From 3debb4c40158ef13cee86c03697712d31119a764 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Sun, 7 Jan 2018 16:29:53 +1100 Subject: [PATCH 01/22] Add license, introduction, dapps --- Decentralized-apps-(dapps).md | 83 ++++++++++ Ethereum-introduction.md | 277 ++++++++++++++++++++++++++++++++++ LICENSE | 5 + 3 files changed, 365 insertions(+) create mode 100644 Decentralized-apps-(dapps).md create mode 100644 Ethereum-introduction.md create mode 100644 LICENSE diff --git a/Decentralized-apps-(dapps).md b/Decentralized-apps-(dapps).md new file mode 100644 index 000000000..1dbed731b --- /dev/null +++ b/Decentralized-apps-(dapps).md @@ -0,0 +1,83 @@ +Any good, service, governance or economic activity can be decentralized and tokenized with and transacted via Ethereum. The token represents the dapp (an abbreviation for decentralized app) while it uses the Ethereum blockchain, but the price of the token is different. Activity that has any economic or governance aspect, conceived or as of yet inconceived, can be done via Ethereum, provided that the right code is written and the necessary hardware is used (such as computers running an Ethereum node, and in some special cases, a measurement device to measure a resource flow for additional verification/auditable purposes, like a meter for electricity ⚡🔌, water 🚰 or gas 🔥; or a waste 🗑️ volume detector). Here's a challenge: keep an eye out for activity that has not been implemented on Ethereum (or could be implemented in a better way; check this article and research to check whether it's implementeId and if so, how well) and then: + + +This platform aspect of Ethereum has been referred to as a 'fat protocol' here, as opposed to the 'thin protocols' of Web 1.0 and 2.0 with HTTP, SMTP, etc., with the take home point (in bold) being: +
the market cap of the protocol always grows faster than the combined value of the applications built on top, since the success of the application layer drives further speculation at the protocol layer.
+One kind of application that is particularly intriguing is decentralized autononous organisations (DAOs, this includes entities as large as, or even larger than nation-states 🇦🇺🇺🇸🇮🇳🇬🇧🇨🇳🇧🇷🇷🇺🇯🇵, social networks, multinational public companies, etc.). Note that having complete autonomy is probably not a good idea, since code may not be able to handle new issues that arise, so human intervention should probably always be an option, but preferably in the hands of a small, non-profit entity or some decentralized solution (perhaps similar to the Aragon Network). By analogy, you wouldn't want a nuclear power plant to be completely automated with no possible means of human intervention. As a precaution, you'd want several safeguards including, for example, an off button 😉. As explained in this Ethereum Wiki here, the first DAO, known as The DAO, resulted in many funds being stolen, and Ethereum hard forking into Ethereum and Ethereum Classic. + +The following list is sourced from [Coin Market Cap tokens (you can sort by market cap)](https://coinmarketcap.com/tokens/) and State of the Dapps, both of which lists many more, as well as elsewhere, e.g. Gitter research room chats. (There are 854 dapps on State of the Dapps as of Dec 1 2017; then [909 on Jan 1 2018] (https://web.archive.org/web/20180101114436/https://www.stateofthedapps.com/). 😯 You can search by tags.) Other examples are also presented e.g. on day 4 of [Devcon 3](http://www.ryanyosua.me/devcon-3-talks/), as well as outlined in the Ethereum whitepaper in the introduction and applications section. Note also that while most of the dapps in the following list run on the Ethereum platform, some examples do not, and where they don't run on Ethereum, it is generally noted as what they do run on. This is not a big deal, as any dapp could theoretically run on another blockchain, (or indirectly via inter-blockchains like Cosmos or Polkadot) provided that the host blockchain has the required features. Also note that the below list is not an endorsement, and is not exhaustive or necessarily well-maintained. At worst, it's included because it was briefly looked into and it seemed like a good idea, while more time may have been spent doing due diligence on some ideas and can therefore have a better idea of its usefulness. Dapps that have been implemented, or are under development, or have been publicly conceptualised, includes: +* a stable coin, e.g. [Dai](https://makerdao.com/whitepaper/DaiDec17WP.pdf) +* smart contracts for the legally enforceable and/or liquid transfer of assets, plus related services e.g. [Mattereum](https://mattereum.com/) and [Sweetbridge](https://sweetbridge.com), e.g. settlement, accounting, risk management, resource sharing, and Optimization & Liquid Talent. Also, asset-based lending: secure loans with holding of assets e.g cryptocurrenices (locking them up) in exchange for cash (fiat currencies), such as Sweetbridge and [SALT](https://coinmarketcap.com/currencies/salt/); +* [Veritaseum](http://veritas.veritaseum.com/), which "enables software-driven P2P capital markets without brokerages, banks and traditional exchanges". +* [invoice financing with Populous](https://populous.co/) +* decentralized exchanges to buy and sell cryptos and fiat, e.g. localethereum; for cryptos only there is DecentrexOmega One and NVO, where the latter two have not been launched as of November 30. +* non-decentralized exchanges such as [Coinbase](https://www.coinbase.com/) (US), [BTCmarkets](https://btcmarkets.net/) (Australia), while more are below, or ones that only exchange cryptocurrencies like Poloniex; +* other exchanges like [OmiseGo](https://omisego.network/). "OmiseGO is a public Ethereum-based financial technology for use in mainstream digital wallets, that enables real-time, peer-to-peer value exchange and payment services agnostically across jurisdictions and organizational silos, and across both fiat money and decentralized currencies. Designed to enable financial inclusion and disrupt existing institutions, access will be made available to everyone via the OmiseGO network and digital wallet framework."; +* exchange platforms like [Binance](https://www.binance.com/aboutUs.html); +* asset exchanges like [WAX](https://wax.io/). +* the Brave browser (which the author uses) which uses the Basic Attention Token, which provides a better solution for users, publishers and advertisers; +* [MaidSafe](https://maidsafe.net/), which has another browser that actually runs on the [Omni](http://www.omnilayer.org/) layer that runs on Bitcoin, not Ethereum. It is also claiming to be: "The World's First Autonomous Data Network". [Currently you have to receive an invite which requires roughly an hour of interaction on their Discourse forum/site.](https://web.archive.org/web/20171230003420/https://invite.maidsafe.net/) +* [ZeroNet](https://zeronet.io/), another decentralized internet network that runs on Bitcoin cryptography and the [BitTorrent network](http://www.bittorrent.com/). [It on Ubuntu 17.10](http://127.0.0.1:43110/Talk.ZeroNetwork.bit/?Topic:1514631579_13fVMZu2wTNAykEvkYHYfGmTBMSFxz9gFG/It+would+be+good+if+you+could+link+to+a+comment). You can make [your own site](http://127.0.0.1:43110/1zz1z8YPFQizJshGkgHq7GVtBSPCyQM5W/), although [you may have issues with following a tutorial](http://127.0.0.1:43110/Blog.ZeroNetwork.bit/?Post:99:ZeroChat+tutorial#comment_1_13fVMZu2wTNAykEvkYHYfGmTBMSFxz9gFG). Note that this link won't work unless you are running ZeroNet.sh) by clicking the download button on the homepage (then as detailed concisely below the button) extracting it and running (in bash) `./ZeroNet.sh` while `cd`ed to the extracted folder that ZeroNet.sh is located in. +* storage, e.g. Swarm and a distributed hypermedia protocol, IPFS [website](https://ipfs.io/), [doc](https://github.com/ipfs/ipfs); +* communication protocols, e.g. Whisper (also see here for code), which allows dapps (you don't need to capitalize this since it is an abbreviation of decentralized applications) to communicate with each other; +* multi-chain networks/tools like [Polkadot](https://polkadot.io/) and [BTCRelay](http://btcrelay.org/) +* Ethereum Name Service (names like jamesray.eth map to an address); +* mesh networking e.g. implemented here and as voted for here on Twitter (which also has other ideas posted in the comments); +* social networks e.g. Akasha (news here), +* Status: "A Mobile Ethereum OS: Browse, chat and make payments securely on the decentralized web."; +* decentralized search engines, e.g. Weipoint (a news post is here); +* reputation and ratings network e.g. as used by [Etheal](https://etheal.com/), which is described below (CTRL+F); +* identity (e.g. as provided by uPort, as well as [in-blockchain proposal](https://www.ethnews.com/erc725-a-self-sovereign-identity-standard-for-ethereum and [Shyft](https://www.shyft.network/)); +* decentralized electricity trading and other decentralized energy economic applications, which would allow renewable energy to be more economical and accelerate the transition to a clean, renewable energy and safe climate future. + +Sun on Twitter Twemoji 2.3Wind Face on Twitter Twemoji 2.3Deciduous Tree on Twitter Twemoji 2.3Water Wave on Twitter Twemoji 2.3 + +Examples of local electricity trading include: Grid+, LO3/Transactive Grid, Power Ledger, Nexergy, Local Volts and Divvi. Grid+ uses Ethereum and they have open source code. Power Ledger has closed source code and runs on the Ethereum Enterprise Alliance, rather than the public Ethereum blockchain. They had a token sale in early October. Both Power Ledger and Grid+ also detail more unique applications in their pipeline, such as renewable energy asset generation (Power Ledger) and Grid+'s in-home computer, an "intelligent agent" that pays for a customers electricity in real-time, using stable tokens, stores cryptocurrency like the hardware wallet functions of Ledger and Trezor; providing Casper proof-of-stake signing, and provide an Ethereum API for IoT ([pp. 26 and 34-36, white paper](https://drive.google.com/file/d/0Bz90riPGRHquNDVXVE81RmppaUk/view)). Transactive Grid uses Ethereum and it has been rolled out in Brooklyn with a microgrid, however LO3 hasn't released any code or details for its Transactive Grid application. The others are still all under development (as of August 2017), and they have been scant on the details of how they would implement their application, at the least not releasing their code. Divvi say on its website that they will use the blockchain. Local Volts and Nexergy do not. +* electricity tokenization: e.g. SolarCoin, EnergyCoin, although both are altcoins rather than Ethereum tokens; +* governance of any organisation, e.g. Democracy.Earth; and also governance of DAOs, e.g. Aragon; +* decentralized search engines like [BitClave](https://www.bitclave.com/en/), [Weipoint](https://www.weipoint.com/) and [Epocum](https://www.stateofthedapps.com/dapps/epocum); +* wallets like MyEtherWallet or hardware wallets Trezor or Ledger; +* blockchain explorers like [Etherscan](https://etherscan.io/); +* a gateway to decentralized services such as [Infura](https://infura.io/); +* visit dapps in your browser with [Metamask](https://metamask.io/); +* decentralized media; +* asset titles (such as land titles). Read more on that here: "Having so far built the software and tested it with a couple dozen land title registrations, Bitfury and the Georgian National Agency of Public Registry have now signed a new memorandum of understanding to expand the service to purchases and sales of land titles, registration of new land titles, demolition of property, mortgages and rentals, as well as notary services". Nottar.io also provides notary services. A similar, more specific application is for academic certificates with [Smart Diploma](https://www.stateofthedapps.com/dapps/smart-diploma); +* Debit card 💳 transactions 🤝 (done on several exchanges 💱, e.g. Coinjar Swipe (but it accepts BTC only), Coinbase, while others which I've mentioned elsewhere in this article have plans to do this e.g. [OmiseGO](https://www.omise.co/go); +* co-ownership of real assets e.g. the [Swarm Fund](https://www.swarm.fund/how-swarm-works/index.html) +* crowdsales, e.g. an Initial Coin Offering (ICO) as compared with an Intial Public Offering (IPO), or for tokens with Ethereum: an Initial Token Offering (ITO). Note that this is not so much a business model in itself, per se, rather it is more of a fundraising method (which has also led to scams, e.g. here); +* crowd development (but not as part of the blockchain, e.g. here), e.g. for infrastructure and other public assets; +* think of public companies being remodelled into communities with tokens instead of shares, governance using a platform like Democracy.Earth (which can be tailored to have voting anywhere between one vote one person like direct democracy, or conventionally more hierarchical like a board of directors and token-holders instead of or in addition to—and probably eventually superceding—shareholders); +* dividend payouts and secure email-based transactions with [Dividend](https://www.dividend.cloud/). For sending ETH via email there is also [You've Got ETH](https://www.stateofthedapps.com/dapps/you-ve-got-eth); +* prediction 🔮 🦉 markets like GNOSIS, Augur and [WINGS DAO](https://www.stateofthedapps.com/dapps/wings-dao); +* [Built-in price discovery and a liquidity mechanism for tokens with Bancor](https://www.bancor.network/); +* labour/recruitment/freelance markets like Chronobank and [Ethlance](https://ethlance.com/); +* permissioned distributed ledgers like [Hydrachain](http://www.brainbot.com/projects#hydrachain); +* trust-based models like the [Trustlines Network](http://trustlines.network/) +* Secure distributed computing, e.g. Golem. Ethereum needs to be faster e.g. with EWASM and parallelizability. +* accountability, e.g. for non-profits (e.g. "how do I know how badly you need a donation unless I can see your net liabilities, net assets, and balance sheet, and how you plan to use the funds?") and aid (also see here) +* Self Learning, Autonomous, Decentralized Artificial Intelligence (this could be used for many things such as self-driving cars, robots, or anything else that is owned by a contract; bots; and art); +* decentralised financial services like [WeTrust](https://www.wetrust.io); +* futures-like dapps such as [TimeBank](https://www.stateofthedapps.com/dapps/timebank) and [hodlethereum](https://hodlethereum.com/); +* sharing car refueling stations with [Share&Charge](https://www.stateofthedapps.com/dapps/share-charge); +* health, e.g. [Etheal](https://etheal.com/), a healthcare service comparison site with a content platform, trust and review / reputation system; an anonymous marketing platform for surveys, ads and communication research where users are paid by pharmaceutical companies; and a platform for building health apps; +* examples of contracts are [here](https://solidity.readthedocs.io/en/develop/solidity-by-example.html) and [here](https://viper.readthedocs.io/en/latest/viper-by-example.html), e.g. voting, auctions (open or blind), safe remote purchases, micropayment channels, crowdfunding and company stock. Many more can be found on Github, which may be referenced from the whitepaper and the website of a dapp. +* [insurance](https://www.stateofthedapps.com/tagged/insurance/); + + +Examples that have been conceptualized, but not implemented (at least as far as the creator of this wiki is aware of) include: +* reducing transaction costs for existing business models (here is a good read about that). However, to tokenize online centric business models, the network model should change from client-server to peer-to-peer, to avoid a conflict of interest. This is more difficult to achieve since a server is a piece of infrastructure, and transferring to a peer-to-peer model would cause it to be a sunk cost. Additionally, it may be difficult to build a replacement dapp for a successful website, because it is hard to get a network of engaged users to change to using something else (inertia). Centralized web apps (not just mobile apps but websites, and use the word to contrast with dapps) include: +* * Google (although note [Weipoint](https://www.weipoint.com/) as mentioned previously), +* * social networks like [Facebook](http://www.trustnodes.com/2018/01/04/zuckerberg-studying-cryptocurrency-implementation-facebook), Twitter, (although note [Akasha](https://akasha.world/) above); +* * online marketplaces e.g. Amazon, eBay and Alibaba (decentralized alternatives include [Soma for products or services](https://soma.co/), [Canya for services](https://canya.io/) also note this simple implementation and subreddit [here](https://www.reddit.com/r/ethmarket/), as well as more specific or niche marketplaces like [Cryptokitties](https://www.cryptokitties.co/), [Hamster](https://hmstr.io/)). For more info see [here](https://www.forbes.com/sites/rogeraitken/2017/10/24/whats-the-future-of-online-marketplaces-blockchains-technology-impact/#3f6bde2a63a0) +* making economically viable other business models that have seen low uptake or aren't economically viable without blockchain tech. So-called sharing economy business models (which are more aptly called tasker or rentier capitalism models) like Airbnb, Uber, AirTasker, Fiverr, Upwork, TaskRabbit, and Menulog are particularly ripe for transformation (the term transformation is preferrable to disruption, since it should be a net positive change, while negative effects are manageable or solvable), since no trusted third party for a transaction is needed, such as banks 🏦, credit card 💳 companies or PayPal, just a smart contract; and +* mortgage brokers; +* More examples are here—scroll to the examples—they have bold headings and are about two thirds of the way down, or search for "Dank meme trading". Note that the Basic Attention Token has already been mentioned, and the creator of this wiki is skeptical that AI will create truly beautiful art, since no AI can have any feeling. CryptoKitties is an example of meme trading and has taken up [a lot of the transactions on the Ethereum network](https://etherscan.io/address/0x06012c8cf97bead5deae237070f9587f8e7a266d). +* curation markets, which is part of what [Steemit](https://steemit.com/@jamesray/feed) does (which runs on the STEEM network), and which curators, social networks and wiki authors would all benefit from. More info is [here](https://medium.com/@simondlr/introducing-curation-markets-trade-popularity-of-memes-information-with-code-70bf6fed9881); +* [P2P Decentralised Autonomous Transportation Network](http://www.flyingcarpet.network/) +* [Waste collection management](https://twitter.com/JamesCRay01/status/936992945173020672). Other ideas include plus generally thinking of existing business models running on the blockchain, like real estate developers and investment trusts (with which blockchains could be used e.g. for crowdfunding). +* legally enforceable wills running on the blockchain, as well as being able to appoint an executor in a legally enforceable way on the blockchain. + +More examples are e.g. [here in a blog post](https://medium.com/@Ethereum_AI/ethereum-introduction-what-exactly-is-it-why-care-how-to-invest-9a627ab04408) and [here on Wikipedia](https://github.com/Ethereum-community/Ethereum-introduction/wiki/Decentralised-apps-(dapps)) diff --git a/Ethereum-introduction.md b/Ethereum-introduction.md new file mode 100644 index 000000000..8d6a862fb --- /dev/null +++ b/Ethereum-introduction.md @@ -0,0 +1,277 @@ +![Ethereum Homestead gold ingots](https://sustergy.files.wordpress.com/2017/05/ethereum-homestead-background-17.jpg?w=1000) + +Note that due to the lightning-fast pace of development in the Ethereum space with core development and dapps continually being launched, certain parts of this article may be outdated. You can help by keeping it up to date! + + + +Table of Contents +================= + + * [Table of Contents](#table-of-contents) + * [About Ethereum](#about-ethereum) + * [Uses](#uses) + * [List of dapps](#list-of-dapps) + * [Market analysis](#market-analysis) + * [Issues](#issues) + * [Scalability](#scalability) + * [Proof of work / proof of stake / other proving methods](#proof-of-work--proof-of-stake--other-proving-methods) + * [Public permissionless blockchains vs. private permissioned blockchains](#public-permissionless-blockchains-vs-private-permissioned-blockchains) + * [No technological artefacts can be a panacea](#no-technological-artefacts-can-be-a-panacea) + * [How do you buy and sell Ether, the currency of Ethereum?](#how-do-you-buy-and-sell-ether-the-currency-of-ethereum) + * [Table of exchanges](#table-of-exchanges) + * [More details about what I've tried (not very necessary to know)](#more-details-about-what-ive-tried-not-very-necessary-to-know) + * [Development](#development) + * [Concluding remarks](#concluding-remarks) + * [Further reading](#further-reading) + +# About Ethereum +Ethereum is a [decentralized](https://medium.com/@VitalikButerin/the-meaning-of-decentralization-a0c92b76a274) blockchain platform for "building unstoppable applications", while Ether is the cryptocurrency used on this platform. Ethereum has been described in several ways, such as (the first and third resources are more general introductions, while the second is a technical introduction, although all are outdated. +Another introduction is available [here](https://bitsonblocks.net/2016/10/02/a-gentle-introduction-to-ethereum/), but again, it is outdated. Despite being outdated, Ethereum has maintained backwards compatibility thus far up till January 1 2018, so the info is still relevant.): + +Let's briefly breakdown what those terms mean. + +**Decentralized** technology uses [peer-to-peer computer networks](https://en.wikipedia.org/wiki/Peer-to-peer) (there's a picture below), and are not subject to the whims of a central authority such as a government or server administrator (like Google or Facebook) which can help to achieve better decision making for public good. **Blockchain** means that the currency is built and secured by adding and verifying blocks of transactions to blocks made previously, thus forming a "chain". Blocks added to the chain become harder and harder to crack over time, as they are verified by more nodes in the blockchain peer-to-peer network. Blockchain technology has been referred to as the **Web 3.0**. The world wide web (retroactively the Web 1.0) consisted of websites publishing content and users passively reading/viewing it. The Web 2.0 used user interaction, such as forums (with upvoting and commenting), reaction buttons (e.g. the Facebook reactions: likes 👍, love ❤️ , laughter 😆, wow 😲, sad 😢, angry 😠), sharing (republishing), however these interactions have no direct economic effect on the host website; users do not share in the value generated from the website. The Web 3.0 is starting to be defined as the movement away from centralisation of computation power in servers which provide services to clients (known as the client-server network model) to peer-to-peer networks and blockchains, and from centralisation of authority and sovereignty from nation-states and corporations to the networked individual. + +![server-based-network](https://sustergy.files.wordpress.com/2017/05/200px-server-based-network-svg.png) +![p2p-network](https://sustergy.files.wordpress.com/2017/05/200px-p2p-network-svg.png) + +**Cryptocurrency** refers to a a digital currency that secures transactions with cryptographic code, which is solved through hardware computational power (known as mining or proof of work) or other less energy-intensive ways such as proof-of-stake. (There are more details on that below.) + +Zero knowledge proofs like ZK SNARKs can also be used to make cryptocurrency transactions more private 🕵️ or secret 🤐 (which is different to being secure 🔒), thus negating the need to run applications on a permissioned private network like the [Ethereum Enterprise Alliance](https://entethalliance.org/). Ethereum uses [precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128](https://github.com/ethereum/EIPs/pull/213), for [pairing checks](https://github.com/ethereum/EIPs/pull/212), which permit [zk-SNARKs](https://blog.ethereum.org/2017/10/12/byzantium-hf-announcement/), also see [here](https://medium.com/@VitalikButerin/zk-snarks-under-the-hood-b33151a013f6), [as implemented](https://github.com/ethereum/EIPs#finalized-eips-standards-that-have-been-adopted) in the [Byzantium hard fork](https://blog.ethereum.org/2017/10/12/byzantium-hf-announcement/). There is also the Zerocoin protocol which is demonstrated by Zcoin (which plans to integrate Ethereum). + +# Uses +The platform part of Ethereum makes it much more useful than just a cryptocurrency. With it, you can create any decentralized application (known as a dapp, which works over a peer-to- peer network rather than a centralized client-server network 💻🕸️), so the functionality is only limited by what programs could potentially do and not do, and by consequence, what programmers develop, 👨‍💻 but it can theoretically be used for any economic or governance activity. + +## List of dapps + +For a list of dapps, visit [here](https://github.com/Ethereum-community/Ethereum-introduction/wiki/Decentralised-apps-(dapps)). + + +*** + + +However, there are several issues that will need to be resolved to help Ethereum be used to its full potential, which are described below. + +## Market analysis +As of the 1st of December 2017, [the market capitalisation of Ethereum is $32.6 billion USD](https://cryptolization.com/ethereum) (refer to the link for the latest figure), and [it has been in circulation possibly since 30 July 2015](https://github.com/jamesray1/homestead-guide/blob/32d2fa4ccfa3d45f8493a673a08247450d55fea0/source/introduction/the-homestead-release.rst#milestones-of-the-ethereum-development-roadmap), with the [first transaction using Ethereum on 8 August 2015](https://www.etherchain.org/account/0x5abfec25f74cd88437631a7731906932776356f9). Compare this with the next largest and the current largest cryptocurrency, [Bitcoin, with a market cap of $41.0 b. US](https://cryptolization.com/ethereum), where [it has been in circulation since January 2009](http://www.newyorker.com/reporting/2011/10/10/111010fa_fact_davis). Technically, Ethereum has had a much faster growth rate, while more importantly for long term investment (I do not encourage speculation as that only causes volatility as has been seen) the fundamentals are much better than Bitcoin. While it is true that Bitcoin has more of a market and currency, e.g. in terms of more entities that will accept it as a form of payment, the creator of this wiki expects that time will change that (indeed the market cap of Ethereum recently surpassed half that of Bitcoin, around May 2017). Also, [the number of transactions of Ethereum surpassed that of several cryptocurrencies combined on 22 Nov 2017](https://www.reddit.com/r/ethereum/comments/7est9k/ethereum_is_now_processing_more_transactions_a/). However, note [this retort](https://www.reddit.com/r/ethereum/comments/7est9k/ethereum_is_now_processing_more_transactions_a/dq7a31u/). + +# Issues +There also several issues with Ethereum, such as not being scalable enough, not being full decentralized, energy consumption with mining, if quantum computing advances it would be insecure (but this is being fixed). With its [large storage database](https://www.reddit.com/r/ethtrader/comments/7axn5g/ethereum_blockchain_sizewe_have_a_problem/) (I have to provide a [Reddit link](https://www.reddit.com/r/ethtrader/comments/7axn5g/ethereum_blockchain_sizewe_have_a_problem/) as a source as the [original link](https://etherscan.io/chart/chaindatasizefull) doesn't have the graph any more, while [Wayback doesn't render it either](https://web.archive.org/web/20171211015955/https://etherscan.io/chart/chaindatasizefull).), mining and architecture requiring to run a full node to mine or validate transactions, it is not decentralized enough. More (outdated but still applicable) info on that is e.g. [here](https://ethereum.stackexchange.com/questions/143/what-are-the-ethereum-disk-space-needs#826), as well as [here](https://github.com/ethereum/go-ethereum#full-node-on-the-main-ethereum-network). + +## Scalability + +Ethereum will need to scale to process far more transactions per second (to become a "world computer") than Visa, Mastercard and American Express combined (which process on the order of [tens of thousands of transactions per second](https://usa.visa.com/run-your-business/small-business-tools/retail.html) [in the link, CTRL+F 24,000]), while Ethereum 1.0, the current version as of December 30 2017, processed [a record of 1103523 transactions on Friday, December 22, 2017, or 12.77 transactions per second](https://web.archive.org/web/20171230005127/https://etherscan.io/chart/tx). + +Note that [Ripple claims that it's Consensus Ledger can process a thousand transactions per second](https://ripple.com/dev-blog/ripple-consensus-ledger-can-sustain-1000-transactions-per-second/), while it could process more with payment channels. "Although payment channels achieve practically infinite scalability by decoupling payment from settlement, they do so without incurring the risk typically associated with delayed settlement." Further note that Ripple achieves this by trading off on decentralization, through a [distributed network of validators or distributed servers](https://ripple.com/build/xrp-ledger-consensus-process/), while it has been described as a [federation protocol](https://wiki.ripple.com/Federation_protocol). + +There are even more scalable blockchains that use a delegated proof of stake (DPOS) consensus protocol, such as Bitshares and Steem. [Bitshares can apparently process 100,000 TPS](https://bitshares.org/technology/industrial-performance-and-scalability/). + +More generally, in order to have faster payments or higher transaction throughput, you need to reduce the number of validators (miners are a kind of validator that perform energy intensive computational work, finding a random nonce or sequence number in a large set of numbers) in the consensus protocol, or reduce the other (i.e. for faster payments you can reduce transaction throughput or reduce validators, while for higher transaction throughput you can reduce validators or have payments take longer to finalize). This is [a trade-off triangle](https://twitter.com/VladZamfir/status/932319930363494400). You could potentially have one blockchain with [heterogeneous sharding](https://twitter.com/VladZamfir/status/932320997021171712), with different shards with a different degree of balance between these properties. Ethereum is working on [sharding](https://github.com/ethereum/sharding/blob/develop/docs/doc.md), which includes using [stateless clients](https://github.com/ethereum/sharding/blob/develop/docs/doc.md#stateless-clients) (while more on that is [here](https://ethresear.ch/t/the-stateless-client-concept/172/14)). + +If you increase scalability in an instant via some blockchain or shard, while keeping latency constant (or reducing it) you need to reduce decentralization, which reduces the number of points of attack needed to compromise the whole network, i.e. reducing decentralization reduces security. + +## Proof of work / proof of stake / other proving methods +The mining process to crack cryptographic code (specifically to discover the nonce, a very large number, for each block by trial and error) requires a lot of computation power. Nevertheless, I'm guessing that the computation power should be less when you consider the energy consumption of incumbent financial systems. (Think of extracting and processing resources to make coins and notes, minting and printing, energy consumption of banks and tiers of related energy consumption in the life cycle of fiat money.) Still, developers of some cryptocurrencies such as Ethereum are transitioning to (as is the case for Ethereum), or already using, a different way of maintaining and creating blocks, known as proof of stake. For more information, you can see this Proof of Stake Wikipedia article here (although note the header warning about the article potentially not being verifiable or neutral due to relying heavily on sources too closely associated to the subject). The tricky part is in getting proof methods to work better than proof of work, as outlined here in the criticism section of the PoS Wiki. + +## No technological artefacts can be a panacea +For the continual improvement of humanity, there needs to be balance in life between things that benefit us materially and things that benefit us on higher levels, particularly spiritually. There is a risk that technology can make some people better off, and others worse off. So there needs to be consideration for how technology can be implemented to maximise [utility](https://en.wikipedia.org/wiki/Utilitarianism). One consideration of that is [here](https://medium.com/@RhysLindmark/co-evolving-the-phase-shift-to-cryptocapitalism-by-founding-the-ethereum-commons-co-op-f4771e5f0c83). + +## There's a risk of attacks from quantum computing, if it becomes performant enough + + + +# How do you buy and sell Ether, the currency of Ethereum? + +Summary: compare deals with buying and sell through different exchanges such as P2P ones with an arbitrator like [**LocalEthereum**](https://localethereum.com), or with centralized exchanges (which vary with your local jurisdiction, e.g. in Australia there is [BTCmarkets](https://btcmarkets.net/fees) and in the US plus worldwide there is [Coinbase](https://www.coinbase.com), which also allows you to spend cryptocurrencies e.g. with a debit card. For more see the table below, [here](https://github.com/jamesray1/Ethereum-introduction/wiki/Ethereum-introduction#table-of-exchanges)). + +The simplest way may be to use [**LocalEthereum**](https://localethereum.com), where you don't need to go through KYC processes. The creator of this wiki has found that "I can **sell Ether for a better deal** than I can find with an exchange, without any trading or withdrawal fees, apart from those associated with different payment methods". I like that it has lower fees compared to exchanges. I also read about how the localethereum platform works, and it seems pretty secure. The maker fee (which is what the party of the trade that puts up the offer) is 0.25% while the taker fee is 0.75%. [BTCmarkets](https://btcmarkets.net/fees) has higher fees compared to the maker fee, and higher than the taker fee if the amount is below $3000. Additionally, there have been hacks with exchanges like Mt. Gox and Bithumb. That's harder to achieve with localethereum since they can't get access to your funds, they can only settle disputes (if they arise) by sending the funds in the escrow to the buyer or the seller. However, I have been able to find a **better deal**, at least at certain times, with buying Ether if I buy through [**BTCmarkets**](https://btcmarkets.net/fees), although that would be slower via BPAY with bank transfer than paying via cash deposit via an ATM or bank." + +More information about Ether is [here](http://ethdocs.org/en/latest/ether.html). + +Disclaimer from the creator of this wiki: I have put most of my funds in Ether, the currency of Ethereum. Does that shock you? 😲 Yep, it's risky, but I've done due diligence 🔍 with fundamental analysis, and a little bit of sentiment and technical analysis, and I think that the market cap of Ether will continue to grow 🌱🌳 and increase, albeit with some volatility 📈. I consider it a digital currency that is in a pioneering, rapid growth stage of development (fuelled by a lot of genuine uptake of the currency as well as speculation about its future value, if not its current value), not just an asset. I hope my post will outline why investing in Ether is a good idea (and not just investing a small percentage of your cash, unless you are tied up with a mortgage 🏠 or have other monetary or non-monetary ties or circumstances that limit your investable capital). However, if you don't want to risk the downside volatility, e.g. if you don't have any risk capital, then you may want to consider buying a stable coin like [Dai Coin](https://makerdao.com/) instead. + +Based on my research below, if you're in Australia 🇦🇺 (otherwise skip to the next paragraph), I recommend creating an account with BTCmarkets.net, verifying your ID, and using BPAY or PoliPayments to deposit AUD. Note that the rest of the following info in this paragraph is outdated since MEBank used to not support BPAY publicly, but now they do. If your bank doesn't support PoliPayments and you want to use that instead of BPAY, although I can't think of any good reason why you'd want to use PoliPayments over BPAY, then you can set up a bank account with BOQ (or any other bank that supports POLi Payments, doesn't invest in fossil fuels and has no fees for transaction and savings accounts [note that Bendigo doesn't have an Ultimate Everyday account any more]. You can probably ignore the interest rate since it is so marginal compared to other bank's rates and the gains that you are likely to make by holding funds with Ether instead. However, when I did research for interest rates I found that ME Bank savings rates were second only to UBank, which invests in fossil fuels indirectly as it is owned by NAB. + +## Table of exchanges + +You can use [localethereum](https://localethereum.com) anywhere, but in my experience you may not get as good a deal as buying it on a local exchange. + +If you're not in Australia 🇦🇺, then here's a comparison of exchange rates 💱 for fiat to crypto- and crypto- to crypto- currencies (note that there is still a focus on Australia, but you can click on the links to get more information of the fees): + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 Exchange link (may go to a fees page)Fiat to crypto exchange fee buy/sell spread
BTCmarketsAUD is the only fiat currency. 0.85% trading fee. Funds available to deposit, withdraw, buy and sell are: AUD, ETH, ETC, BTC and LTC. To deposit AUD, you need to verify your account and then use POLi Payments (available banks are here. My bank is ME Bank, which doesn't support POLi Payments. I applied with BOQ because they do support POLi Payments, they don't invest in fossil fuels [like ME Bank] and they have transaction and savings accounts with no fees [like ME Bank].)
GDAX0.25/.3% maker fee low volume, 0% taker fee BTC for USD/EUR/GBP, ETH/LTC for USD/BTC/EUR
Coinjar, has a debit card with accounts for Ether, BTC, XRP and LTC.1.00% AUD/BTC (and only AUD/BTC)
CoinbaseIn Aus: 3.99% credit/debit card only (no other transaction method accepted). Other fiat and crypto currencies are available.
CEX7% BTC/ETH for USD/EUR/GBP/RUB
ice3x1% ZAR/BTC
LunoZAR/BTC fee not easy to find
okcoinCNY/USD for BTC/LTC, fee not easy to find
MaicoinTN/BTC Fee not shown, claimed none
+ + + + + + + + + + + + + + + + + + + + + + + +
Crypto to crypto exchange fee / buy/sell spread
Poloniex0.15/.25% BTC/ETH “maker-taker” (presumably the same as buy-sell)
gdax.com/fees/0.25/.3% maker fee low volume, 0% taker fee ETH/LTC for BTC
Exodus~0.4720–.528% BTC/ETH variable. Desktop app. Sometimes currencies are not available for exchange!
NVODecentralised. ICO 05/27/17 02:00 UTC to 06/27/17 02:00 UTC
+ +Exchanges are listed in [this article](https://medium.com/@Ethereum_AI/ethereum-introduction-what-exactly-is-it-why-care-how-to-invest-9a627ab04408), which I've copied and pasted (repetition is OK): + +**America, US dollars** + +https://www.coinbase.com + +https://gemini.com/ + +**Australian Dollar** + +https://btcmarkets.net/ + +**Canadian Dollar** + +https://www.quadrigacx.com + +**Chinese Yuan** + +https://www.huobi.com + +https://www.okcoin.com + +https://yunbi.com + +**European Euros** + +https://www.kraken.com + +**India** + +https://duckduckgo.com/?q=Ethereum+exchange+india&t=brave&ia=web + +**Mexican Peso** + +https://bitso.com + +**South Korean Won** + +https://coinone.co.kr/ + +https://www.bithumb.com/ + +## More details about what I've tried (not very necessary to know) + +I bought BTC in a different way. Step 2 worked for me. I will try step 1 next time I buy more BTC. + +I created an account on btcmarkets.net, verified my email address, tried to login, but couldn't. I tried to disable two factor authentication, but it asked for my mobile number, which I didn't enter when I created my account. I tried to reset my password and log in again, but that didn't work. I entered my email address correctly. I sent a message to support to ask for help. I figured out that my password was too long, and have notified btcmarkets.net. After creating a password of 23 characters, I was able to log in. I created another password of 56 characters using Chinese characters, emojis and ASCII characters, and was able to log in. (Incidentally, it is a hassle to do this, so a decentralised, private password generator would be wonderful.) + +The following steps are what I have tried so far, in detail. +
    +
  1. Convert AUD to Bitcoin (BTC) via an exchange like Coinjar. I left a review of Coinjar here. Fee: 1%. While this step is tailored for Australia, it can be adapted to any country that has a bitcoin exchange.
  2. +
  3. I created a Poloniex account, sent funds from got the Bitcoin deposit address, then sent my BitGo funds to that address. Once the transaction completed, I then used Poloniex Exchange to convert to Eth, with a maker-taker fee of: 0.15/0.25%.
  4. +
+Before step 2 above, I tried the following: +
    +
  1. Create an Ethereum Wallet 👛 like MyEtherWallet. Unfortunately Mist, a program being developed by Ethereum that has a browser and a wallet is still a pre-release, so it may not be very suitable for end users just yet.
  2. +
  3. Convert BTC to Ether (ETH) via a cryptocurrency exchange like Shapeshift. Use a precise transaction, make sure the amount is within the min. and max. deposit. Copy and paste the bitcoin address in Coinjar by signing in (if you aren't already) and going to Accounts > Everyday Bitcoin > View address. Put this address as the refundable address. Copy and paste the address from MyEtherWallet. Put this as the destination address. Tick the box to save the destination address for future payments. However, this didn't work.
  4. +
+I also sent an email to Coinjar to suggest that they develop functionality for purchasing Ether directly using AUD. You can do the same with the exchange of your choice. + +I have been able to deposit funds into Coinjar (needing to be less than the transaction limits) but have not been able to get Eth funds as of yet. I have also tried to create an account on BitGo, send coins from Coinjar to BitGo, and use Shapeshift with that account and still with MyEtherWallet, however that didn't work. + +I will not discuss trading (which I mean buying with the intention to sell most or all of the purchase at any future time particularly in the short term in order to realize a profit) as I am not very interested in trying to guess the short-term direction of markets (although I admit that trading helps to provide liquidity). + +# Development +Are you interested in learning to develop smart contracts with Ethereum, and maybe develop a really useful dapp and become a millionaire? + +Check out the [Ethereum website](https://www.ethereum.org/)! Then, you can [read the Solidity docs](https://solidity.readthedocs.io/en/develop/). + +If you want to help contribute to core development, there is also: +* the [Yellow Paper](https://github.com/ethereum/yellowpaper/pull/376) (make sure that you read the [EIPs](https://github.com/ethereum/EIPs) too since as of Dec 8 it is not up-to-date with the last commit on August 8, while the Constantinople EIPs were implemented in October). Instead I recommend ; +* Learn Python first, e.g. with [Learn Python the Hard Way](https://www.learnpythonthehardway.org/) (I learnt using this, it's pretty good), [Codecademy](https://www.codecademy.com/learn/learn-python), [Pydocs](https://docs.python.org/3/), [Coursera](https://www.coursera.org/courses?languages=en&query=learn+python), etc. Knowing Python is useful for [pyethereum](https://github.com/ethereum/pyethereum), which is being used as an Ethereum client, to implement Serenity and sharding, as well as [vyper](https://github.com/ethereum/Vyper), an experimental, secure smart contract programming language; +* [LLL](https://media.consensys.net/an-introduction-to-lll-for-ethereum-smart-contract-development-e26e38ea6c23) (also see [here](https://github.com/ethereum/solidity/tree/develop/liblll) and [here](https://github.com/ethereum/solidity/tree/develop/lllc)); +* [JULIA](https://solidity.readthedocs.io/en/develop/julia.html), an intermediate language for different Ethereum virtual machines; +* clients such as [Geth](https://github.com/ethereum/go-ethereum), [Parity](https://github.com/paritytech/parity) which is under [Parity Tech](https://github.com/paritytech) a separate organization to the Ethereum Foundation, [C++ Ethereum](https://github.com/ethereum/cpp-ethereum), [Pyethereum](https://github.com/ethereum/pyethereum); +* [Serenity](https://github.com/ethereum/pyethereum/tree/serenity); +* [sharding](https://github.com/ethereum/sharding/blob/develop/docs/doc.md); +* [research](https://github.com/ethereum/research) such as stateless clients, sharding, scalability improvements, Casper and more; +* [EWasM](https://github.com/ewasm); +* if you're interested in testing, see the documentation [here](https://ethereum-tests.readthedocs.io/en/latest/), as well as [the Github tests repo](https://github.com/ethereum/tests), [a Gist here (it is outdated)](https://gist.github.com/Souptacular/fd197b1fac7c6d2660b0bef27a33ed40#lll-and-evm-stack-resources), and [Gitter here](https://gitter.im/ethereum/tests) ; and +* [many other repositories](https://github.com/ethereum). + +# Concluding remarks + +Ether certainly seems like a good investment, and a good alternative to using fiat currencies, as well as an enabler for otherwise uneconomical business, due to lower transaction costs. It's more decentralized nature than central banks has advantages for trade from a local to global scale. With governance applications and systems on top Ethereum, it is even possible to do away with the hindering borders surmounted by nation-states. By doing away with these borders, society can be more open, inclusive and equitable. + +However, all technology can only help mankind and the world to a certain extent. What is more important is for each and every person to become increasingly blissful. Each person must go within and enter a stillness of body and mind, which is when that bliss starts to manifest, and practice balanced living. Practicing certain techniques such as those given by Self-Realization Fellowship, such as daily Kriya yoga meditation, developing unconditional love that starts in the heart, keeping the mind at the point between the eyebrows, and moral living, helps each person manifest that bliss within, and from there, express that bliss outwardly at all times. + +# Further reading + +* [Another introduction](https://github.com/jamesray1/Ethereum-introduction/wiki/Ethereum-introduction) +* [MyEtherWallet knowledge base (good for issues with wallets)](https://myetherwallet.github.io/knowledge-base/) +* [An introduction (Frontier first release, outdated)](https://ethereum.gitbooks.io/frontier-guide/content/ethereum.html) +* [Here's another introduction, made in November 2017](https://medium.com/@Ethereum_AI/ethereum-introduction-what-exactly-is-it-why-care-how-to-invest-9a627ab04408) +* [Ethereum community on Gitter](https://gitter.im/ethereum) +* [Ethereum research forum](https://ethresear.ch/) +* [Correct by construction Casper prototype](https://ethresear.ch/t/the-correct-by-construction-casper-paper-prototype-published-at-devcon-tear-it-apart/196) +* [Casper the Friendly Finality Gadget](https://ethresear.ch/t/latest-casper-basics-tear-it-apart/151/57) +* [The stateless client concept](https://ethresear.ch/t/the-stateless-client-concept/172) +* [Ethereum 2 and alternative PoS implementations](https://ethresear.ch/t/ethereum-2-and-alternative-pos-implementations/190/7) +* [Ethereum wiki](https://en.wikipedia.org/wiki/Ethereum) +* [Ethereum and the hodlers that love them](https://www.reddit.com/r/ethtrader/comments/6jyn9y/ethereum_the_hodlors_that_love_them/) + + +This article was originally created here in May 2017, and has been regularly updated since then: https://sustergy.wordpress.com/2017/05/18/why-buy-ether-and-how/. Feel free to send a donation to the initial author at jamesray.eth, or make edits to it yourself, or fork it! diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..40d9af62e --- /dev/null +++ b/LICENSE @@ -0,0 +1,5 @@ +The license for this repository is CC BY-SA 4.0. + +A human-readable summary (and not a substitute) of the license is [here](https://creativecommons.org/licenses/by-sa/4.0/). + +The license is [here](https://creativecommons.org/licenses/by-sa/4.0/legalcode). From 9907eb990c9ca7d2c79a9607545d1c3bad422fc5 Mon Sep 17 00:00:00 2001 From: jamesray1 <16969914+jamesray1@users.noreply.github.com> Date: Sat, 7 Apr 2018 14:05:23 +1000 Subject: [PATCH 02/22] Reorganizing all files into folders. --- LICENSE | 5 -- Licensing.md => pages/Licensing.md | 0 .../Middleware-and-Dapp-Project-Ideas.md | 0 .../Open-job-positions-&-Schemes.md | 0 pages/Readme.md | 14 ++++ _Sidebar.md => pages/_Sidebar.md | 0 .../Fortnight-In-Ethereum-Template.md | 0 .../Template:-This-Week-in-Ethereum-w-YY.md | 0 .../This Week In Ethereum 47.2014.md | 0 .../blog-and-notes/Todo-before-alpha.md | 0 .../blog-and-notes/stubs/Which-Client?.md | 0 .../Contract-Metadata-Docs-(NatSpec,-ABI).md | 0 .../Dapp-Developer-Resources.md | 4 +- .../dapp-development/Dapp-using-Meteor.md | 0 .../dapp-development/Ethereum-Contract-ABI.md | 0 .../Ethereum-Development-Tutorial.md | 0 .../First-steps-with-ethereum-JSON-RPC.md | 0 .../dapp-development/JSON-RPC.md | 8 +- .../dapp-development/JavaScript-API.md | 33 +++++++- .../Javascript-Development-Deficiencies.md | 0 .../dapp-development/Mix-Features.md | 0 .../dapp-development/Mix:-The-DApp-IDE.md | 0 .../dapp-development/RPC-Testing.md | 0 .../Standardized_Contract_APIs.md | 17 ++-- .../Useful-\303\220app-Patterns.md" | 0 .../serpent/Serpent-1.0-(old).md | 0 .../dapp-development/serpent/Serpent.md | 0 .../dapp-development/serpent/Serpent_3.0.md | 0 .../solidity/Solidity,-Docs-and-ABI.md | 0 .../solidity/Solidity-Changelog.md | 0 .../solidity/Solidity-Features.md | 0 .../solidity/Solidity-Tutorial.md | 0 .../solidity/Solidity-standard-library.md | 0 .../dapp-development/solidity/Solidity.md | 0 ...Tags-for-Solidity-in-code-documentation.md | 0 .../The-Solidity-Programming-Language.md | 0 .../[english]-design-rationale.md | 4 +- .../Node-discovery-protocol.md | 0 .../Web3-Secret-Storage-Definition.md | 0 .../dev-technologies/enode-url-format.md | 0 .../dev-technologies/libp2p-Whitepaper.md | 0 .../dev-technologies/web.js-0.9.md | 2 +- .../\303\220\316\236Vp2p-Wire-Protocol.md" | 0 .../eip/Geth-Dapp-loading-proposal.md | 0 ...ON-RPC-Error-Codes-Improvement-Proposal.md | 0 .../eip/Mix-improvement-proposal.md | 0 .../eip/Proposal:-BlockHashesFromNumbers.md | 0 ...-Extend-GetBlockHashes-with-target-hash.md | 0 .../eip/Proposal:-NewBlockHashes.md | 0 .../eip/Proposal:-Reversion-Notification.md | 0 .../eip/Proposal:-Transaction-Proxy-Hooks.md | 0 .../newBlockFilter-Improvement-Proposal.md | 0 .../sendTransaction-return-value-proposal.md | 0 .../Dagger-Hashimoto.md | 8 +- .../ethash-dagger-hashimoto/Dagger.md | 0 .../ethash-dagger-hashimoto/Ethash-C-API.md | 0 .../Ethash-DAG-Disk-Storage-Format.md | 0 .../Ethash-Design-Rationale.md | 0 .../ethash-dagger-hashimoto/Ethash.md | 0 .../Ethash_revision_11.md | 0 .../Bad-Block-Reporting.md | 0 .../Bad-Chain-Canary.md | 0 .../Block-Protocol-2.0.md | 4 +- ...ockchain-import-and-export-instructions.md | 0 .../Distributed-Preimage-Archive.md | 0 .../EVM-Subtleties.md | 0 .../Ethereum-Natural-Specification-Format.md | 2 +- .../Ethereum-Wire-Protocol.md | 2 +- .../Light-client-protocol.md | 0 .../Morden.md | 0 .../[english]-patricia-tree.md | 0 .../[english]-rlp.md | 0 .../research/CLL.md | 0 .../research/Chain-Fibers-Redux.md | 0 .../research/Generalized_Merkle_DHT.md | 0 .../research/HPOC_2015.md | 0 .../research/Parallel-Block-Downloads.md | 0 .../research/Problems.md | 0 .../research/Security-Categorization.md | 0 .../research/Security-Issue-Process.md | 0 .../research/Serenity_Wishlist.md | 0 pages/ethereum-toc/[spanish]-ethereum-toc.md | 24 ------ .../Adaptive-Message-IDs.md | 0 .../Adaptive-Peer-Time.md | 2 +- .../infrastructure-networking/Brain-Wallet.md | 0 .../Clearinghouse.md | 0 .../Default-Extra-Data-Standard.md | 0 .../Deterministic_Wallet_Spec.md | 0 .../EVM-JIT-Binary-Interface.md | 0 ...ereum-Raspberry-Pi-e\317\200-Programme.md" | 0 .../Exchange-Integration.md | 0 ...-Inter-exchange-Client-Address-Protocol.md | 0 .../infrastructure-networking/IPv6.md | 0 .../Kademlia-Peer-Selection.md | 0 .../infrastructure-networking/Layers.md | 0 .../infrastructure-networking/Mining.md | 2 +- .../NatSpec-Determination.md | 0 .../Natspec-Example.md | 0 .../Network-Status.md | 0 .../NewBlock-Message.md | 0 .../Raspberry-Pi-instructions.md | 0 .../Registrar-ABI.md | 0 .../URL-Hint-Protocol.md | 0 .../Decentralized-apps-(dapps).md | 0 .../introduction/Ethereum-introduction.md | 0 FAQ.md => pages/introduction/FAQ.md | 0 .../introduction/Gitter-Channels.md | 0 Glossary.md => pages/introduction/Glossary.md | 4 +- Home.md => pages/introduction/Home.md | 0 .../introduction/What-is-Ethereum.md | 14 ++-- .../other-languages/[German]-Clearinghaus.md | 0 ...l-proprio-ambiente-di-sviluppo-Ethereum.md | 0 ...-Introduzione-allo-sviluppo-su-Ethereum.md | 0 .../other-languages/[Italian]-Libro-Bianco.md | 0 ...panese]-Cryptocurrency-Current-Problems.md | 0 ...Japanese]-Ethereum-Development-Tutorial.md | 79 ++++++++----------- .../[Japanese]-Ethereum-TOC.md | 0 .../other-languages/[Japanese]-HPOC_2015.md | 0 .../[Japanese]-Javascript-API.md | 0 .../other-languages/[Japanese]-License.md | 0 .../[Japanese]-Solidity-Tutorial.md | 0 ...71\343\203\221\343\203\274\357\274\211.md" | 0 .../[Japenese]-Ethereum-TOC.md | 0 .../other-languages/[Persian]-Ethereum-TOC.md | 0 .../[Romanian]-Block-Protocol-2.0.md | 0 .../other-languages/[Romanian]-CLL.md | 0 .../other-languages/[Romanian]-Cuprins.md | 0 .../other-languages/[Romanian]-Dagger.md | 0 .../other-languages/[Romanian]-Layers.md | 0 ...omanian]-Limbajul-de-programare-Serpent.md | 0 .../[Romanian]-Wire-Protocol.md | 0 .../[chinese]-ethereum-toc.md | 0 .../{rlp => other-languages}/[chinese]-rlp.md | 0 .../[chinese]-white-paper.md | 0 .../[french]-ethereum-toc.md | 0 .../[german]-ethereum-toc.md | 0 .../{rlp => other-languages}/[german]-rlp.md | 0 .../[german]-white-paper.md | 0 .../[italian]-ethereum-toc.md | 0 .../[japanese]-design-rationale.md | 0 .../[japanese]-patricia-tree.md | 0 .../[japanese]-rlp.md | 0 .../[japanese]-white-paper.md | 0 .../[korean]-white-paper.md | 0 .../[persian]-white-paper.md | 0 .../[romanian]-patricia-tree.md | 0 .../[romanian]-rlp.md | 0 .../[romanian]-white-paper.md | 0 .../other-languages/[spanish]-ethereum-toc.md | 24 ++++++ ...6\207]-Serpent\346\214\207\345\215\227.md" | 0 ...45\235\212Wiki\347\233\256\345\275\225.md" | 0 ...00\345\217\221\350\256\241\345\210\222.md" | 4 +- ...12\346\234\257\350\257\255\350\241\250.md" | 0 ...12\347\231\275\347\232\256\344\271\246.md" | 4 +- ...346\230\216\346\251\237\345\210\266FAQ.md" | 0 ...21\347\273\234\347\212\266\346\200\201.md" | 0 ...\262\320\276-\320\277\320\276-Solidity.md" | 0 Swarm-Hash.md => pages/swarm/Swarm-Hash.md | 0 .../whisper/Whisper-Overview.md | 0 .../whisper/Whisper-PoC-2-Protocol-Spec.md | 0 .../whisper/Whisper-PoC-2-Wire-Protocol.md | 0 .../whisper/Whisper-Wire-Protocol.md | 0 Whisper.md => pages/whisper/Whisper.md | 0 pages/white-paper/[english]-white-paper.md | 24 +++--- 164 files changed, 154 insertions(+), 130 deletions(-) delete mode 100644 LICENSE rename Licensing.md => pages/Licensing.md (100%) rename Middleware-and-Dapp-Project-Ideas.md => pages/Middleware-and-Dapp-Project-Ideas.md (100%) rename Open-positions-&-Schemes.md => pages/Open-job-positions-&-Schemes.md (100%) create mode 100644 pages/Readme.md rename _Sidebar.md => pages/_Sidebar.md (100%) rename Fortnight-In-Ethereum-Template.md => pages/blog-and-notes/Fortnight-In-Ethereum-Template.md (100%) rename Template:-This-Week-in-Ethereum-w-YY.md => pages/blog-and-notes/Template:-This-Week-in-Ethereum-w-YY.md (100%) rename This Week In Ethereum 47.2014.md => pages/blog-and-notes/This Week In Ethereum 47.2014.md (100%) rename Todo-before-alpha.md => pages/blog-and-notes/Todo-before-alpha.md (100%) rename Which-Client?.md => pages/blog-and-notes/stubs/Which-Client?.md (100%) rename Contract-Metadata-Docs-(NatSpec,-ABI).md => pages/dapp-development/Contract-Metadata-Docs-(NatSpec,-ABI).md (100%) rename Dapp-Developer-Resources.md => pages/dapp-development/Dapp-Developer-Resources.md (84%) rename Dapp-using-Meteor.md => pages/dapp-development/Dapp-using-Meteor.md (100%) rename Ethereum-Contract-ABI.md => pages/dapp-development/Ethereum-Contract-ABI.md (100%) rename Ethereum-Development-Tutorial.md => pages/dapp-development/Ethereum-Development-Tutorial.md (100%) rename First-steps-with-ethereum-JSON-RPC.md => pages/dapp-development/First-steps-with-ethereum-JSON-RPC.md (100%) rename JSON-RPC.md => pages/dapp-development/JSON-RPC.md (99%) rename JavaScript-API.md => pages/dapp-development/JavaScript-API.md (98%) rename Javascript-Development-Deficiencies.md => pages/dapp-development/Javascript-Development-Deficiencies.md (100%) rename Mix-Features.md => pages/dapp-development/Mix-Features.md (100%) rename Mix:-The-DApp-IDE.md => pages/dapp-development/Mix:-The-DApp-IDE.md (100%) rename RPC-Testing.md => pages/dapp-development/RPC-Testing.md (100%) rename Standardized_Contract_APIs.md => pages/dapp-development/Standardized_Contract_APIs.md (80%) rename "Useful-\303\220app-Patterns.md" => "pages/dapp-development/Useful-\303\220app-Patterns.md" (100%) rename Serpent-1.0-(old).md => pages/dapp-development/serpent/Serpent-1.0-(old).md (100%) rename Serpent.md => pages/dapp-development/serpent/Serpent.md (100%) rename Serpent_3.0.md => pages/dapp-development/serpent/Serpent_3.0.md (100%) rename Solidity,-Docs-and-ABI.md => pages/dapp-development/solidity/Solidity,-Docs-and-ABI.md (100%) rename Solidity-Changelog.md => pages/dapp-development/solidity/Solidity-Changelog.md (100%) rename Solidity-Features.md => pages/dapp-development/solidity/Solidity-Features.md (100%) rename Solidity-Tutorial.md => pages/dapp-development/solidity/Solidity-Tutorial.md (100%) rename Solidity-standard-library.md => pages/dapp-development/solidity/Solidity-standard-library.md (100%) rename Solidity.md => pages/dapp-development/solidity/Solidity.md (100%) rename Tags-for-Solidity-in-code-documentation.md => pages/dapp-development/solidity/Tags-for-Solidity-in-code-documentation.md (100%) rename The-Solidity-Programming-Language.md => pages/dapp-development/solidity/The-Solidity-Programming-Language.md (100%) rename Node-discovery-protocol.md => pages/dev-technologies/Node-discovery-protocol.md (100%) rename Web3-Secret-Storage-Definition.md => pages/dev-technologies/Web3-Secret-Storage-Definition.md (100%) rename enode-url-format.md => pages/dev-technologies/enode-url-format.md (100%) rename libp2p-Whitepaper.md => pages/dev-technologies/libp2p-Whitepaper.md (100%) rename web.js-0.9.md => pages/dev-technologies/web.js-0.9.md (81%) rename "\303\220\316\236Vp2p-Wire-Protocol.md" => "pages/dev-technologies/\303\220\316\236Vp2p-Wire-Protocol.md" (100%) rename Geth-Dapp-loading-proposal.md => pages/eip/Geth-Dapp-loading-proposal.md (100%) rename JSON-RPC-Error-Codes-Improvement-Proposal.md => pages/eip/JSON-RPC-Error-Codes-Improvement-Proposal.md (100%) rename Mix-improvement-proposal.md => pages/eip/Mix-improvement-proposal.md (100%) rename Proposal:-BlockHashesFromNumbers.md => pages/eip/Proposal:-BlockHashesFromNumbers.md (100%) rename Proposal:-Extend-GetBlockHashes-with-target-hash.md => pages/eip/Proposal:-Extend-GetBlockHashes-with-target-hash.md (100%) rename Proposal:-NewBlockHashes.md => pages/eip/Proposal:-NewBlockHashes.md (100%) rename Proposal:-Reversion-Notification.md => pages/eip/Proposal:-Reversion-Notification.md (100%) rename Proposal:-Transaction-Proxy-Hooks.md => pages/eip/Proposal:-Transaction-Proxy-Hooks.md (100%) rename newBlockFilter-Improvement-Proposal.md => pages/eip/newBlockFilter-Improvement-Proposal.md (100%) rename sendTransaction-return-value-proposal.md => pages/eip/sendTransaction-return-value-proposal.md (100%) rename Dagger-Hashimoto.md => pages/ethash-dagger-hashimoto/Dagger-Hashimoto.md (98%) rename Dagger.md => pages/ethash-dagger-hashimoto/Dagger.md (100%) rename Ethash-C-API.md => pages/ethash-dagger-hashimoto/Ethash-C-API.md (100%) rename Ethash-DAG-Disk-Storage-Format.md => pages/ethash-dagger-hashimoto/Ethash-DAG-Disk-Storage-Format.md (100%) rename Ethash-Design-Rationale.md => pages/ethash-dagger-hashimoto/Ethash-Design-Rationale.md (100%) rename Ethash.md => pages/ethash-dagger-hashimoto/Ethash.md (100%) rename Ethash_revision_11.md => pages/ethash-dagger-hashimoto/Ethash_revision_11.md (100%) rename Bad-Block-Reporting.md => pages/ethereum-and-blockchain-technologies-and-research/Bad-Block-Reporting.md (100%) rename Bad-Chain-Canary.md => pages/ethereum-and-blockchain-technologies-and-research/Bad-Chain-Canary.md (100%) rename Block-Protocol-2.0.md => pages/ethereum-and-blockchain-technologies-and-research/Block-Protocol-2.0.md (99%) rename Blockchain-import-and-export-instructions.md => pages/ethereum-and-blockchain-technologies-and-research/Blockchain-import-and-export-instructions.md (100%) rename Distributed-Preimage-Archive.md => pages/ethereum-and-blockchain-technologies-and-research/Distributed-Preimage-Archive.md (100%) rename Subtleties.md => pages/ethereum-and-blockchain-technologies-and-research/EVM-Subtleties.md (100%) rename Ethereum-Natural-Specification-Format.md => pages/ethereum-and-blockchain-technologies-and-research/Ethereum-Natural-Specification-Format.md (99%) rename Ethereum-Wire-Protocol.md => pages/ethereum-and-blockchain-technologies-and-research/Ethereum-Wire-Protocol.md (97%) rename Light-client-protocol.md => pages/ethereum-and-blockchain-technologies-and-research/Light-client-protocol.md (100%) rename Morden.md => pages/ethereum-and-blockchain-technologies-and-research/Morden.md (100%) rename pages/{patricia-tree => ethereum-and-blockchain-technologies-and-research}/[english]-patricia-tree.md (100%) rename pages/{rlp => ethereum-and-blockchain-technologies-and-research}/[english]-rlp.md (100%) rename CLL.md => pages/ethereum-and-blockchain-technologies-and-research/research/CLL.md (100%) rename Chain-Fibers-Redux.md => pages/ethereum-and-blockchain-technologies-and-research/research/Chain-Fibers-Redux.md (100%) rename Generalized_Merkle_DHT.md => pages/ethereum-and-blockchain-technologies-and-research/research/Generalized_Merkle_DHT.md (100%) rename HPOC_2015.md => pages/ethereum-and-blockchain-technologies-and-research/research/HPOC_2015.md (100%) rename Parallel-Block-Downloads.md => pages/ethereum-and-blockchain-technologies-and-research/research/Parallel-Block-Downloads.md (100%) rename Problems.md => pages/ethereum-and-blockchain-technologies-and-research/research/Problems.md (100%) rename Security-Categorization.md => pages/ethereum-and-blockchain-technologies-and-research/research/Security-Categorization.md (100%) rename Security-Issue-Process.md => pages/ethereum-and-blockchain-technologies-and-research/research/Security-Issue-Process.md (100%) rename Serenity_Wishlist.md => pages/ethereum-and-blockchain-technologies-and-research/research/Serenity_Wishlist.md (100%) delete mode 100644 pages/ethereum-toc/[spanish]-ethereum-toc.md rename Adaptive-Message-IDs.md => pages/infrastructure-networking/Adaptive-Message-IDs.md (100%) rename Adaptive-Peer-Time.md => pages/infrastructure-networking/Adaptive-Peer-Time.md (83%) rename Brain-Wallet.md => pages/infrastructure-networking/Brain-Wallet.md (100%) rename Clearinghouse.md => pages/infrastructure-networking/Clearinghouse.md (100%) rename Default-Extra-Data-Standard.md => pages/infrastructure-networking/Default-Extra-Data-Standard.md (100%) rename Deterministic_Wallet_Spec.md => pages/infrastructure-networking/Deterministic_Wallet_Spec.md (100%) rename EVM-JIT-Binary-Interface.md => pages/infrastructure-networking/EVM-JIT-Binary-Interface.md (100%) rename "e\317\200-Programme.md" => "pages/infrastructure-networking/Ethereum-Raspberry-Pi-e\317\200-Programme.md" (100%) rename Exchange-Integration.md => pages/infrastructure-networking/Exchange-Integration.md (100%) rename ICAP:-Inter-exchange-Client-Address-Protocol.md => pages/infrastructure-networking/ICAP:-Inter-exchange-Client-Address-Protocol.md (100%) rename IPv6.md => pages/infrastructure-networking/IPv6.md (100%) rename Kademlia-Peer-Selection.md => pages/infrastructure-networking/Kademlia-Peer-Selection.md (100%) rename Layers.md => pages/infrastructure-networking/Layers.md (100%) rename Mining.md => pages/infrastructure-networking/Mining.md (88%) rename NatSpec-Determination.md => pages/infrastructure-networking/NatSpec-Determination.md (100%) rename Natspec-Example.md => pages/infrastructure-networking/Natspec-Example.md (100%) rename Network-Status.md => pages/infrastructure-networking/Network-Status.md (100%) rename NewBlock-Message.md => pages/infrastructure-networking/NewBlock-Message.md (100%) rename Raspberry-Pi-instructions.md => pages/infrastructure-networking/Raspberry-Pi-instructions.md (100%) rename Registrar-ABI.md => pages/infrastructure-networking/Registrar-ABI.md (100%) rename URL-Hint-Protocol.md => pages/infrastructure-networking/URL-Hint-Protocol.md (100%) rename Decentralized-apps-(dapps).md => pages/introduction/Decentralized-apps-(dapps).md (100%) rename Ethereum-introduction.md => pages/introduction/Ethereum-introduction.md (100%) rename FAQ.md => pages/introduction/FAQ.md (100%) rename Gitter-Channels.md => pages/introduction/Gitter-Channels.md (100%) rename Glossary.md => pages/introduction/Glossary.md (99%) rename Home.md => pages/introduction/Home.md (100%) rename What-is-Ethereum.md => pages/introduction/What-is-Ethereum.md (98%) rename [German]-Clearinghaus.md => pages/other-languages/[German]-Clearinghaus.md (100%) rename [Italian]-Impostare-il-proprio-ambiente-di-sviluppo-Ethereum.md => pages/other-languages/[Italian]-Impostare-il-proprio-ambiente-di-sviluppo-Ethereum.md (100%) rename [Italian]-Introduzione-allo-sviluppo-su-Ethereum.md => pages/other-languages/[Italian]-Introduzione-allo-sviluppo-su-Ethereum.md (100%) rename [Italian]-Libro-Bianco.md => pages/other-languages/[Italian]-Libro-Bianco.md (100%) rename [Japanese]-Cryptocurrency-Current-Problems.md => pages/other-languages/[Japanese]-Cryptocurrency-Current-Problems.md (100%) rename [Japanese]--Ethereum-Development-Tutorial.md => pages/other-languages/[Japanese]-Ethereum-Development-Tutorial.md (64%) rename [Japanese]-Ethereum-TOC.md => pages/other-languages/[Japanese]-Ethereum-TOC.md (100%) rename [Japanese]-HPOC_2015.md => pages/other-languages/[Japanese]-HPOC_2015.md (100%) rename [Japanese]-Javascript-API.md => pages/other-languages/[Japanese]-Javascript-API.md (100%) rename [Japanese]--License.md => pages/other-languages/[Japanese]-License.md (100%) rename [Japanese]-Solidity-Tutorial.md => pages/other-languages/[Japanese]-Solidity-Tutorial.md (100%) rename "[Japanese]-Whisper-\357\274\210\343\202\246\343\202\243\343\202\271\343\203\221\343\203\274\357\274\211.md" => "pages/other-languages/[Japanese]-Whisper-\357\274\210\343\202\246\343\202\243\343\202\271\343\203\221\343\203\274\357\274\211.md" (100%) rename [Japenese]-Ethereum-TOC.md => pages/other-languages/[Japenese]-Ethereum-TOC.md (100%) rename [Persian]-Ethereum-TOC.md => pages/other-languages/[Persian]-Ethereum-TOC.md (100%) rename [Romanian]-Block-Protocol-2.0.md => pages/other-languages/[Romanian]-Block-Protocol-2.0.md (100%) rename [Romanian]-CLL.md => pages/other-languages/[Romanian]-CLL.md (100%) rename [Romanian]-Cuprins.md => pages/other-languages/[Romanian]-Cuprins.md (100%) rename [Romanian]-Dagger.md => pages/other-languages/[Romanian]-Dagger.md (100%) rename [Romanian]-Layers.md => pages/other-languages/[Romanian]-Layers.md (100%) rename [Romanian]-Limbajul-de-programare-Serpent.md => pages/other-languages/[Romanian]-Limbajul-de-programare-Serpent.md (100%) rename [Romanian]-Wire-Protocol.md => pages/other-languages/[Romanian]-Wire-Protocol.md (100%) rename pages/{ethereum-toc => other-languages}/[chinese]-ethereum-toc.md (100%) rename pages/{rlp => other-languages}/[chinese]-rlp.md (100%) rename pages/{white-paper => other-languages}/[chinese]-white-paper.md (100%) rename pages/{ethereum-toc => other-languages}/[french]-ethereum-toc.md (100%) rename pages/{ethereum-toc => other-languages}/[german]-ethereum-toc.md (100%) rename pages/{rlp => other-languages}/[german]-rlp.md (100%) rename pages/{white-paper => other-languages}/[german]-white-paper.md (100%) rename pages/{ethereum-toc => other-languages}/[italian]-ethereum-toc.md (100%) rename pages/{design-rationale => other-languages}/[japanese]-design-rationale.md (100%) rename pages/{patricia-tree => other-languages}/[japanese]-patricia-tree.md (100%) rename pages/{rlp => other-languages}/[japanese]-rlp.md (100%) rename pages/{white-paper => other-languages}/[japanese]-white-paper.md (100%) rename pages/{white-paper => other-languages}/[korean]-white-paper.md (100%) rename pages/{white-paper => other-languages}/[persian]-white-paper.md (100%) rename pages/{patricia-tree => other-languages}/[romanian]-patricia-tree.md (100%) rename pages/{rlp => other-languages}/[romanian]-rlp.md (100%) rename pages/{white-paper => other-languages}/[romanian]-white-paper.md (100%) create mode 100644 pages/other-languages/[spanish]-ethereum-toc.md rename "[\344\270\255\346\226\207]-Serpent\346\214\207\345\215\227.md" => "pages/other-languages/[\344\270\255\346\226\207]-Serpent\346\214\207\345\215\227.md" (100%) rename "[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212Wiki\347\233\256\345\275\225.md" => "pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212Wiki\347\233\256\345\275\225.md" (100%) rename "[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\345\274\200\345\217\221\350\256\241\345\210\222.md" => "pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\345\274\200\345\217\221\350\256\241\345\210\222.md" (99%) rename "[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\346\234\257\350\257\255\350\241\250.md" => "pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\346\234\257\350\257\255\350\241\250.md" (100%) rename "[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\347\231\275\347\232\256\344\271\246.md" => "pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\347\231\275\347\232\256\344\271\246.md" (99%) rename "[\344\270\255\346\226\207]-\346\254\212\347\233\212\350\255\211\346\230\216\346\251\237\345\210\266FAQ.md" => "pages/other-languages/[\344\270\255\346\226\207]-\346\254\212\347\233\212\350\255\211\346\230\216\346\251\237\345\210\266FAQ.md" (100%) rename "[\344\270\255\346\226\207]-\347\275\221\347\273\234\347\212\266\346\200\201.md" => "pages/other-languages/[\344\270\255\346\226\207]-\347\275\221\347\273\234\347\212\266\346\200\201.md" (100%) rename "\320\240\321\203\320\272\320\276\320\262\320\276\320\264\321\201\321\202\320\262\320\276-\320\277\320\276-Solidity.md" => "pages/other-languages/\320\240\321\203\320\272\320\276\320\262\320\276\320\264\321\201\321\202\320\262\320\276-\320\277\320\276-Solidity.md" (100%) rename Swarm-Hash.md => pages/swarm/Swarm-Hash.md (100%) rename Whisper-Overview.md => pages/whisper/Whisper-Overview.md (100%) rename Whisper-PoC-2-Protocol-Spec.md => pages/whisper/Whisper-PoC-2-Protocol-Spec.md (100%) rename Whisper-PoC-2-Wire-Protocol.md => pages/whisper/Whisper-PoC-2-Wire-Protocol.md (100%) rename Whisper-Wire-Protocol.md => pages/whisper/Whisper-Wire-Protocol.md (100%) rename Whisper.md => pages/whisper/Whisper.md (100%) diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 40d9af62e..000000000 --- a/LICENSE +++ /dev/null @@ -1,5 +0,0 @@ -The license for this repository is CC BY-SA 4.0. - -A human-readable summary (and not a substitute) of the license is [here](https://creativecommons.org/licenses/by-sa/4.0/). - -The license is [here](https://creativecommons.org/licenses/by-sa/4.0/legalcode). diff --git a/Licensing.md b/pages/Licensing.md similarity index 100% rename from Licensing.md rename to pages/Licensing.md diff --git a/Middleware-and-Dapp-Project-Ideas.md b/pages/Middleware-and-Dapp-Project-Ideas.md similarity index 100% rename from Middleware-and-Dapp-Project-Ideas.md rename to pages/Middleware-and-Dapp-Project-Ideas.md diff --git a/Open-positions-&-Schemes.md b/pages/Open-job-positions-&-Schemes.md similarity index 100% rename from Open-positions-&-Schemes.md rename to pages/Open-job-positions-&-Schemes.md diff --git a/pages/Readme.md b/pages/Readme.md new file mode 100644 index 000000000..6e4b622fe --- /dev/null +++ b/pages/Readme.md @@ -0,0 +1,14 @@ +Newcomers and those seeking an introduction to Ethereum may go to https://ethereum.org or https://github.com/ethereum/wiki/wiki. + +Note that you can proofread while you read and learn about anything. + +# Contribution guidelines +Please just **edit the pages in the wiki directly** as shown in the sidebar here: https://github.com/ethereum/wiki/wiki, rather than making **pull requests**. + +Please only create an **issue** if you can't fix it by editing yourself, and only if it is related to the wiki. If it is a technical issue e.g. with [web3 or JSON.RPC](https://github.com/ethereum/web3.js/issues), [geth](https://github.com/ethereum/go-ethereum/issues), [Mist](https://github.com/ethereum/mist) (although note that Mist isn't really user-ready yet, so using alternatives like [MyEtherWallet](https://www.myetherwallet.com/) is recommended instead), etc., please post an issue in the repo for that project as well, and reference the issue that you create in this repo (by copying and pasting the link to the issue in this repo in a comment in the issue in the relevant project repo). + +If you are **translating** an article, please **create a new page** and create the translation in that. Do not edit an existing article by translating it. Someone did this with the home wiki, changing the title, and this actually caused the home page to just direct to a list of pages in the wiki, and made it hard to find the edited home page as the title was changed to Arabic. So **do not edit the title of an article**. + +If you have experience with editing on Wikipedia, then that will help with knowing how to edit this wiki, although the contribution rules are less strict. Referencing facts is a key writing and proofreading task, as well as checking that information is up-to-date (and updating it if otherwise), correcting grammar, typos, and spelling; and making the wiki comprehensive and easy to understand. + +Other rules, such as a neutral point of view and no original research are desirable, but may be hard to maintain. Notability is less relevant. diff --git a/_Sidebar.md b/pages/_Sidebar.md similarity index 100% rename from _Sidebar.md rename to pages/_Sidebar.md diff --git a/Fortnight-In-Ethereum-Template.md b/pages/blog-and-notes/Fortnight-In-Ethereum-Template.md similarity index 100% rename from Fortnight-In-Ethereum-Template.md rename to pages/blog-and-notes/Fortnight-In-Ethereum-Template.md diff --git a/Template:-This-Week-in-Ethereum-w-YY.md b/pages/blog-and-notes/Template:-This-Week-in-Ethereum-w-YY.md similarity index 100% rename from Template:-This-Week-in-Ethereum-w-YY.md rename to pages/blog-and-notes/Template:-This-Week-in-Ethereum-w-YY.md diff --git a/This Week In Ethereum 47.2014.md b/pages/blog-and-notes/This Week In Ethereum 47.2014.md similarity index 100% rename from This Week In Ethereum 47.2014.md rename to pages/blog-and-notes/This Week In Ethereum 47.2014.md diff --git a/Todo-before-alpha.md b/pages/blog-and-notes/Todo-before-alpha.md similarity index 100% rename from Todo-before-alpha.md rename to pages/blog-and-notes/Todo-before-alpha.md diff --git a/Which-Client?.md b/pages/blog-and-notes/stubs/Which-Client?.md similarity index 100% rename from Which-Client?.md rename to pages/blog-and-notes/stubs/Which-Client?.md diff --git a/Contract-Metadata-Docs-(NatSpec,-ABI).md b/pages/dapp-development/Contract-Metadata-Docs-(NatSpec,-ABI).md similarity index 100% rename from Contract-Metadata-Docs-(NatSpec,-ABI).md rename to pages/dapp-development/Contract-Metadata-Docs-(NatSpec,-ABI).md diff --git a/Dapp-Developer-Resources.md b/pages/dapp-development/Dapp-Developer-Resources.md similarity index 84% rename from Dapp-Developer-Resources.md rename to pages/dapp-development/Dapp-Developer-Resources.md index 96831e95d..531ce5405 100644 --- a/Dapp-Developer-Resources.md +++ b/pages/dapp-development/Dapp-Developer-Resources.md @@ -4,7 +4,7 @@ As a Ðapp developer you have three main resources which allow Ðapp development - [Web3 JavaScript API](https://github.com/ethereum/wiki/wiki/JavaScript-API) - This is the main JavaScript SDK to use when you want to interact with a nodes API - [JSON RPC API](https://github.com/ethereum/wiki/wiki/JSON-RPC) - This is the low level JSON RPC 2.0 interface to interface with a node. This API is used by the [Web3 JavaScript API](https://github.com/ethereum/wiki/wiki/JavaScript-API). -- [Solidity Documentation](https://ethereum.github.io/solidity/docs/home/) - Solidity is the Ethereum developed Smart Contract language, which compiles to EVM (Ethereum Virtual Machine) opcodes. +- [Solidity Documentation](https://solidity.readthedocs.io/en/latest/) - Solidity is the Ethereum developed Smart Contract language, which compiles to EVM (Ethereum Virtual Machine) opcodes. ### Other Resources: @@ -14,4 +14,4 @@ As a Ðapp developer you have three main resources which allow Ðapp development ### Useful read - [FAQ](https://github.com/ethereum/wiki/wiki/FAQ) - Collection of links, useful for understanding the Ethereum eco system. -- [Glossary](https://github.com/ethereum/wiki/wiki/Glossary) - Great explanation of Blockchain related terms. \ No newline at end of file +- [Glossary](https://github.com/ethereum/wiki/wiki/Glossary) - Great explanation of Blockchain related terms. diff --git a/Dapp-using-Meteor.md b/pages/dapp-development/Dapp-using-Meteor.md similarity index 100% rename from Dapp-using-Meteor.md rename to pages/dapp-development/Dapp-using-Meteor.md diff --git a/Ethereum-Contract-ABI.md b/pages/dapp-development/Ethereum-Contract-ABI.md similarity index 100% rename from Ethereum-Contract-ABI.md rename to pages/dapp-development/Ethereum-Contract-ABI.md diff --git a/Ethereum-Development-Tutorial.md b/pages/dapp-development/Ethereum-Development-Tutorial.md similarity index 100% rename from Ethereum-Development-Tutorial.md rename to pages/dapp-development/Ethereum-Development-Tutorial.md diff --git a/First-steps-with-ethereum-JSON-RPC.md b/pages/dapp-development/First-steps-with-ethereum-JSON-RPC.md similarity index 100% rename from First-steps-with-ethereum-JSON-RPC.md rename to pages/dapp-development/First-steps-with-ethereum-JSON-RPC.md diff --git a/JSON-RPC.md b/pages/dapp-development/JSON-RPC.md similarity index 99% rename from JSON-RPC.md rename to pages/dapp-development/JSON-RPC.md index dab857df8..33f9d64d1 100644 --- a/JSON-RPC.md +++ b/pages/dapp-development/JSON-RPC.md @@ -2089,7 +2089,7 @@ params: [{ ##### Example ```js // Request -curl -X POST --data '{"jsonrpc":"2.0","method":"shh_post","params":[{"from":"0xc931d93e97ab07fe42d923478ba2465f2..","topics": ["0x68656c6c6f20776f726c64"],"payload":"0x68656c6c6f20776f726c64","ttl":0x64,"priority":0x64}],"id":73}' +curl -X POST --data '{"jsonrpc":"2.0","method":"shh_post","params":[{"from":"0xc931d93e97ab07fe42d923478ba2465f2..","topics": ["0x68656c6c6f20776f726c64"],"payload":"0x68656c6c6f20776f726c64","ttl":"0x64","priority":"0x64"}],"id":73}' // Result { @@ -2176,7 +2176,7 @@ none ##### Example ```js // Request -curl -X POST --data '{"jsonrpc":"2.0","method":"shh_newIdentity","params":[],"id":73}' +curl -X POST --data '{"jsonrpc":"2.0","method":"shh_newGroup","params":[],"id":73}' // Result { @@ -2209,7 +2209,7 @@ params: [ ##### Example ```js // Request -curl -X POST --data '{"jsonrpc":"2.0","method":"shh_hasIdentity","params":["0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1"],"id":73}' +curl -X POST --data '{"jsonrpc":"2.0","method":"shh_addToGroup","params":["0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1"],"id":73}' // Result { @@ -2378,4 +2378,4 @@ See [shh_getFilterChanges](#shh_getfilterchanges) curl -X POST --data '{"jsonrpc":"2.0","method":"shh_getMessages","params":["0x7"],"id":73}' ``` -Result see [shh_getFilterChanges](#shh_getfilterchanges) \ No newline at end of file +Result see [shh_getFilterChanges](#shh_getfilterchanges) diff --git a/JavaScript-API.md b/pages/dapp-development/JavaScript-API.md similarity index 98% rename from JavaScript-API.md rename to pages/dapp-development/JavaScript-API.md index 4767cb94c..213269b39 100644 --- a/JavaScript-API.md +++ b/pages/dapp-development/JavaScript-API.md @@ -15,7 +15,7 @@ If you want to look at some more sophisticated examples using web3.js check out As this API is designed to work with a local RPC node and all its functions are by default use synchronous HTTP requests.con -If you want to make asynchronous request, you can pass an optional callback as the last parameter to most functions. +If you want to make an asynchronous request, you can pass an optional callback as the last parameter to most functions. All callbacks are using an [error first callback](http://fredkschott.com/post/2014/03/understanding-error-first-callbacks-in-node-js/) style: ```js @@ -60,7 +60,7 @@ balance.plus(21).toString(10); // toString(10) converts it to a number string // "131242344353464564564574574567477" ``` -The next example wouldn't work as we have more than 20 floating points, therefore it is recommended to keep you balance always in *wei* and only transform it to other units when presenting to the user: +The next example wouldn't work as we have more than 20 floating points, therefore it is recommended that you always keep your balance in *wei* and only transform it to other units when presenting to the user: ```js var balance = new BigNumber('13124.234435346456466666457455567456'); @@ -86,6 +86,7 @@ balance.plus(21).toString(10); // toString(10) converts it to a number string, b * [toAscii(hexString)](#web3toascii) * [fromAscii(textString, [padding])](#web3fromascii) * [toDecimal(hexString)](#web3todecimal) + * [toChecksumAddress(string)](#web3tochecksumaddress) * [fromDecimal(number)](#web3fromdecimal) * [fromWei(numberStringOrBigNumber, unit)](#web3fromwei) * [toWei(numberStringOrBigNumber, unit)](#web3towei) @@ -173,7 +174,7 @@ The `web3` object provides all methods. ```js var Web3 = require('web3'); // create an instance of web3 using the HTTP provider. -// NOTE in mist web3 is already available, so check first if its available before instantiating +// NOTE in mist web3 is already available, so check first if it's available before instantiating var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); ``` @@ -472,6 +473,30 @@ console.log(str2); // "0x657468657265756d000000000000000000000000000000000000000 *** +#### web3.toChecksumAddress + + web3.toChecksumAddress(hexString); + +Converts a string to the checksummed address equivalent. + +##### Parameters + +1. `String` - A string to be converted to a checksummed address. + + +##### Returns + +`String` - A string containing the checksummed address. + +##### Example + +```js +var myAddress = web3.toChecksumAddress('0xa0c876ec9f2d817c4304a727536f36363840c02c'); +console.log(myAddress); // '0xA0C876eC9F2d817c4304A727536f36363840c02c' +``` + +*** + #### web3.toDecimal web3.toDecimal(hexString); @@ -2388,4 +2413,4 @@ console.log(address); // '00c5496aee77c1ba1f0854206a26dda82a81d6d8' ```js var i = new web3.eth.iban('XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS'); console.log(i.toString()); // 'XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS' -``` \ No newline at end of file +``` diff --git a/Javascript-Development-Deficiencies.md b/pages/dapp-development/Javascript-Development-Deficiencies.md similarity index 100% rename from Javascript-Development-Deficiencies.md rename to pages/dapp-development/Javascript-Development-Deficiencies.md diff --git a/Mix-Features.md b/pages/dapp-development/Mix-Features.md similarity index 100% rename from Mix-Features.md rename to pages/dapp-development/Mix-Features.md diff --git a/Mix:-The-DApp-IDE.md b/pages/dapp-development/Mix:-The-DApp-IDE.md similarity index 100% rename from Mix:-The-DApp-IDE.md rename to pages/dapp-development/Mix:-The-DApp-IDE.md diff --git a/RPC-Testing.md b/pages/dapp-development/RPC-Testing.md similarity index 100% rename from RPC-Testing.md rename to pages/dapp-development/RPC-Testing.md diff --git a/Standardized_Contract_APIs.md b/pages/dapp-development/Standardized_Contract_APIs.md similarity index 80% rename from Standardized_Contract_APIs.md rename to pages/dapp-development/Standardized_Contract_APIs.md index f1682d44c..68ccb0a68 100644 --- a/Standardized_Contract_APIs.md +++ b/pages/dapp-development/Standardized_Contract_APIs.md @@ -3,11 +3,16 @@ name: Standardized Contract APIs category: --- -Although Ethereum allows developers to create absolutely any kind of application without restriction to specific feature types, and prides itself on its "lack of features", there is nevertheless a need to standardize certain very common use cases in order to allow users and applications to more easily interact with each other. This includes sending currency units, registering names, making offers on exchanges, and other similar functions. A standard typically consists of a set of function signatures for a few methods, eg. `send`, `register`, `delete`, providing the set of arguments and their formats in the [Ethereum contract ABI](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI) language. +Ethereum allows you to standardize common use cases that allow users and applications to more easily interact with each other. This includes currency units, registering names, making offers on exchanges, and other similar functions. A standard typically consists of function signatures for methods, eg. `send`, `register`, `delete`, providing the set of arguments and their formats in the [Ethereum contract ABI](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI) language. The standards described below have sample implementations available [here](https://github.com/ethereum/dapp-bin/tree/master/standardized_contract_apis). -All function names are in lower camelCase (eg. `sendCoin`) and all event names are in upper CamelCase (eg. `CoinTransfer`). Input variables are in underscore-prefixed lower camelCase (eg. `_offerId`), and output variables are `_r` for pure getter (ie. constant) functions, `_success` (always boolean) when denoting success or failure, and other values (eg. `_maxValue`) for methods that perform an action but need to return a value as an identifier. Addresses are referred to using `_address` when generic, and otherwise if a more specific description exists (eg. `_from`, `_to`). +All function names are in lower camelCase (eg. `sendCoin`), and all event names are in upper CamelCase (eg. `CoinTransfer`). + +Input variables are in underscore-prefixed lower camelCase (eg. `_offerId`). + +Output variables are `_r` for pure getter (ie. constant) functions - `_success` (always boolean) when denoting success or failur, and other values (eg. `_maxValue`) for methods that perform an action but need to return a value as an identifier. +Addresses are referred to using `_address` when generic, and otherwise if a more specific description exists (eg. `_from`, `_to`). # Transferable Fungibles @@ -39,7 +44,7 @@ balanceOf(address _address) constant returns (uint256 balance) Get the account balance of another account with address `_address` --- -The `transferFrom` method is used for a "direct debit" workflow, allowing contracts to send coins on your behalf, for example to "deposit" to a contract address and/or to charge fees in sub-currencies; the command should fail unless the `_from` account has deliberately authorized the sender of the message via some mechanism; we propose these standardized APIs for approval: +The `transferFrom` method is used for a "direct debit" workflow, allowing contracts to send coins on your behalf, for example to "deposit" to a contract address and/or to charge fees in sub-currencies. The command should fail unless the `_from` account has deliberately authorized the sender of the message via some mechanism. We propose these standardized APIs for approval: #### approve @@ -133,7 +138,7 @@ baseUnit(address _token) constant returns (uint256) Sets or returns the base unit of a token. Although most tokens are displayed to the final user as containing decimal points, token values are unsigned integers counting in the smallest possible unit. The client should always display the total units divided by `baseUnit`. Base units can be any integer but we suggest only using powers of 10. At the moment there is no support for multiple sub-units. -Example: Bob has a balance of 100000 BobTokens, whose base unit is 100. His balance will be displayed on the client as **BOB$100.00** +Example: Bob has a balance of 100000 BobTokens whose base unit is 100. His balance will be displayed on the client as **BOB$100.00** ## Registries @@ -263,7 +268,7 @@ setFeeCurrency(address _feeCurrency) Sets the currency that the fee is paid in -The latter two methods are optional; also, note that the fee may be charged either in ether or subcurrency; if the contract charges in ether then the `setFeeCurrency` method is unnecessary. +The latter two methods are optional. Also, note that the fee may be charged either in ether or subcurrency. If the contract charges in ether then the `setFeeCurrency` method is unnecessary. ## Forwarding contracts (eg. multisig) @@ -287,4 +292,4 @@ confirm(bytes32 _id) returns (bool _success) Confirm a pending message with a particular ID using your account; returns success or failure. If enough confirmations are made, sends the message along. -Access policies can be of any form, eg. multisig, an arbitrary CNF boolean formula, a scheme that depends on the _value_ or _contents_ of a transaction, etc. \ No newline at end of file +Access policies can be of any form, eg. multisig, an arbitrary CNF boolean formula, a scheme that depends on the _value_ or _contents_ of a transaction, etc. diff --git "a/Useful-\303\220app-Patterns.md" "b/pages/dapp-development/Useful-\303\220app-Patterns.md" similarity index 100% rename from "Useful-\303\220app-Patterns.md" rename to "pages/dapp-development/Useful-\303\220app-Patterns.md" diff --git a/Serpent-1.0-(old).md b/pages/dapp-development/serpent/Serpent-1.0-(old).md similarity index 100% rename from Serpent-1.0-(old).md rename to pages/dapp-development/serpent/Serpent-1.0-(old).md diff --git a/Serpent.md b/pages/dapp-development/serpent/Serpent.md similarity index 100% rename from Serpent.md rename to pages/dapp-development/serpent/Serpent.md diff --git a/Serpent_3.0.md b/pages/dapp-development/serpent/Serpent_3.0.md similarity index 100% rename from Serpent_3.0.md rename to pages/dapp-development/serpent/Serpent_3.0.md diff --git a/Solidity,-Docs-and-ABI.md b/pages/dapp-development/solidity/Solidity,-Docs-and-ABI.md similarity index 100% rename from Solidity,-Docs-and-ABI.md rename to pages/dapp-development/solidity/Solidity,-Docs-and-ABI.md diff --git a/Solidity-Changelog.md b/pages/dapp-development/solidity/Solidity-Changelog.md similarity index 100% rename from Solidity-Changelog.md rename to pages/dapp-development/solidity/Solidity-Changelog.md diff --git a/Solidity-Features.md b/pages/dapp-development/solidity/Solidity-Features.md similarity index 100% rename from Solidity-Features.md rename to pages/dapp-development/solidity/Solidity-Features.md diff --git a/Solidity-Tutorial.md b/pages/dapp-development/solidity/Solidity-Tutorial.md similarity index 100% rename from Solidity-Tutorial.md rename to pages/dapp-development/solidity/Solidity-Tutorial.md diff --git a/Solidity-standard-library.md b/pages/dapp-development/solidity/Solidity-standard-library.md similarity index 100% rename from Solidity-standard-library.md rename to pages/dapp-development/solidity/Solidity-standard-library.md diff --git a/Solidity.md b/pages/dapp-development/solidity/Solidity.md similarity index 100% rename from Solidity.md rename to pages/dapp-development/solidity/Solidity.md diff --git a/Tags-for-Solidity-in-code-documentation.md b/pages/dapp-development/solidity/Tags-for-Solidity-in-code-documentation.md similarity index 100% rename from Tags-for-Solidity-in-code-documentation.md rename to pages/dapp-development/solidity/Tags-for-Solidity-in-code-documentation.md diff --git a/The-Solidity-Programming-Language.md b/pages/dapp-development/solidity/The-Solidity-Programming-Language.md similarity index 100% rename from The-Solidity-Programming-Language.md rename to pages/dapp-development/solidity/The-Solidity-Programming-Language.md diff --git a/pages/design-rationale/[english]-design-rationale.md b/pages/design-rationale/[english]-design-rationale.md index dec648c00..c50bcedbb 100644 --- a/pages/design-rationale/[english]-design-rationale.md +++ b/pages/design-rationale/[english]-design-rationale.md @@ -209,7 +209,7 @@ Some particular design decisions that were made: The function and purpose of some opcodes in the VM is obvious, however other opcodes are less so. Some particular justifications are given below: -* **ADDMOD**, **MULMOD**: in most cases, `addmod(a, b, c) = a * b % c`. However, in the specific case of many classes of elliptic curve cryptography, 32-byte modular arithmetic is used, and doing `a * b % c` directly is therefore actually doing `((a * b) % 2^256) % c`, which gives a completely different result. A formula that calculates `a * b % c` with 32-byte values in 32 bytes of space is rather nontrivial and bulky. +* **ADDMOD**, **MULMOD**: in most cases, `mulmod(a, b, c) = a * b % c`. However, in the specific case of many classes of elliptic curve cryptography, 32-byte modular arithmetic is used, and doing `a * b % c` directly is therefore actually doing `((a * b) % 2^256) % c`, which gives a completely different result. A formula that calculates `a * b % c` with 32-byte values in 32 bytes of space is rather nontrivial and bulky. * **SIGNEXTEND**: the purpose of SIGNEXTEND is to facilitate typecasting from a larger signed integer to a smaller signed integer. Small signed integers are useful because JIT-compiled virtual machines may in the future be able to detect long-running chunks of code that deals primarily with 32-byte integers and speed it up considerably. * **SHA3**: SHA3 is very highly applicable in Ethereum code as secure infinite-sized hash maps that use storage will likely need to use a secure hash function so as to prevent malicious collisions, as well as for verifying Merkle trees and even verifying Ethereum-like data structures. A key point is that its companions `SHA256`, `ECRECOVER` and `RIPEMD160` are included not as opcodes but as pseudo-contracts. The purpose of this is to place them into a separate category so that, if/when we come up with a proper "native extensions" system later, more such contracts can be added without filling up the opcode space. * **ORIGIN**: the primary use of the ORIGIN opcode, which provides the sender of a transaction, is to allow contracts to make refund payments for gas. @@ -220,4 +220,4 @@ The function and purpose of some opcodes in the VM is obvious, however other opc * **LOG**: LOG is meant to log events, see trie usage section above. * **CALLCODE**: the purpose of this is to allow contracts to call "functions" in the form of code stored in other contracts, with a separate stack and memory, but using the contract's own storage. This makes it much easier to scalably implement "standard libraries" of code on the blockchain. * **SUICIDE**: an opcode which allows a contract to quickly delete itself if it is no longer needed. The fact that SUICIDES are processed at the end of transaction execution, and not immediately, is motivated by the fact that having the ability to revert suicides that were already executed would substantially increase the complexity of the cache that would be required in an efficient VM implementation. -* **PC**: although theoretically not necessary, as all instances of the PC opcode can be replaced by simply putting in the actual program counter at that index as a push, using PC in code allows for the creation of position-independent code (ie. compiled functions which can be copy/pasted into other contracts, and do not break if they end up at different indices). \ No newline at end of file +* **PC**: although theoretically not necessary, as all instances of the PC opcode can be replaced by simply putting in the actual program counter at that index as a push, using PC in code allows for the creation of position-independent code (ie. compiled functions which can be copy/pasted into other contracts, and do not break if they end up at different indices). diff --git a/Node-discovery-protocol.md b/pages/dev-technologies/Node-discovery-protocol.md similarity index 100% rename from Node-discovery-protocol.md rename to pages/dev-technologies/Node-discovery-protocol.md diff --git a/Web3-Secret-Storage-Definition.md b/pages/dev-technologies/Web3-Secret-Storage-Definition.md similarity index 100% rename from Web3-Secret-Storage-Definition.md rename to pages/dev-technologies/Web3-Secret-Storage-Definition.md diff --git a/enode-url-format.md b/pages/dev-technologies/enode-url-format.md similarity index 100% rename from enode-url-format.md rename to pages/dev-technologies/enode-url-format.md diff --git a/libp2p-Whitepaper.md b/pages/dev-technologies/libp2p-Whitepaper.md similarity index 100% rename from libp2p-Whitepaper.md rename to pages/dev-technologies/libp2p-Whitepaper.md diff --git a/web.js-0.9.md b/pages/dev-technologies/web.js-0.9.md similarity index 81% rename from web.js-0.9.md rename to pages/dev-technologies/web.js-0.9.md index 9e13ed414..ad77e2330 100644 --- a/web.js-0.9.md +++ b/pages/dev-technologies/web.js-0.9.md @@ -7,7 +7,7 @@ Web3.js 0.9 changes I would like to apply KISS principle to web3.js. I used the library recently much more and I realised that we are doing to many things implicitly. eg: -1, newFilter it should either get all logs or poll for new logs. It's shouldn't do both in the same time. In my story, I don't want to poll for filter changes, but I want to get all logs between block X and Y. Same as caktux here: https://github.com/ethereum/web3.js/issues/250 +1, newFilter it should either get all logs or poll for new logs. It shouldn't do both in the same time. In my story, I don't want to poll for filter changes, but I want to get all logs between block X and Y. Same as caktux here: https://github.com/ethereum/web3.js/issues/250 examples of new solution diff --git "a/\303\220\316\236Vp2p-Wire-Protocol.md" "b/pages/dev-technologies/\303\220\316\236Vp2p-Wire-Protocol.md" similarity index 100% rename from "\303\220\316\236Vp2p-Wire-Protocol.md" rename to "pages/dev-technologies/\303\220\316\236Vp2p-Wire-Protocol.md" diff --git a/Geth-Dapp-loading-proposal.md b/pages/eip/Geth-Dapp-loading-proposal.md similarity index 100% rename from Geth-Dapp-loading-proposal.md rename to pages/eip/Geth-Dapp-loading-proposal.md diff --git a/JSON-RPC-Error-Codes-Improvement-Proposal.md b/pages/eip/JSON-RPC-Error-Codes-Improvement-Proposal.md similarity index 100% rename from JSON-RPC-Error-Codes-Improvement-Proposal.md rename to pages/eip/JSON-RPC-Error-Codes-Improvement-Proposal.md diff --git a/Mix-improvement-proposal.md b/pages/eip/Mix-improvement-proposal.md similarity index 100% rename from Mix-improvement-proposal.md rename to pages/eip/Mix-improvement-proposal.md diff --git a/Proposal:-BlockHashesFromNumbers.md b/pages/eip/Proposal:-BlockHashesFromNumbers.md similarity index 100% rename from Proposal:-BlockHashesFromNumbers.md rename to pages/eip/Proposal:-BlockHashesFromNumbers.md diff --git a/Proposal:-Extend-GetBlockHashes-with-target-hash.md b/pages/eip/Proposal:-Extend-GetBlockHashes-with-target-hash.md similarity index 100% rename from Proposal:-Extend-GetBlockHashes-with-target-hash.md rename to pages/eip/Proposal:-Extend-GetBlockHashes-with-target-hash.md diff --git a/Proposal:-NewBlockHashes.md b/pages/eip/Proposal:-NewBlockHashes.md similarity index 100% rename from Proposal:-NewBlockHashes.md rename to pages/eip/Proposal:-NewBlockHashes.md diff --git a/Proposal:-Reversion-Notification.md b/pages/eip/Proposal:-Reversion-Notification.md similarity index 100% rename from Proposal:-Reversion-Notification.md rename to pages/eip/Proposal:-Reversion-Notification.md diff --git a/Proposal:-Transaction-Proxy-Hooks.md b/pages/eip/Proposal:-Transaction-Proxy-Hooks.md similarity index 100% rename from Proposal:-Transaction-Proxy-Hooks.md rename to pages/eip/Proposal:-Transaction-Proxy-Hooks.md diff --git a/newBlockFilter-Improvement-Proposal.md b/pages/eip/newBlockFilter-Improvement-Proposal.md similarity index 100% rename from newBlockFilter-Improvement-Proposal.md rename to pages/eip/newBlockFilter-Improvement-Proposal.md diff --git a/sendTransaction-return-value-proposal.md b/pages/eip/sendTransaction-return-value-proposal.md similarity index 100% rename from sendTransaction-return-value-proposal.md rename to pages/eip/sendTransaction-return-value-proposal.md diff --git a/Dagger-Hashimoto.md b/pages/ethash-dagger-hashimoto/Dagger-Hashimoto.md similarity index 98% rename from Dagger-Hashimoto.md rename to pages/ethash-dagger-hashimoto/Dagger-Hashimoto.md index 12a26bac0..680e23845 100644 --- a/Dagger-Hashimoto.md +++ b/pages/ethash-dagger-hashimoto/Dagger-Hashimoto.md @@ -12,7 +12,7 @@ Dagger Hashimoto is a proposed spec for the mining algorithm for Ethereum 1.0. D With an additional modification, we also specify how to fulfill a third goal if desired, but at the cost of additional complexity: -**Full chain storage**: mining should require storage of the complete blockchain state (due to the irregular structure of the Ethereum state trie, we anticipate that some pruning will be possible, particularly of some often-used contracts, but we want to minimize this). +3. **Full chain storage**: mining should require storage of the complete blockchain state (due to the irregular structure of the Ethereum state trie, we anticipate that some pruning will be possible, particularly of some often-used contracts, but we want to minimize this). Dagger Hashimoto builds on two key pieces of previous work: @@ -81,7 +81,7 @@ params = { "diff": 2**14, # Difficulty (adjusted during block evaluation) "epochtime": 100000, # Length of an epoch in blocks (how often the dataset is updated) "k": 1, # Number of parents of a node - "w": w, # Used for modular exponentiation hashing + "w": w, # Used for modular exponentiation hashing "accesses": 200, # Number of dataset accesses during hashimoto "P": SAFE_PRIME_512 # Safe Prime for hashing and random number generation } @@ -148,7 +148,7 @@ The algorithm used to generate the actual set of DAGs used to compute the work f def get_prevhash(n): from pyethereum.blocks import GENESIS_PREVHASH from pyethreum import chain_manager - if num <= 0: + if n <= 0: return hash_to_int(GENESIS_PREVHASH) else: prevhash = chain_manager.index.get_block_by_number(n - 1) @@ -335,4 +335,4 @@ Special thanks to feedback from: * Tim Hughes * Matthew Wampler-Doty -* Thaddeus Dryja \ No newline at end of file +* Thaddeus Dryja diff --git a/Dagger.md b/pages/ethash-dagger-hashimoto/Dagger.md similarity index 100% rename from Dagger.md rename to pages/ethash-dagger-hashimoto/Dagger.md diff --git a/Ethash-C-API.md b/pages/ethash-dagger-hashimoto/Ethash-C-API.md similarity index 100% rename from Ethash-C-API.md rename to pages/ethash-dagger-hashimoto/Ethash-C-API.md diff --git a/Ethash-DAG-Disk-Storage-Format.md b/pages/ethash-dagger-hashimoto/Ethash-DAG-Disk-Storage-Format.md similarity index 100% rename from Ethash-DAG-Disk-Storage-Format.md rename to pages/ethash-dagger-hashimoto/Ethash-DAG-Disk-Storage-Format.md diff --git a/Ethash-Design-Rationale.md b/pages/ethash-dagger-hashimoto/Ethash-Design-Rationale.md similarity index 100% rename from Ethash-Design-Rationale.md rename to pages/ethash-dagger-hashimoto/Ethash-Design-Rationale.md diff --git a/Ethash.md b/pages/ethash-dagger-hashimoto/Ethash.md similarity index 100% rename from Ethash.md rename to pages/ethash-dagger-hashimoto/Ethash.md diff --git a/Ethash_revision_11.md b/pages/ethash-dagger-hashimoto/Ethash_revision_11.md similarity index 100% rename from Ethash_revision_11.md rename to pages/ethash-dagger-hashimoto/Ethash_revision_11.md diff --git a/Bad-Block-Reporting.md b/pages/ethereum-and-blockchain-technologies-and-research/Bad-Block-Reporting.md similarity index 100% rename from Bad-Block-Reporting.md rename to pages/ethereum-and-blockchain-technologies-and-research/Bad-Block-Reporting.md diff --git a/Bad-Chain-Canary.md b/pages/ethereum-and-blockchain-technologies-and-research/Bad-Chain-Canary.md similarity index 100% rename from Bad-Chain-Canary.md rename to pages/ethereum-and-blockchain-technologies-and-research/Bad-Chain-Canary.md diff --git a/Block-Protocol-2.0.md b/pages/ethereum-and-blockchain-technologies-and-research/Block-Protocol-2.0.md similarity index 99% rename from Block-Protocol-2.0.md rename to pages/ethereum-and-blockchain-technologies-and-research/Block-Protocol-2.0.md index 481b29757..f60f0fb7d 100644 --- a/Block-Protocol-2.0.md +++ b/pages/ethereum-and-blockchain-technologies-and-research/Block-Protocol-2.0.md @@ -248,8 +248,8 @@ The protocol altogether can be shown to be incentive-compatible as follows: 2. The miner of a block, and all uncles inside the block, at the very least have the incentive to respond to challenges. 3. Light nodes have the incentive to respect the block validity rules because everyone else does, an argument advanced in http://themonetaryfuture.blogspot.ca/2011/07/bitcoin-decentralization-and-nash.html. Without the challenge-response protocol, this argument does not apply because the cost of determining whether or not a block is valid is prohibitively high; with the protocol, this reasoning no longer applies. 4. Substantial stakeholders have the incentive to promote the perceived integrity of the system to maximize the value of their currency units, and thus may want to help actively submit both challenges and responses where possible. -5. Statistically speaking, far more than 0.01% of agents inside of real-world economic agents, whether or not weighted by economic power, tend to motivated by altruistic/ideological considerations. The market share of charities around the world is sufficient evidence of this. +5. Statistically speaking, far more than 0.01% of agents inside of real-world economic agents, whether or not weighted by economic power, tend to be motivated by altruistic/ideological considerations. The market share of charities around the world is sufficient evidence of this. ### Comparison with Bitcoin -In Bitcoin, one can create a challenge-response protocol to achieve similar functionality along very similar principles, but there is one key way in which such a protocol in Bitcoin would be inadequate: miner fees. Because Bitcoin does not include a Merkle-tree mechanism for adding up transaction fees, the only way to prove that a block has a certain quantity of transaction fees is to process every transaction. Furthermore, in Bitcoin transaction fees all go to the miner. Thus, in Bitcoin a light node has no way of knowing if a given block is valid or if it gives its creator excessive fees, and can only rely on the computational majority as a source of information for this. In Ethereum, all changes to the state are incorporated into the stacktrace, so this weakness does not exist and, given the weak security assumption that at least one full node with at least 0.01% mining power or stake is honest, have 100% of the security properties that full nodes have. \ No newline at end of file +In Bitcoin, one can create a challenge-response protocol to achieve similar functionality along very similar principles, but there is one key way in which such a protocol in Bitcoin would be inadequate: miner fees. Because Bitcoin does not include a Merkle-tree mechanism for adding up transaction fees, the only way to prove that a block has a certain quantity of transaction fees is to process every transaction. Furthermore, in Bitcoin transaction fees all go to the miner. Thus, in Bitcoin a light node has no way of knowing if a given block is valid or if it gives its creator excessive fees, and can only rely on the computational majority as a source of information for this. In Ethereum, all changes to the state are incorporated into the stacktrace, so this weakness does not exist and, given the weak security assumption that at least one full node with at least 0.01% mining power or stake is honest, have 100% of the security properties that full nodes have. diff --git a/Blockchain-import-and-export-instructions.md b/pages/ethereum-and-blockchain-technologies-and-research/Blockchain-import-and-export-instructions.md similarity index 100% rename from Blockchain-import-and-export-instructions.md rename to pages/ethereum-and-blockchain-technologies-and-research/Blockchain-import-and-export-instructions.md diff --git a/Distributed-Preimage-Archive.md b/pages/ethereum-and-blockchain-technologies-and-research/Distributed-Preimage-Archive.md similarity index 100% rename from Distributed-Preimage-Archive.md rename to pages/ethereum-and-blockchain-technologies-and-research/Distributed-Preimage-Archive.md diff --git a/Subtleties.md b/pages/ethereum-and-blockchain-technologies-and-research/EVM-Subtleties.md similarity index 100% rename from Subtleties.md rename to pages/ethereum-and-blockchain-technologies-and-research/EVM-Subtleties.md diff --git a/Ethereum-Natural-Specification-Format.md b/pages/ethereum-and-blockchain-technologies-and-research/Ethereum-Natural-Specification-Format.md similarity index 99% rename from Ethereum-Natural-Specification-Format.md rename to pages/ethereum-and-blockchain-technologies-and-research/Ethereum-Natural-Specification-Format.md index 22584ee5c..6409728eb 100644 --- a/Ethereum-Natural-Specification-Format.md +++ b/pages/ethereum-and-blockchain-technologies-and-research/Ethereum-Natural-Specification-Format.md @@ -35,7 +35,7 @@ There are a few things to note about the above example. + @param: Documents a parameter just like in doxygen. Has to be followed by the parameter name. + @return: Documents the return type of a contract's function. -- If any of the above are missing they are simply considered as blank and it's not illegal to omit any of them +- If any of the above are missing they are simply considered as blank, and it's not illegal to omit any of them. - `(valueInmGAV / 1000).fixed(0,3)` A dynamic expression. This should be a valid Javascript/Paperscript expression, which when evaluated in an EVM Javascript environment initialised with various system values (such as parameters). diff --git a/Ethereum-Wire-Protocol.md b/pages/ethereum-and-blockchain-technologies-and-research/Ethereum-Wire-Protocol.md similarity index 97% rename from Ethereum-Wire-Protocol.md rename to pages/ethereum-and-blockchain-technologies-and-research/Ethereum-Wire-Protocol.md index 1d30dea88..51f8df916 100644 --- a/Ethereum-Wire-Protocol.md +++ b/pages/ethereum-and-blockchain-technologies-and-research/Ethereum-Wire-Protocol.md @@ -15,7 +15,7 @@ Peer-to-peer communications between nodes running Ethereum clients run using the ### Ethereum Sub-protocol **Status** -[`+0x00`: `P`, `protocolVersion`: `P`, `networkId`: `P`, `td`: `P`, `bestHash`: `B_32`, `genesisHash`: `B_32`] Inform a peer of it's current **ethereum** state. This message should be sent _after_ the initial handshake and _prior_ to any **ethereum** related messages. +[`+0x00`: `P`, `protocolVersion`: `P`, `networkId`: `P`, `td`: `P`, `bestHash`: `B_32`, `genesisHash`: `B_32`] Inform a peer of its current **ethereum** state. This message should be sent _after_ the initial handshake and _prior_ to any **ethereum** related messages. * `protocolVersion` is one of: * `0x00` for PoC-1; * `0x01` for PoC-2; diff --git a/Light-client-protocol.md b/pages/ethereum-and-blockchain-technologies-and-research/Light-client-protocol.md similarity index 100% rename from Light-client-protocol.md rename to pages/ethereum-and-blockchain-technologies-and-research/Light-client-protocol.md diff --git a/Morden.md b/pages/ethereum-and-blockchain-technologies-and-research/Morden.md similarity index 100% rename from Morden.md rename to pages/ethereum-and-blockchain-technologies-and-research/Morden.md diff --git a/pages/patricia-tree/[english]-patricia-tree.md b/pages/ethereum-and-blockchain-technologies-and-research/[english]-patricia-tree.md similarity index 100% rename from pages/patricia-tree/[english]-patricia-tree.md rename to pages/ethereum-and-blockchain-technologies-and-research/[english]-patricia-tree.md diff --git a/pages/rlp/[english]-rlp.md b/pages/ethereum-and-blockchain-technologies-and-research/[english]-rlp.md similarity index 100% rename from pages/rlp/[english]-rlp.md rename to pages/ethereum-and-blockchain-technologies-and-research/[english]-rlp.md diff --git a/CLL.md b/pages/ethereum-and-blockchain-technologies-and-research/research/CLL.md similarity index 100% rename from CLL.md rename to pages/ethereum-and-blockchain-technologies-and-research/research/CLL.md diff --git a/Chain-Fibers-Redux.md b/pages/ethereum-and-blockchain-technologies-and-research/research/Chain-Fibers-Redux.md similarity index 100% rename from Chain-Fibers-Redux.md rename to pages/ethereum-and-blockchain-technologies-and-research/research/Chain-Fibers-Redux.md diff --git a/Generalized_Merkle_DHT.md b/pages/ethereum-and-blockchain-technologies-and-research/research/Generalized_Merkle_DHT.md similarity index 100% rename from Generalized_Merkle_DHT.md rename to pages/ethereum-and-blockchain-technologies-and-research/research/Generalized_Merkle_DHT.md diff --git a/HPOC_2015.md b/pages/ethereum-and-blockchain-technologies-and-research/research/HPOC_2015.md similarity index 100% rename from HPOC_2015.md rename to pages/ethereum-and-blockchain-technologies-and-research/research/HPOC_2015.md diff --git a/Parallel-Block-Downloads.md b/pages/ethereum-and-blockchain-technologies-and-research/research/Parallel-Block-Downloads.md similarity index 100% rename from Parallel-Block-Downloads.md rename to pages/ethereum-and-blockchain-technologies-and-research/research/Parallel-Block-Downloads.md diff --git a/Problems.md b/pages/ethereum-and-blockchain-technologies-and-research/research/Problems.md similarity index 100% rename from Problems.md rename to pages/ethereum-and-blockchain-technologies-and-research/research/Problems.md diff --git a/Security-Categorization.md b/pages/ethereum-and-blockchain-technologies-and-research/research/Security-Categorization.md similarity index 100% rename from Security-Categorization.md rename to pages/ethereum-and-blockchain-technologies-and-research/research/Security-Categorization.md diff --git a/Security-Issue-Process.md b/pages/ethereum-and-blockchain-technologies-and-research/research/Security-Issue-Process.md similarity index 100% rename from Security-Issue-Process.md rename to pages/ethereum-and-blockchain-technologies-and-research/research/Security-Issue-Process.md diff --git a/Serenity_Wishlist.md b/pages/ethereum-and-blockchain-technologies-and-research/research/Serenity_Wishlist.md similarity index 100% rename from Serenity_Wishlist.md rename to pages/ethereum-and-blockchain-technologies-and-research/research/Serenity_Wishlist.md diff --git a/pages/ethereum-toc/[spanish]-ethereum-toc.md b/pages/ethereum-toc/[spanish]-ethereum-toc.md deleted file mode 100644 index 4019b677b..000000000 --- a/pages/ethereum-toc/[spanish]-ethereum-toc.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -name: Ethereum TOC -category: ---- - -### Bienvenidos a Ethereum, la plataforma para la siguiente generación de contratos inteligentes y aplicaciones descentralizadas. - -[Whitepaper de Ethereum](https://google.com) - -[RLP](https://google.com), Prefijo Linear Recursivo (Recursive Linear Prefix), usado para codificación de datos a través de Ethereum. - -[Patricia Tree](https://google.com) especificaciones del árbol Merkle Patricia (“Merkle Patria Tree”, también conocido como Trie), la estructura usada para almacenar y procesar a través de funciones Hash el estado de la cadena de bloques en Ethereum. - -[Protocolo de conexión](https://google.com), especificaciones. - -[CLL](https://google.com), Lenguage de alto nivel similar a C usado para crear contratos, especificaciones. - -[Dagger](https://google.com), Prueba de trabajo (Proof-of-work) de Ethereum. - -[Protocolo de Bloques 2.0](https://google.com) - -[Capas](https://google.com) - -[Cámara de compensación](https://google.com) diff --git a/Adaptive-Message-IDs.md b/pages/infrastructure-networking/Adaptive-Message-IDs.md similarity index 100% rename from Adaptive-Message-IDs.md rename to pages/infrastructure-networking/Adaptive-Message-IDs.md diff --git a/Adaptive-Peer-Time.md b/pages/infrastructure-networking/Adaptive-Peer-Time.md similarity index 83% rename from Adaptive-Peer-Time.md rename to pages/infrastructure-networking/Adaptive-Peer-Time.md index b4fffa08b..0405c26da 100644 --- a/Adaptive-Peer-Time.md +++ b/pages/infrastructure-networking/Adaptive-Peer-Time.md @@ -13,7 +13,7 @@ A system with multiple peers should be robust to a few peers having substantiall Each peer does a ping-sequence, each message timestamped with the hardware clock (H) directly after handshake to determine both the network traversal distance ("ping time") and an estimate of the peer's hardware clock (Hp). -The clock-offset (D) of the peer then becomes it's hardware clock (H) corrected to become the median of the peer hardware clocks (median({H1, H2, ...}) = M). +The clock-offset (D) of the peer then becomes its hardware clock (H) corrected to become the median of the peer hardware clocks (median({H1, H2, ...}) = M). The clock offset (D) is dynamically evaluated as the peer set changes. diff --git a/Brain-Wallet.md b/pages/infrastructure-networking/Brain-Wallet.md similarity index 100% rename from Brain-Wallet.md rename to pages/infrastructure-networking/Brain-Wallet.md diff --git a/Clearinghouse.md b/pages/infrastructure-networking/Clearinghouse.md similarity index 100% rename from Clearinghouse.md rename to pages/infrastructure-networking/Clearinghouse.md diff --git a/Default-Extra-Data-Standard.md b/pages/infrastructure-networking/Default-Extra-Data-Standard.md similarity index 100% rename from Default-Extra-Data-Standard.md rename to pages/infrastructure-networking/Default-Extra-Data-Standard.md diff --git a/Deterministic_Wallet_Spec.md b/pages/infrastructure-networking/Deterministic_Wallet_Spec.md similarity index 100% rename from Deterministic_Wallet_Spec.md rename to pages/infrastructure-networking/Deterministic_Wallet_Spec.md diff --git a/EVM-JIT-Binary-Interface.md b/pages/infrastructure-networking/EVM-JIT-Binary-Interface.md similarity index 100% rename from EVM-JIT-Binary-Interface.md rename to pages/infrastructure-networking/EVM-JIT-Binary-Interface.md diff --git "a/e\317\200-Programme.md" "b/pages/infrastructure-networking/Ethereum-Raspberry-Pi-e\317\200-Programme.md" similarity index 100% rename from "e\317\200-Programme.md" rename to "pages/infrastructure-networking/Ethereum-Raspberry-Pi-e\317\200-Programme.md" diff --git a/Exchange-Integration.md b/pages/infrastructure-networking/Exchange-Integration.md similarity index 100% rename from Exchange-Integration.md rename to pages/infrastructure-networking/Exchange-Integration.md diff --git a/ICAP:-Inter-exchange-Client-Address-Protocol.md b/pages/infrastructure-networking/ICAP:-Inter-exchange-Client-Address-Protocol.md similarity index 100% rename from ICAP:-Inter-exchange-Client-Address-Protocol.md rename to pages/infrastructure-networking/ICAP:-Inter-exchange-Client-Address-Protocol.md diff --git a/IPv6.md b/pages/infrastructure-networking/IPv6.md similarity index 100% rename from IPv6.md rename to pages/infrastructure-networking/IPv6.md diff --git a/Kademlia-Peer-Selection.md b/pages/infrastructure-networking/Kademlia-Peer-Selection.md similarity index 100% rename from Kademlia-Peer-Selection.md rename to pages/infrastructure-networking/Kademlia-Peer-Selection.md diff --git a/Layers.md b/pages/infrastructure-networking/Layers.md similarity index 100% rename from Layers.md rename to pages/infrastructure-networking/Layers.md diff --git a/Mining.md b/pages/infrastructure-networking/Mining.md similarity index 88% rename from Mining.md rename to pages/infrastructure-networking/Mining.md index f55ae1c0e..2fce6bcb0 100644 --- a/Mining.md +++ b/pages/infrastructure-networking/Mining.md @@ -21,7 +21,7 @@ The difficulty dynamically adjusts so that on average one block is produced by t Any node participating in the network can be a miner and their expected revenue from mining will be directly proportional to their (relative) mining power or **hashrate**, ie., number of nonces tried per second normalised by the total hashrate of the network. -Ethash PoW is memory hard, making it basically ASIC resistant. This basically means that calculating the PoW requires choosing subsets of a fixed resource dependent on the nonce and block header. This resource (a few gigabyte size data) is called a **DAG**. The [DAG](https://github.com/ethereum/wiki/wiki/Ethash-DAG) is totally different every 30000 blocks (a 100 hour window, called an **epoch**) and takes a while to generate. Since the DAG only depends on block height, it can be pregenerated but if its not, the client need to wait the end of this process to produce a block. Until clients actually precache dags ahead of time the network may experience a massive block delay on each epoch transition. Note that the DAG does not need to be generated for verifying the PoW essentially allowing for verification with both low CPU and small memory. +Ethash PoW is memory hard, making it ASIC resistant. This means that calculating the PoW requires choosing subsets of a fixed resource dependent on the nonce and block header. This resource (a few gigabyte size data) is called a **DAG**. The [DAG](https://github.com/ethereum/wiki/wiki/Ethash-DAG) is totally different every 30000 blocks (a 100 hour window, called an **epoch**) and takes a while to generate. Since the DAG only depends on block height, it can be pregenerated but if its not, the client needs to wait till the end of this process to produce a block. Until clients actually precache dags ahead of time the network may experience a massive block delay on each epoch transition. Note that the DAG does not need to be generated for verifying the PoW essentially allowing for verification with both low CPU and small memory. As a special case, when you start up your node from scratch, mining will only start once the DAG is built for the current epoch. diff --git a/NatSpec-Determination.md b/pages/infrastructure-networking/NatSpec-Determination.md similarity index 100% rename from NatSpec-Determination.md rename to pages/infrastructure-networking/NatSpec-Determination.md diff --git a/Natspec-Example.md b/pages/infrastructure-networking/Natspec-Example.md similarity index 100% rename from Natspec-Example.md rename to pages/infrastructure-networking/Natspec-Example.md diff --git a/Network-Status.md b/pages/infrastructure-networking/Network-Status.md similarity index 100% rename from Network-Status.md rename to pages/infrastructure-networking/Network-Status.md diff --git a/NewBlock-Message.md b/pages/infrastructure-networking/NewBlock-Message.md similarity index 100% rename from NewBlock-Message.md rename to pages/infrastructure-networking/NewBlock-Message.md diff --git a/Raspberry-Pi-instructions.md b/pages/infrastructure-networking/Raspberry-Pi-instructions.md similarity index 100% rename from Raspberry-Pi-instructions.md rename to pages/infrastructure-networking/Raspberry-Pi-instructions.md diff --git a/Registrar-ABI.md b/pages/infrastructure-networking/Registrar-ABI.md similarity index 100% rename from Registrar-ABI.md rename to pages/infrastructure-networking/Registrar-ABI.md diff --git a/URL-Hint-Protocol.md b/pages/infrastructure-networking/URL-Hint-Protocol.md similarity index 100% rename from URL-Hint-Protocol.md rename to pages/infrastructure-networking/URL-Hint-Protocol.md diff --git a/Decentralized-apps-(dapps).md b/pages/introduction/Decentralized-apps-(dapps).md similarity index 100% rename from Decentralized-apps-(dapps).md rename to pages/introduction/Decentralized-apps-(dapps).md diff --git a/Ethereum-introduction.md b/pages/introduction/Ethereum-introduction.md similarity index 100% rename from Ethereum-introduction.md rename to pages/introduction/Ethereum-introduction.md diff --git a/FAQ.md b/pages/introduction/FAQ.md similarity index 100% rename from FAQ.md rename to pages/introduction/FAQ.md diff --git a/Gitter-Channels.md b/pages/introduction/Gitter-Channels.md similarity index 100% rename from Gitter-Channels.md rename to pages/introduction/Gitter-Channels.md diff --git a/Glossary.md b/pages/introduction/Glossary.md similarity index 99% rename from Glossary.md rename to pages/introduction/Glossary.md index dbc6194c1..06dd59b44 100644 --- a/Glossary.md +++ b/pages/introduction/Glossary.md @@ -46,7 +46,7 @@ See also: http://ethereum.org/ethereum.html * **Externally owned account**: an account controlled by a private key. Externally owned accounts cannot contain EVM code. * **Contract**: an account which contains, and is controlled by, EVM code. Contracts cannot be controlled by private keys directly; unless built into the EVM code, a contract has no owner once released. * **Ether**: the primary internal cryptographic token of the Ethereum network. Ether is used to pay transaction and computation fees for Ethereum transactions. -* **Gas**: a measurement roughly equivalent to computational steps. Every transaction is required to include a gas limit and a fee that it is willing to pay per gas; miners have the choice of including the transaction and collecting the fee or not. If the total number of gas used by the computation spawned by the transaction, including the original message and any sub-messages that may be triggered, is less than or equal to the gas limit, then the transaction processes. If the total gas exceeds the gas limit, then all changes are reverted, except that the transaction is still valid and the fee can still be collected by the miner. Every operation has a gas expenditure; for most operations it is 1, although some expensive operations fave expenditures up to 100 and a transaction itself has an expenditure of 500. +* **Gas**: a measurement roughly equivalent to computational steps. Every transaction is required to include a gas limit and a fee that it is willing to pay per gas; miners have the choice of including the transaction and collecting the fee or not. If the total number of gas used by the computation spawned by the transaction, including the original message and any sub-messages that may be triggered, is less than or equal to the gas limit, then the transaction processes. If the total gas exceeds the gas limit, then all changes are reverted, except that the transaction is still valid and the fee can still be collected by the miner. Every operation has a gas expenditure; for most operations it is 1, although some expensive operations have expenditures up to 100 and a transaction itself has an expenditure of 500. ### Non-blockchain @@ -79,4 +79,4 @@ See also: http://ethereum.org/ethereum.html * **Web of trust**: the idea that if A highly rates B, and B highly rates C, then A is likely to trust C. Complicated and powerful mechanisms for determining the reliability of specific individuals in specific concepts can theoretically be gathered from this principle. * **Escrow**: if two low-reputation entities are engaged in commerce, the payer may wish to leave the funds with a high-reputation third party and instruct that party to send the funds to the payee only when the product is delivered. This reduces the risk of the payer or payee committing fraud. * **Deposit**: digital property placed into a contract involving another party such that if certain conditions are not satisfied that property is automatically forfeited to the counterparty -* **Hostage**: digital property placed into a contract such that if certain conditions are not satisfied that property is automatically either destroyed or donated to charity or basic income funds, perhaps with widely distributed benefit but necessarily with no significant benefit to any specific individual. \ No newline at end of file +* **Hostage**: digital property placed into a contract such that if certain conditions are not satisfied that property is automatically either destroyed or donated to charity or basic income funds, perhaps with widely distributed benefit but necessarily with no significant benefit to any specific individual. diff --git a/Home.md b/pages/introduction/Home.md similarity index 100% rename from Home.md rename to pages/introduction/Home.md diff --git a/What-is-Ethereum.md b/pages/introduction/What-is-Ethereum.md similarity index 98% rename from What-is-Ethereum.md rename to pages/introduction/What-is-Ethereum.md index c427d5e04..0bb7ecfdd 100644 --- a/What-is-Ethereum.md +++ b/pages/introduction/What-is-Ethereum.md @@ -3,12 +3,12 @@ name: What is Ethereum? category: --- -#What is Ethereum? +# What is Ethereum? Ethereum, like any advanced system, will mean different things to different people. As you read this section, some bits may not resonate with you or even make sense. That is fine, just skip to the next paragraph and hopefully that one will be more enlightening. If you reach the end of this section and still feel confused, then jump on a forum and start asking questions. -##A World Computer +## A World Computer >"It is very possible that ... one machine would suffice to solve all the problems ... of the whole [world]" - Sir Charles Darwin, 1946* @@ -17,7 +17,7 @@ In a technical sense, Ethereum is a "world computer". Harking back to the days o You may ask, "why would anyone use such a system?" and again there are many reasons. The main reason is because it makes what you want to do cheaper and easier. This statement needs to be broken down somewhat, which is what the following paragraphs explore. -##An Internet Service Platform +## An Internet Service Platform >"Technology gives us the facilities that lessen the barriers of time and distance - the telegraph and cable, the telephone, radio, and the rest." - Emily Greene Balch @@ -35,7 +35,7 @@ Over the last twenty years in particular, we have seen an acceleration in the de With the coming of the Mix IDE and the Mist browser, the functionality of Ethereum as a deployment platform for internet services will become more clear. The take-home message from this section, however, is that Ethereum is poised to disrupt industries as diverse as finance and supply chains. -##Opt-in Social Contracts +## Opt-in Social Contracts > "This is an era of organization" - Theodore Roosevelt, 1912** @@ -44,7 +44,7 @@ At a more abstract level, it is a facility for enabling smart organization, in t Crowdfunding is a key example in the advancement organizational tools. It provides a couple of really important functions: a way for individuals to work together for a particular cause (in this case giving a wedge of cash to a person or group) and a mechanism for individuals to interact meaningfully with potentially large companies (such as a games studio). The first follows from the previous paragraph, but the second point is impressive also, because in general individuals can only communicate with large organizations on the organization's terms, which often default to "ignore"; in the same way you ignore the bacteria on your skin. As it stands, you might be disgruntled by the crowdfunding recipient taking your money and spending it in a wholey inappropriate and therefore inefficient manner. However, it's hard to get the operating company to act on your behalf against the recipient. After all, the crowdfunding service provider is likely to be a large company and there isn't a universal mechanism with which you can meaningfully communicate with it if it does not want you to. Ethereum can help by allowing you to define post-funding milestones or conditions to stage the payment of the total amount raised, and then enforce those conditions for you. As times goes on, we will get more creative in the ways in which Ethereum can interact with the real world and the ability of Ethereum to check that milestones have been completed will extend beyond the obvious such as "30% of the crowd that funded the project (by value) have voted that the milestone has been passed". -##Part of the Decentralization Revolution +## Part of the Decentralization Revolution >"No matter who you vote for, the government always gets in" - The Bonzo Dog Doo-Dah Band, 1992 @@ -53,12 +53,12 @@ Philosophically, it is the next step in re-decentralizing the internet. A decent Ethereum allows people to safely interact trustlessly by entering into neutrally enforceable agreements in a completely peer-to-peer fashion. Now, it must be remembered that Ethereum can only enforce within its own digital limits; Ethereum does not remove the need for an external authority for adjudication over disputes outside its realm---"the other party punched me in the face after putting in the Ethereum contract that he wouldn't" is non-sense, but rules exist elsewhere to cover this---but what Ethereum does do is allow us to push the boundary on what the digital realm can cover. -##Conclusion +## Conclusion Gavin Wood has distilled the description of Ethereum to being a collection of non-localized singleton programmable data structures. What this means will depend on where you are coming from, but wherever you are, it's probably going to be better with Ethereum. -###Notes +### Notes *Copeland, Jack (2006). Colossus: The Secrets of Bletchley Park's Codebreaking Computers. Oxford University Press. p.109 Note that T.J.Watson, the former head of IBM, almost certainly never said, "I think there is a world market for maybe five computers", although for a time (late 1940s, early 1950s) it was indeed the case that there was, in the United States, a market for about five computers. diff --git a/[German]-Clearinghaus.md b/pages/other-languages/[German]-Clearinghaus.md similarity index 100% rename from [German]-Clearinghaus.md rename to pages/other-languages/[German]-Clearinghaus.md diff --git a/[Italian]-Impostare-il-proprio-ambiente-di-sviluppo-Ethereum.md b/pages/other-languages/[Italian]-Impostare-il-proprio-ambiente-di-sviluppo-Ethereum.md similarity index 100% rename from [Italian]-Impostare-il-proprio-ambiente-di-sviluppo-Ethereum.md rename to pages/other-languages/[Italian]-Impostare-il-proprio-ambiente-di-sviluppo-Ethereum.md diff --git a/[Italian]-Introduzione-allo-sviluppo-su-Ethereum.md b/pages/other-languages/[Italian]-Introduzione-allo-sviluppo-su-Ethereum.md similarity index 100% rename from [Italian]-Introduzione-allo-sviluppo-su-Ethereum.md rename to pages/other-languages/[Italian]-Introduzione-allo-sviluppo-su-Ethereum.md diff --git a/[Italian]-Libro-Bianco.md b/pages/other-languages/[Italian]-Libro-Bianco.md similarity index 100% rename from [Italian]-Libro-Bianco.md rename to pages/other-languages/[Italian]-Libro-Bianco.md diff --git a/[Japanese]-Cryptocurrency-Current-Problems.md b/pages/other-languages/[Japanese]-Cryptocurrency-Current-Problems.md similarity index 100% rename from [Japanese]-Cryptocurrency-Current-Problems.md rename to pages/other-languages/[Japanese]-Cryptocurrency-Current-Problems.md diff --git a/[Japanese]--Ethereum-Development-Tutorial.md b/pages/other-languages/[Japanese]-Ethereum-Development-Tutorial.md similarity index 64% rename from [Japanese]--Ethereum-Development-Tutorial.md rename to pages/other-languages/[Japanese]-Ethereum-Development-Tutorial.md index 4058307fa..3d0c3f5c7 100644 --- a/[Japanese]--Ethereum-Development-Tutorial.md +++ b/pages/other-languages/[Japanese]-Ethereum-Development-Tutorial.md @@ -1,15 +1,17 @@ --- name: Ethereum Development Tutorial -category: +category: --- - この項の目的は、契約の生成とDアプリ開発の視点からイーサリアムを理解するのに必要な基礎知識の紹介である。イーサリアムの導入としては、ふつう、はじめに白書に目を通し、さらに技術スペックを網羅するためにYellow Paperを読むが、この項を読む前に必ずしも読んで置く必要はない。つまりこのページが、アプリ開発者にとって、それらにとってかわる導入となりうることを意味する。 + このページの目的はコントラクトや分散アプリケーションを作成するために、開発の観点から理解する必要があるEthereumの基礎を紹介することです。Ethereumの全般的なイントロダクションについてはホワイトペーパー、完全な技術仕様についてはイエローペーパーが参考になりますが、このページを読むのに必須ではありません。アプリケーション開発者にとって、このページがそれらに代わるEthereumへの導入となり得ます。 ### Introduction - イーサリアム(Ethereum)は blockchain を利用した分散型アプリケーション(D-App)を簡単にプログラム可能にすることを目的とした platform (仮想マシン)である。D-Appとは、ある特定の目的のために事えるアプリであるが、アプリ自身は、その重要な性質として、今あるどのパーティにも依存しない、全く新しいものである。このD-Appというものは、特定のプラットフォームを提供し売り込むための開発環境というよりかはむしろ、(売り手と買い手などといった)違った立場にいる人間や機関が、中央集約型の媒介を無しにして取引、契約等(相互利用)をするための道具である。フィルタリングや第三者認証、紛争解決、個人認証業務のような典型的な「中央集約型の媒介」の業務でさえ、分散型ネットワークで扱うことが可能であり、参加者全員にオープンとなっており、内部トークンシステムとして評判の高いシステムをツールとして採用し、利用者に高品質なサービスを提供する。初期のD-Appの例としては、ファイルシェアアプリとしてBitTorrentが、通貨アプリとしてビットコインが含まれる。イーサリアムは BittorentやBitcoinで使われたものや、P2Pネットワークやブロックチェイン技術を含む最初の進化版開発物(web3.0)といえよう。そして、開発者がこれらの技術を使いやすいように一般化したものだ。 + Ethereumは、ブロックチェーンを利用した分散型アプリケーション(DApps)を簡単にプログラムすることを目的としたプラットフォームです。DAppsとは、ユーザーに対し特定の目的のためを果たすアプリケーションですが、アプリケーション自体は既存の特定の管理者に依存しないという重要な特性を持っています。DAppsは、特定の管理者のサービスを提供するためのフロントエンドとして機能するのではなく、仲介業者なしで人や組織がやり取りするのためのツールです。 - イーサリアムのブロックチェインは(ビットコインに見られる単なる金銭記録データではなく)プログラミング言語が組み込まれたブロックチェインというふうに説明できる。あるいは、大衆の思惑による決定(コンセンサス)を基板とした地球規模の仮想マシンとも言える。Ethereum仮想マシン(EVM)を参照してえられる部分的なプロトコルは、内部状態と計算を実際に処理する。実用的な観点からして、EVMは膨大な量のアカウント(というオブジェクト)を内部に保持する分散型コンピュータと考えることができ、このコンピュータでは各々のオブジェクトがそれぞれ内部コードとストレージという名前の32バイトのkey/valueデータベースを保持し、オブジェクトは他のオブジェクトを意のままに呼び出すことができる。 + このDAppsというものは、特定のプラットフォームを提供し売り込むための開発環境というよりかはむしろ、(売り手と買い手などといった)違った立場にいる人間や機関が、中央集約型の媒介を無しにして取引、契約等(相互利用)をするための道具である。フィルタリングや第三者認証、紛争解決、個人認証業務のような典型的な「中央集約型の媒介」の業務でさえ、分散型ネットワークで扱うことが可能であり、参加者全員にオープンとなっており、内部トークンシステムとして評判の高いシステムをツールとして採用し、利用者に高品質なサービスを提供する。初期のDAppsの例としては、ファイルシェアアプリとしてBitTorrentが、通貨アプリとしてビットコインが含まれる。Ethereumは BittorentやBitcoinで使われたものや、P2Pネットワークやブロックチェーン技術を含む最初の進化版開発物(web3.0)といえよう。そして、開発者がこれらの技術を使いやすいように一般化したものだ。 + + Ethereumのブロックチェーンは(ビットコインに見られる単なる金銭記録データではなく)プログラミング言語が組み込まれたブロックチェーンというふうに説明できる。あるいは、大衆の思惑による決定(コンセンサス)を基板とした地球規模の仮想マシンとも言える。Ethereum仮想マシン(EVM)を参照してえられる部分的なプロトコルは、内部状態と計算を実際に処理する。実用的な観点からして、EVMは膨大な量のアカウント(というオブジェクト)を内部に保持する分散型コンピュータと考えることができ、このコンピュータでは各々のオブジェクトがそれぞれ内部コードとストレージという名前の32バイトのkey/valueデータベースを保持し、オブジェクトは他のオブジェクトを意のままに呼び出すことができる。  〜アカウントには2つのタイプがある〜  オブジェクトの外側の世界からEVMを使用してアクセスすることができるアカウント(オブジェクト)として「外部所有アカウント(EOA,EOアカウント)」という名の特別なタイプがある。あるEOアカウントから他のどんなアカウントに対する「メッセージ」も、そのEOアカウントの秘密鍵で署名されたトランザクションを送ることが引き金となり、送ることが可能だ。EOアカウントでないものは「 契約、contract 」と呼ばれ、「メッセージ」の受け取り、自動的に内部コードを実行し、(自身のもつ内部ストレージに読み書きする能力を持つ。)受け取った「メッセージ」のストレージを読み取り、そして他の契約アカウントにメッセージを送る。(自分自身にも送ることができる。) ひとつの捉え方として、contract とは、契約を遂行するためのプログラミングコードだ。 @@ -27,7 +29,7 @@ category: 4. ライブラリとして機能する。  他の契約によって呼び出される関数を格納しておく。 - contract は、互いに「 呼出 calling 」や「 送信 sending message 」などと呼ばれる動作を通じて作用しあう。一通の「メッセージ」は、1.ある量のether 2.どんなサイズのデータを格納したバイト型配列 3.送受信者双方のアドレス を保持する。契約アカウントが、返り値としてあるデータを返す「メッセージ」を受信し、その返り値をメッセージの送り手がすぐに使用できるようなときは、「送信」とは、まさに、プログラミングにおける関数の履行である。 + contract は、互いに「 呼出(calling)」や「 送信(sending message)」などと呼ばれる動作を通じて作用しあう。一通の「メッセージ」は、1.ある量のether 2.どんなサイズのデータを格納したバイト型配列 3.送受信者双方のアドレス を保持する。契約アカウントが、返り値としてあるデータを返す「メッセージ」を受信し、その返り値をメッセージの送り手がすぐに使用できるようなときは、「送信」とは、まさに、プログラミングにおける関数の履行である。  以上に示したように、契約アカウントは異なる働きをし、それら同士が互いに作用しあうことが期待できる。例をあげよう。次のような状況を考えてみよう。  アリスとボブが、「来年サンフランシスコの気温が35度を超えることはない」ということに100Gavcoin(開発者の名前が付けられた仮想通貨)の賭けをしたとしよう。しかし、アリスは危険回避思考の持ち主で、アリスの第一アカウントは、マルチシグをかけた「前進型契約」を保持している。ボブは量子暗号に猜疑的で(疑い深く)、伝統的な楕円曲線アルゴリズムに沿ったランポート署名を施したメッセージを転送する「前進型契約」を保持している(訳略)。この賭博を管理する契約アカウントはそれ自身サンフランシスコの気象データをあるコントラクトから呼び出してこないといけない。(以後、契約アカウントの呼び名として、プログラマであるわれわれがmethodのことをメソッドと呼ぶように、コントラクトと呼ぶことにする。コンストラクタ等と混同しないように別名がほしいところだが。)またGavCoinコントラクトともやりとりしなくてはならない。・・・ @@ -36,7 +38,7 @@ category: ![img](https://github.com/ethereumbuilders/GitBook/blob/master/en/vitalik-diagrams/contract_relationship.png)  スタック上に積み上がっていくメソッドの呼び出し(コールスタック)を頭に思い描くことができれば、 -ここでの説明は容易であろう。 +ここでの説明は容易であろう。 ボブが賭けを終了させたいと思った時、次のことが起こる: @@ -55,7 +57,7 @@ GavCoin はすべて Gavcion contract データベースの項目として "貯 ### State Machine - Ethereum仮想マシンの計算処理は、ビットコインスクリプトと伝統的アセンブラやリスプといったものの架け橋である、スタックベースのバイトコード言語を使用する。(Lispは再帰的コントラクト呼出の機能の役割を担う。)仮想マシン上のプログラムは以下のようなopcodesのシーケンスである。 + Ethereum仮想マシンの計算処理は、ビットコインスクリプトと伝統的アセンブラやLispといったものの架け橋である、スタックベースのバイトコード言語を使用する。(Lispは再帰的コントラクト呼出の機能の役割を担う。)仮想マシン上のプログラムは以下のようなopcodesのシーケンスである。 PUSH1 0 CALLDATALOAD SLOAD NOT PUSH1 9 JUMPI STOP PUSH1 32 CALLDATALOAD PUSH1 0 CALLDATALOAD SSTORE @@ -68,60 +70,45 @@ GavCoin はすべて Gavcion contract データベースの項目として "貯 PC: 0 STACK: [] MEM: [], STORAGE: {} -最初の命令は、PUSH1 で -スタックに値0をpushする。 PUSH1は1バイトの値を扱う。 -よって: +最初の命令は`PUSH1`で次の値である0をスタックにpushする。`PUSH1`は1バイトの値を扱う。よって以下のような状態に変わる: PC: 2 STACK: [0] MEM: [], STORAGE: {} -二つ目の命令は CALLDATALOAD で、 -スタックから取り出される値(ここでは0)をアドレスとしてメッセージデータを参照し、 -そこに格納されている値(ここでは54)をスタックに取り込む。 -よって: +2番目の命令である`CALLDATALOAD`では、スタックから値を一つ取り出し、そのアドレス先のデータの先頭32バイトのメッセージを取得し、その値をスタックに保存する(ここでは先頭の32ビットが54である)。よって以下のような状態に変わる: PC: 3 STACK: [54] MEM: [], STORAGE: {} -SLOAD; -スタックから一つ取り出し、その値を参照値としたストレージの値を、スタックへ入れる。 +次の命令の`SLOAD`はスタックから値を一つ取り出し、contractのstorageの参照先の値をスタックに保存する。今回初めてcontractは使用するため値が入っておらず、値は0が埋められる: PC: 4 STACK: [0] MEM: [], STORAGE: {} -NOT; -スタックから値を取り出し -0であれば、  1をスタックに入れる。 -0以外であれば、0をスタックに入れる。 +`NOT`スタックから値を取り出し、0であれば1を、それ以外は0をスタックに入れる: PC: 5 STACK: [1] MEM: [], STORAGE: {} -Next, we PUSH1 9. +次は`PUSH1`であるため、9をスタックに保存する: PC: 7 STACK: [1, 9] MEM: [], STORAGE: {} -JUMPI; -この命令はスタックから2つの値を取り出し、二つ目の値が0でななければ、一つ目の値によって指定された命令へジャンプする。ここでは0でないのでジャンプする。もしストレージ内の54番目の値が0でなかったならば、スタックの二つ目の値が0になっているだろう。よって、この場合ジャンプできずに動作がここで終了する。 - - PC: 9 STACK: [] MEM: [], STORAGE: {} +次の`JUMPI`命令では、スタックから2つの値を取り出し、二つ目の値が0でなければ、一つ目の値によって指定された命令へジャンプする。ここでは0でないのでジャンプする。もしストレージ内の54番目の値が0でなかったならば、スタックの二つ目の値が0になっているだろう。よって、この場合ジャンプできずに動作がここで終了する: -Here, we PUSH1 32. +次は`PUSH1`であるため、32をスタックに保存する. PC: 11 STACK: [32] MEM: [], STORAGE: {} -Now, we CALLDATALOAD again, popping 32 and pushing the bytes in message data starting from byte 32 until byte 63. +次は再び`CALLDATALOAD`である。 スタックの32バイト目から63バイトまで値を取得しスタックに保存する: PC: 13 STACK: [2020202020] MEM: [], STORAGE: {} -Next, we PUSH1 0. +次は`PUSH1`で0をスタックに保存する: PC: 14 STACK: [2020202020, 0] MEM: [], STORAGE: {} -Now, we load message data bytes 0-31 again (loading message data is just as cheap as loading memory, so we don't bother to save it in memory) +そして再び0-31バイト目のデータを取得してスタックに保存する (なぜメモリに保存させて再利用しないかって?それはメモリからロードをする方が安上がりだからさ): PC: 16 STACK: [2020202020, 54] MEM: [], STORAGE: {} -最後は SSTORE で、 -スタックから取り出した1番目の値を、ストレージ内の参照値とした場所へ、 -二つ目の値を格納する。 -よって: +最後は`SSTORE`で、スタックから取り出した1番目の値を、ストレージ内の参照値とした場所へ、二つ目の値を格納する。よって以下の通りになる: PC: 17 STACK: [] MEM: [], STORAGE: {54: 2020202020} @@ -131,8 +118,8 @@ Now, we load message data bytes 0-31 again (loading message data is just as chea LLLやSerpent、Mutanなどと言った数々の高級言語が存在し、コントラクトをもっと簡単に記述してくれる。これらの言語で書かれたどんな言語もEthereum仮想マシンにコンパイルされ、あなたがEVMバイトコードを含むトランザクション上で呼び出すコントラクトを作成する。  トランザクションには二つのタイプがある。 -「イーサー送信トランザクション」と「コントラクト生成トランザクション」だ。 -イーサー送信トランザクションとは標準的なトランザクションのことで、受信用アドレス、etherの額、バイト型配列のデータと他のパラメータを含み、秘密鍵による署名は送信者のアカウントに関連づけられている。「コントラクト生成トランザクション」は、受信用アドレスが空である点を除いて標準的なトランザクションと似ている。コントラクト生成トランザクションがブロックチェインに自身を組み込むとき、トランザクションのバイト型配列のデータはEVMコードとして解釈され、EVMの実行による返り値が新しいコントラクトのコードとなる。このように、初期化の間中、ひとつのトランザクションにあることをやってもらうことができる。新しいコントラクトのアドレスは送信アドレスとそのアカウントが以前トランザクションを作成した回数に基づいて決定論的に計算される。(nonceと呼ばれるこの値もまた別のセキュリティの観点から保存される。)このように、上記のnameレジストリを生成するためにブロックチェイン上に載せる必要があるフルコードは以下のとおり: +「Ether送信トランザクション」と「コントラクト生成トランザクション」だ。 +Ether送信トランザクションとは標準的なトランザクションのことで、受信用アドレス、etherの額、バイト型配列のデータと他のパラメータを含み、秘密鍵による署名は送信者のアカウントに関連づけられている。「コントラクト生成トランザクション」は、受信用アドレスが空である点を除いて標準的なトランザクションと似ている。コントラクト生成トランザクションがブロックチェーンに自身を組み込むとき、トランザクションのバイト型配列のデータはEVMコードとして解釈され、EVMの実行による返り値が新しいコントラクトのコードとなる。このように、初期化の間中、ひとつのトランザクションにあることをやってもらうことができる。新しいコントラクトのアドレスは送信アドレスとそのアカウントが以前トランザクションを作成した回数に基づいて決定論的に計算される。(nonceと呼ばれるこの値もまた別のセキュリティの観点から保存される。)このように、上記のnameレジストリを生成するためにブロックチェーン上に載せる必要があるフルコードは以下のとおり: PUSH1 16 DUP PUSH1 12 PUSH1 0 CODECOPY PUSH1 0 RETURN STOP PUSH1 0 CALLDATALOAD SLOAD NOT PUSH1 9 JUMPI STOP PUSH1 32 CALLDATALOAD PUSH1 0 CALLDATALOAD SSTORE @@ -141,12 +128,12 @@ LLLやSerpent、Mutanなどと言った数々の高級言語が存在し、コ ### Gas - 仮想マシンを動かす上で重要な側面がある。それは「仮想マシン内部で処理されるあらゆる単一操作は、実際はすべてのノード上で同時に実行される」ということだ。イーサリウム1.0の必要なコンポーネントであり、「仮想マシン上のどんなコントラクトもほぼコスト0で他のあらゆるコントラクトを呼び出すことができる」といった恩恵をもたしてくれる。しかしながら、Ethereum仮想マシン上での計算処理のステップはとても高価なもとなる。Ethereum仮想マシンの使用方法の概要は、「1999年代以降のスマホでできないことは、ここでもできない。」とでもとらえておけばだいたい正しい。 -ビジネスロジックを走らせたり、署名やその他の暗号オブジェクトの有効化をしているEVMの正しい使用法として;EVMの使用法の上限としてあるのが、他のブロックチェインの部分集合を有効化するアプリケーションだ。(例:分散型ether - bitcoin 両替所) 受け入れがたい使い道としては、ファイルストレージやEmailテキスト、メールシステム、画像処理インターフェースを用いて行うプログラムや遺伝的アルゴリズムや機械学習、グラフ探索などのcloud computingにベストマッチするアプリケーションなどだ。 + 仮想マシンを動かす上で重要な側面がある。それは「仮想マシン内部で処理されるあらゆる単一操作は、実際はすべてのノード上で同時に実行される」ということだ。Ethereum1.0の必要なコンポーネントであり、「仮想マシン上のどんなコントラクトもほぼコスト0で他のあらゆるコントラクトを呼び出すことができる」といった恩恵をもたしてくれる。しかしながら、Ethereum仮想マシン上での計算処理のステップはとても高価なもとなる。Ethereum仮想マシンの使用方法の概要は、「1999年代以降のスマホでできないことは、ここでもできない。」とでもとらえておけばだいたい正しい。 +ビジネスロジックを走らせたり、署名やその他の暗号オブジェクトの有効化をしているEVMの正しい使用法として;EVMの使用法の上限としてあるのが、他のブロックチェーンの部分集合を有効化するアプリケーションだ。(例:分散型ether - bitcoin 両替所) 受け入れがたい使い道としては、ファイルストレージやEmailテキスト、メールシステム、画像処理インターフェースを用いて行うプログラムや遺伝的アルゴリズムや機械学習、グラフ探索などのcloud computingにベストマッチするアプリケーションなどだ。 - 故意による攻撃や破壊を予防するため、イーサリウムプロトコルは、一計算ステップあたりの使用料を徴収する。料金は市場に基づくものの、いざ動かしてみると強制力をともわすような設計がなされている。;ブロックひとつあたりに蓄えられるオペレーション数の流動的上限があることによって、ほぼコストなしでトランザクションをインクルードすることのできる(ブロックを生成することのできる)マイナー(採掘者)でさえネットワーク全体へのトランザクションのコストと同額の使用料が課せられる。手数料とブロックのオペレーション上限のシステムの経済基礎知識についての詳細は、イーサリウム白書の「fee」の項目を参照。 + 故意による攻撃や破壊を予防するため、Ethereumプロトコルは、一計算ステップあたりの使用料を徴収する。料金は市場に基づくものの、いざ動かしてみると強制力をともわすような設計がなされている。;ブロックひとつあたりに蓄えられるオペレーション数の流動的上限があることによって、ほぼコストなしでトランザクションをインクルードすることのできる(ブロックを生成することのできる)マイナー(採掘者)でさえネットワーク全体へのトランザクションのコストと同額の使用料が課せられる。手数料とブロックのオペレーション上限のシステムの経済基礎知識についての詳細は、Ethereum白書の「fee」の項目を参照。 - 手数料が実際にどう動くかをいかに述べる。あらゆるドランザクションは、他のデータとともに、ガス価格とガス開始値を含む。ガス開始値とはガスの量であり、トランザクション自身がそれを確約する。ガス価格とはトランザクションが支払うことになる単位ガス料金だ。;このようにして、トランサクションが送られると、ガスがあるとき最初に行われるのが、送信者のアカウントのバランスから、トランザクションの値と、(ガス価格☓ガス開始値)[wei]を足したものを差し引く。ガス価格は送信者によりセットされるが、低すぎるガス価格のトランザクションの処理は、採掘者が拒否をする可能性が高いだろう。 + 手数料が実際にどう動くかをいかに述べる。あらゆるトランザクションは、他のデータとともに、ガス価格とガス開始値を含む。ガス開始値とはガスの量であり、トランザクション自身がそれを確約する。ガス価格とはトランザクションが支払うことになる単位ガス料金だ。;このようにして、トランサクションが送られると、ガスがあるとき最初に行われるのが、送信者のアカウントのバランスから、トランザクションの値と、(ガス価格☓ガス開始値)[wei]を足したものを差し引く。ガス価格は送信者によりセットされるが、低すぎるガス価格のトランザクションの処理は、採掘者が拒否をする可能性が高いだろう。  ガスはざっくりといえば、計算ステップのカウンターとして考えることができ、トランザクションの実行中存在するもので、実行が終われば消えてなくなる。トランザクションの実行が始まった時、今あるガスは(ガス開始値 - 500 - 5 ☓ トランザクションデータ長※)としてセットされる。全計算ステップにおいて、あるガス量(ふつう1で、時々オペレーションに依存して値が大きくなる)が全体から差し引かれていく。もしガスが0に達すれば、すべての実行は元に戻るがトランザクションは有効で送信者はガスの料金を支払わなければならない。もし、トランザクションの実行が無事終了し、Nだけガスがのこっていたら、N×ガス価格が払い戻されるというわけだ。 @@ -224,9 +211,9 @@ The opcodes in the EVM are as follows: Note that high-level languages will often have their own wrappers for these opcodes, sometimes with very different interfaces. -### Basics of the Ethereum Blockchain +### Ethereum ブロックチェーンの基本 - イーサリアム・ブロックチェイン(あるいは「帳簿」)は分散型で(中央集約型ではなく)、全アカウントのカレントステイト(現在の状態)を保持し、大規模に複製されたデータベースである。このブロックチェーンは全アカウントの状態を貯蔵するのに、[「パトリシア木」](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree) というデータ構造を採用している。この「パトリシア木」は本質的に、一般的なKey/value貯蔵時にふるまう「マークル木」の特殊型である。標準のマークル木のように、パトリシア木はルートハッシュを保持している。ルートハッシュは、木構造全体を参照するために使用可能で、木のコンテンツはルートハッシュの変更なしに修正不可能である。それぞれのアカウントのために、木は、[ account_nonce, ether_balance, code_hash, storage_root ] をふくんだ、4つの構成要素からなるタップル(4-tuple)を貯蔵している。ここで、このタップルの要素の定義は以下の通りである。 + Ethereum・ブロックチェーン(あるいは「帳簿」)は分散型で(中央集約型ではなく)、全アカウントのカレントステイト(現在の状態)を保持し、大規模に複製されたデータベースである。このブロックチェーンは全アカウントの状態を貯蔵するのに、[「パトリシア木」](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree) というデータ構造を採用している。この「パトリシア木」は本質的に、一般的なKey/value貯蔵時にふるまう「マークル木」の特殊型である。標準のマークル木のように、パトリシア木はルートハッシュを保持している。ルートハッシュは、木構造全体を参照するために使用可能で、木のコンテンツはルートハッシュの変更なしに修正不可能である。それぞれのアカウントのために、木は、[ account_nonce, ether_balance, code_hash, storage_root ] をふくんだ、4つの構成要素からなるタップル(4-tuple)を貯蔵している。ここで、このタップルの要素の定義は以下の通りである。 * account_nonce:アカウントから送られたトランザクション数 * ether_balance :アカウントの残金 @@ -237,13 +224,13 @@ Note that high-level languages will often have their own wrappers for these opco ![img](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/chaindiag.png) - 毎分、マイナーは新しいブロックを生成し、(イーサリアムのマイニングの概念はビットコインにおける概念と全く同じである。より情報が必要ならばそこらのビットコインのチュートリアルを見るとよい。)新しいブロックは、「一番最近生成されたブロック以降に生成され、かつパトリシア木が、これらのトランザクションを一つのブロックとして適用しマイナーに報酬を与えたのち、そのルートのハッシュ値を新しい状態(状態木)にしてから、新たに生成されたトランザクションのリスト」を含んでいる。 + 毎分、マイナーは新しいブロックを生成し、(Ethereumのマイニングの概念はビットコインにおける概念と全く同じである。より情報が必要ならばそこらのビットコインのチュートリアルを見るとよい。)新しいブロックは、「一番最近生成されたブロック以降に生成され、かつパトリシア木が、これらのトランザクションを一つのブロックとして適用しマイナーに報酬を与えたのち、そのルートのハッシュ値を新しい状態(状態木)にしてから、新たに生成されたトランザクションのリスト」を含んでいる。  パトリシア木の仕組みのおかげで、もし少ししかない変更がなされれば、木の大部分は変更前の最後の状態と全く同じになるだろう。このように、新しいパトリシア木のノードが単に、古いパトリシア木と新しいパトリシア木が全く同じである空間における古い方のノードを貯蔵する同じメモリアドレスを指し戻すことができるだろうような場合には、同じデータを二度蓄える必要はない。N番目のブロックとN+1番目のブロックの間に(N+1番目のブロックに取り込まれるべき)、千箇所の変更があったとして、たとえ全パトリシア木のデータサイズが何ギガバイトに及ぼうとも、N+1番目のブロックに貯蔵されるのに必要な新しいデータ量はたかだか数百キロバイトであり、基本的にもっと少ない(同じコントラクト内で変化が生じたときは特に)。全てのブロックは、ブロック数、タイムスタンプ、マイナーのアドレス、ガスの上限のような他のデータと同様にして、一つ前のブロックのハッシュ値を含んでいる。 ### Graphical Interfaces - コントラクトはそれ自身とてもパワフルなものだが、Dアプリを完全にするものとは言えない。Dアプリはむしろ、コントラクトとそのコントラクトを使用するグラフィカルインターフェースの融合によるものである。(これは、現バージョンのイーサリアムのことを述べており、イーサリアムの未来バージョンでは、whisperといった、Dアプリ内のノードに対して、ブロックチェインなしで互いにp2pメッセージを送らせることのできるプロトコルを含むだろう。)いまちょうど、そのインターフェイスは、HTML/CSS/JSのウェブページとして実装され、特別な javascript API がイーサリアムブロックチェインと一緒に動作する eth オブジェクト形式の中にある。javascript APIのキーとなる部分は以下の通りである。 + コントラクトはそれ自身とてもパワフルなものだが、Dアプリを完全にするものとは言えない。Dアプリはむしろ、コントラクトとそのコントラクトを使用するグラフィカルインターフェースの融合によるものである。(これは、現バージョンのEthereumのことを述べており、Ethereumの未来バージョンでは、whisperといった、Dアプリ内のノードに対して、ブロックチェーンなしで互いにp2pメッセージを送らせることのできるプロトコルを含むだろう。)いまちょうど、そのインターフェイスは、HTML/CSS/JSのウェブページとして実装され、特別な javascript API がEthereumブロックチェーンと一緒に動作する eth オブジェクト形式の中にある。javascript APIのキーとなる部分は以下の通りである。 * `eth.transact(from, ethervalue, to, data, gaslimit, gasprice)` - sends a transaction to the desired address from the desired address (note: `from` must be a private key and `to` must be an address in hex form) with the desired parameters * `(string).pad(n)` - converts a number, encoded as a string, to binary form `n` bytes long @@ -253,10 +240,10 @@ Note that high-level languages will often have their own wrappers for these opco * `eth.key` - the user's private key * `eth.watch(acct, index, f)` - calls `f` when the given storage entry of the given account changes - eth オブジェクトを利用するのに、特別なソースファイルやライブラリは全く要らない。 -しかしながら、そうして作られたDアプリはイーサリアムクライアントの中で開いたときのみ動作するようになり、一般的なwebブラウザ上では動かない。Javascript APIの実践的使用例として[the source code of this webpage](http://gavwood.com/gavcoin.html)を訪れるとよい。 + ethオブジェクトを利用するのに、特別なソースファイルやライブラリは全く要らない。 +しかしながら、そうして作られたDアプリはEthereumクライアントの中で開いたときのみ動作するようになり、一般的なwebブラウザ上では動かない。Javascript APIの実践的使用例として[the source code of this webpage](http://gavwood.com/gavcoin.html)を訪れるとよい。 . ### Fine Points To Keep Track Of -See [https://github.com/ethereum/wiki/wiki/Subtleties](https://github.com/ethereum/wiki/wiki/Subtleties) \ No newline at end of file +See [https://github.com/ethereum/wiki/wiki/Subtleties](https://github.com/ethereum/wiki/wiki/Subtleties) diff --git a/[Japanese]-Ethereum-TOC.md b/pages/other-languages/[Japanese]-Ethereum-TOC.md similarity index 100% rename from [Japanese]-Ethereum-TOC.md rename to pages/other-languages/[Japanese]-Ethereum-TOC.md diff --git a/[Japanese]-HPOC_2015.md b/pages/other-languages/[Japanese]-HPOC_2015.md similarity index 100% rename from [Japanese]-HPOC_2015.md rename to pages/other-languages/[Japanese]-HPOC_2015.md diff --git a/[Japanese]-Javascript-API.md b/pages/other-languages/[Japanese]-Javascript-API.md similarity index 100% rename from [Japanese]-Javascript-API.md rename to pages/other-languages/[Japanese]-Javascript-API.md diff --git a/[Japanese]--License.md b/pages/other-languages/[Japanese]-License.md similarity index 100% rename from [Japanese]--License.md rename to pages/other-languages/[Japanese]-License.md diff --git a/[Japanese]-Solidity-Tutorial.md b/pages/other-languages/[Japanese]-Solidity-Tutorial.md similarity index 100% rename from [Japanese]-Solidity-Tutorial.md rename to pages/other-languages/[Japanese]-Solidity-Tutorial.md diff --git "a/[Japanese]-Whisper-\357\274\210\343\202\246\343\202\243\343\202\271\343\203\221\343\203\274\357\274\211.md" "b/pages/other-languages/[Japanese]-Whisper-\357\274\210\343\202\246\343\202\243\343\202\271\343\203\221\343\203\274\357\274\211.md" similarity index 100% rename from "[Japanese]-Whisper-\357\274\210\343\202\246\343\202\243\343\202\271\343\203\221\343\203\274\357\274\211.md" rename to "pages/other-languages/[Japanese]-Whisper-\357\274\210\343\202\246\343\202\243\343\202\271\343\203\221\343\203\274\357\274\211.md" diff --git a/[Japenese]-Ethereum-TOC.md b/pages/other-languages/[Japenese]-Ethereum-TOC.md similarity index 100% rename from [Japenese]-Ethereum-TOC.md rename to pages/other-languages/[Japenese]-Ethereum-TOC.md diff --git a/[Persian]-Ethereum-TOC.md b/pages/other-languages/[Persian]-Ethereum-TOC.md similarity index 100% rename from [Persian]-Ethereum-TOC.md rename to pages/other-languages/[Persian]-Ethereum-TOC.md diff --git a/[Romanian]-Block-Protocol-2.0.md b/pages/other-languages/[Romanian]-Block-Protocol-2.0.md similarity index 100% rename from [Romanian]-Block-Protocol-2.0.md rename to pages/other-languages/[Romanian]-Block-Protocol-2.0.md diff --git a/[Romanian]-CLL.md b/pages/other-languages/[Romanian]-CLL.md similarity index 100% rename from [Romanian]-CLL.md rename to pages/other-languages/[Romanian]-CLL.md diff --git a/[Romanian]-Cuprins.md b/pages/other-languages/[Romanian]-Cuprins.md similarity index 100% rename from [Romanian]-Cuprins.md rename to pages/other-languages/[Romanian]-Cuprins.md diff --git a/[Romanian]-Dagger.md b/pages/other-languages/[Romanian]-Dagger.md similarity index 100% rename from [Romanian]-Dagger.md rename to pages/other-languages/[Romanian]-Dagger.md diff --git a/[Romanian]-Layers.md b/pages/other-languages/[Romanian]-Layers.md similarity index 100% rename from [Romanian]-Layers.md rename to pages/other-languages/[Romanian]-Layers.md diff --git a/[Romanian]-Limbajul-de-programare-Serpent.md b/pages/other-languages/[Romanian]-Limbajul-de-programare-Serpent.md similarity index 100% rename from [Romanian]-Limbajul-de-programare-Serpent.md rename to pages/other-languages/[Romanian]-Limbajul-de-programare-Serpent.md diff --git a/[Romanian]-Wire-Protocol.md b/pages/other-languages/[Romanian]-Wire-Protocol.md similarity index 100% rename from [Romanian]-Wire-Protocol.md rename to pages/other-languages/[Romanian]-Wire-Protocol.md diff --git a/pages/ethereum-toc/[chinese]-ethereum-toc.md b/pages/other-languages/[chinese]-ethereum-toc.md similarity index 100% rename from pages/ethereum-toc/[chinese]-ethereum-toc.md rename to pages/other-languages/[chinese]-ethereum-toc.md diff --git a/pages/rlp/[chinese]-rlp.md b/pages/other-languages/[chinese]-rlp.md similarity index 100% rename from pages/rlp/[chinese]-rlp.md rename to pages/other-languages/[chinese]-rlp.md diff --git a/pages/white-paper/[chinese]-white-paper.md b/pages/other-languages/[chinese]-white-paper.md similarity index 100% rename from pages/white-paper/[chinese]-white-paper.md rename to pages/other-languages/[chinese]-white-paper.md diff --git a/pages/ethereum-toc/[french]-ethereum-toc.md b/pages/other-languages/[french]-ethereum-toc.md similarity index 100% rename from pages/ethereum-toc/[french]-ethereum-toc.md rename to pages/other-languages/[french]-ethereum-toc.md diff --git a/pages/ethereum-toc/[german]-ethereum-toc.md b/pages/other-languages/[german]-ethereum-toc.md similarity index 100% rename from pages/ethereum-toc/[german]-ethereum-toc.md rename to pages/other-languages/[german]-ethereum-toc.md diff --git a/pages/rlp/[german]-rlp.md b/pages/other-languages/[german]-rlp.md similarity index 100% rename from pages/rlp/[german]-rlp.md rename to pages/other-languages/[german]-rlp.md diff --git a/pages/white-paper/[german]-white-paper.md b/pages/other-languages/[german]-white-paper.md similarity index 100% rename from pages/white-paper/[german]-white-paper.md rename to pages/other-languages/[german]-white-paper.md diff --git a/pages/ethereum-toc/[italian]-ethereum-toc.md b/pages/other-languages/[italian]-ethereum-toc.md similarity index 100% rename from pages/ethereum-toc/[italian]-ethereum-toc.md rename to pages/other-languages/[italian]-ethereum-toc.md diff --git a/pages/design-rationale/[japanese]-design-rationale.md b/pages/other-languages/[japanese]-design-rationale.md similarity index 100% rename from pages/design-rationale/[japanese]-design-rationale.md rename to pages/other-languages/[japanese]-design-rationale.md diff --git a/pages/patricia-tree/[japanese]-patricia-tree.md b/pages/other-languages/[japanese]-patricia-tree.md similarity index 100% rename from pages/patricia-tree/[japanese]-patricia-tree.md rename to pages/other-languages/[japanese]-patricia-tree.md diff --git a/pages/rlp/[japanese]-rlp.md b/pages/other-languages/[japanese]-rlp.md similarity index 100% rename from pages/rlp/[japanese]-rlp.md rename to pages/other-languages/[japanese]-rlp.md diff --git a/pages/white-paper/[japanese]-white-paper.md b/pages/other-languages/[japanese]-white-paper.md similarity index 100% rename from pages/white-paper/[japanese]-white-paper.md rename to pages/other-languages/[japanese]-white-paper.md diff --git a/pages/white-paper/[korean]-white-paper.md b/pages/other-languages/[korean]-white-paper.md similarity index 100% rename from pages/white-paper/[korean]-white-paper.md rename to pages/other-languages/[korean]-white-paper.md diff --git a/pages/white-paper/[persian]-white-paper.md b/pages/other-languages/[persian]-white-paper.md similarity index 100% rename from pages/white-paper/[persian]-white-paper.md rename to pages/other-languages/[persian]-white-paper.md diff --git a/pages/patricia-tree/[romanian]-patricia-tree.md b/pages/other-languages/[romanian]-patricia-tree.md similarity index 100% rename from pages/patricia-tree/[romanian]-patricia-tree.md rename to pages/other-languages/[romanian]-patricia-tree.md diff --git a/pages/rlp/[romanian]-rlp.md b/pages/other-languages/[romanian]-rlp.md similarity index 100% rename from pages/rlp/[romanian]-rlp.md rename to pages/other-languages/[romanian]-rlp.md diff --git a/pages/white-paper/[romanian]-white-paper.md b/pages/other-languages/[romanian]-white-paper.md similarity index 100% rename from pages/white-paper/[romanian]-white-paper.md rename to pages/other-languages/[romanian]-white-paper.md diff --git a/pages/other-languages/[spanish]-ethereum-toc.md b/pages/other-languages/[spanish]-ethereum-toc.md new file mode 100644 index 000000000..1f4770a5b --- /dev/null +++ b/pages/other-languages/[spanish]-ethereum-toc.md @@ -0,0 +1,24 @@ +--- +name: Ethereum TOC +category: +--- + +### Bienvenidos a Ethereum, la plataforma para la siguiente generación de contratos inteligentes y aplicaciones descentralizadas. + +[Whitepaper de Ethereum](https://github.com/ethereum/wiki/wiki/White-Paper) + +[RLP](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP), Prefijo Linear Recursivo (Recursive Linear Prefix), usado para codificación de datos a través de Ethereum. + +[Patricia Tree](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree) especificaciones del árbol Merkle Patricia (“Merkle Patria Tree”, también conocido como Trie), la estructura usada para almacenar y procesar a través de funciones Hash el estado de la cadena de bloques en Ethereum. + +[Protocolo de conexión](https://github.com/ethereum/wiki/wiki/Ethereum-Wire-Protocol), especificaciones. + +[CLL](https://github.com/ethereum/wiki/blob/master/CLL.md), Lenguage de alto nivel similar a C usado para crear contratos, especificaciones. + +[Dagger](https://github.com/ethereum/wiki/blob/master/Dagger.md), Prueba de trabajo (Proof-of-work) de Ethereum. + +[Protocolo de Bloques 2.0](https://github.com/ethereum/wiki/blob/master/Block-Protocol-2.0.md) + +[Capas](https://github.com/ethereum/wiki/blob/master/Layers.md) + +[Cámara de compensación](https://github.com/ethereum/wiki/blob/master/Clearinghouse.md) diff --git "a/[\344\270\255\346\226\207]-Serpent\346\214\207\345\215\227.md" "b/pages/other-languages/[\344\270\255\346\226\207]-Serpent\346\214\207\345\215\227.md" similarity index 100% rename from "[\344\270\255\346\226\207]-Serpent\346\214\207\345\215\227.md" rename to "pages/other-languages/[\344\270\255\346\226\207]-Serpent\346\214\207\345\215\227.md" diff --git "a/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212Wiki\347\233\256\345\275\225.md" "b/pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212Wiki\347\233\256\345\275\225.md" similarity index 100% rename from "[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212Wiki\347\233\256\345\275\225.md" rename to "pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212Wiki\347\233\256\345\275\225.md" diff --git "a/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\345\274\200\345\217\221\350\256\241\345\210\222.md" "b/pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\345\274\200\345\217\221\350\256\241\345\210\222.md" similarity index 99% rename from "[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\345\274\200\345\217\221\350\256\241\345\210\222.md" rename to "pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\345\274\200\345\217\221\350\256\241\345\210\222.md" index b0f12fde4..555f733d3 100644 --- "a/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\345\274\200\345\217\221\350\256\241\345\210\222.md" +++ "b/pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\345\274\200\345\217\221\350\256\241\345\210\222.md" @@ -17,7 +17,7 @@ category: 黄皮书(内有关于以太坊技术的实现规范), -官方网站(https://www.ethereum.org/)里面有关于包括介绍的视频等以太坊的简要概述, +官方网站[https://www.ethereum.org/](https://www.ethereum.org/) 里面有关于包括介绍的视频等以太坊的简要概述, 本文档介绍了ĐΞV计划如何制定以太坊的软件平台,在以太坊项目的大背景下ĐΞV计划的定位。 @@ -275,4 +275,4 @@ DAO化 – 虽然DAO化肯定会是加密货币的一个主要的研究重点, - \ No newline at end of file + diff --git "a/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\346\234\257\350\257\255\350\241\250.md" "b/pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\346\234\257\350\257\255\350\241\250.md" similarity index 100% rename from "[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\346\234\257\350\257\255\350\241\250.md" rename to "pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\346\234\257\350\257\255\350\241\250.md" diff --git "a/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\347\231\275\347\232\256\344\271\246.md" "b/pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\347\231\275\347\232\256\344\271\246.md" similarity index 99% rename from "[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\347\231\275\347\232\256\344\271\246.md" rename to "pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\347\231\275\347\232\256\344\271\246.md" index 243b8d309..a2e59f48e 100644 --- "a/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\347\231\275\347\232\256\344\271\246.md" +++ "b/pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\347\231\275\347\232\256\344\271\246.md" @@ -78,7 +78,7 @@ ### 挖矿 -![](https://camo.githubusercontent.com/e8e2a0c15c17b066e7f17056f7697819b9a1aa33/687474703a2f2f766974616c696b2e63612f66696c65732f626c6f636b5f706963747572652e706e67) +![](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/block.png) 如果我们拥有可信任的中心化服务机构,状态转换系统可以很容易地实现,可以简单地将上述功能准确编码。然而,我们想把比特币系统建成为去中心化的货币系统,为了确保每个人都同意交易的顺序,我们需要将状态转换系统与一个共识系统结合起来。比特币的去中心化共识进程要求网络中的节点不断尝试将交易打包成“区块”。网络被设计为大约每十分钟产生一个区块,每个区块包含一个时间戳、一个随机数、一个对上一个区块的引用(即哈希)和上一区块生成以来发生的所有交易列表。这样随着时间流逝就创建出了一个持续增长的区块链,它不断地更新,从而能够代表比特币账本的最新状态。 @@ -191,7 +191,7 @@ if !self.storage[calldataload(0)]: 3. 初始设定gas=2000,假设交易长为170字节,每字节的费用是5,减去850,所以还剩1150。 4. 从发送者账户减去10个以太币,为合约账户增加10个以太币。 5. 运行代码。在这个合约中,运行代码很简单:它检查合约存储器索引为2处是否已使用,注意到它未被使用,然后将其值置为CHARLIE。假设这消耗了187单位的瓦斯,于是剩余的瓦斯为1150 - 187 = 963。 -6. 向发送者的账户增加963*0.001=0.963个以太币,返回最终状态。 +6. 向发送者的账户增加963*0.001=0.963个以太币,返回最终状态。 如果没有合约接收交易,那么所有的交易费用就等于GASPRICE乘以交易的字节长度,交易的数据就与交易费用无关了。另外,需要注意的是,合约发起的消息可以对它们产生的计算分配瓦斯限额,如果子计算的瓦斯用完了,它只恢复到消息发出时的状态。因此,就像交易一样,合约也可以通过对它产生的子计算设置严格的限制,保护它们的计算资源。 ### 代码执行 diff --git "a/[\344\270\255\346\226\207]-\346\254\212\347\233\212\350\255\211\346\230\216\346\251\237\345\210\266FAQ.md" "b/pages/other-languages/[\344\270\255\346\226\207]-\346\254\212\347\233\212\350\255\211\346\230\216\346\251\237\345\210\266FAQ.md" similarity index 100% rename from "[\344\270\255\346\226\207]-\346\254\212\347\233\212\350\255\211\346\230\216\346\251\237\345\210\266FAQ.md" rename to "pages/other-languages/[\344\270\255\346\226\207]-\346\254\212\347\233\212\350\255\211\346\230\216\346\251\237\345\210\266FAQ.md" diff --git "a/[\344\270\255\346\226\207]-\347\275\221\347\273\234\347\212\266\346\200\201.md" "b/pages/other-languages/[\344\270\255\346\226\207]-\347\275\221\347\273\234\347\212\266\346\200\201.md" similarity index 100% rename from "[\344\270\255\346\226\207]-\347\275\221\347\273\234\347\212\266\346\200\201.md" rename to "pages/other-languages/[\344\270\255\346\226\207]-\347\275\221\347\273\234\347\212\266\346\200\201.md" diff --git "a/\320\240\321\203\320\272\320\276\320\262\320\276\320\264\321\201\321\202\320\262\320\276-\320\277\320\276-Solidity.md" "b/pages/other-languages/\320\240\321\203\320\272\320\276\320\262\320\276\320\264\321\201\321\202\320\262\320\276-\320\277\320\276-Solidity.md" similarity index 100% rename from "\320\240\321\203\320\272\320\276\320\262\320\276\320\264\321\201\321\202\320\262\320\276-\320\277\320\276-Solidity.md" rename to "pages/other-languages/\320\240\321\203\320\272\320\276\320\262\320\276\320\264\321\201\321\202\320\262\320\276-\320\277\320\276-Solidity.md" diff --git a/Swarm-Hash.md b/pages/swarm/Swarm-Hash.md similarity index 100% rename from Swarm-Hash.md rename to pages/swarm/Swarm-Hash.md diff --git a/Whisper-Overview.md b/pages/whisper/Whisper-Overview.md similarity index 100% rename from Whisper-Overview.md rename to pages/whisper/Whisper-Overview.md diff --git a/Whisper-PoC-2-Protocol-Spec.md b/pages/whisper/Whisper-PoC-2-Protocol-Spec.md similarity index 100% rename from Whisper-PoC-2-Protocol-Spec.md rename to pages/whisper/Whisper-PoC-2-Protocol-Spec.md diff --git a/Whisper-PoC-2-Wire-Protocol.md b/pages/whisper/Whisper-PoC-2-Wire-Protocol.md similarity index 100% rename from Whisper-PoC-2-Wire-Protocol.md rename to pages/whisper/Whisper-PoC-2-Wire-Protocol.md diff --git a/Whisper-Wire-Protocol.md b/pages/whisper/Whisper-Wire-Protocol.md similarity index 100% rename from Whisper-Wire-Protocol.md rename to pages/whisper/Whisper-Wire-Protocol.md diff --git a/Whisper.md b/pages/whisper/Whisper.md similarity index 100% rename from Whisper.md rename to pages/whisper/Whisper.md diff --git a/pages/white-paper/[english]-white-paper.md b/pages/white-paper/[english]-white-paper.md index 7b31acf22..28b0258fa 100644 --- a/pages/white-paper/[english]-white-paper.md +++ b/pages/white-paper/[english]-white-paper.md @@ -1,4 +1,4 @@ ---- +---gg name: White Paper category: Basics --- @@ -48,7 +48,7 @@ The mechanism behind proof of work was a breakthrough in the space because it si ### Bitcoin As A State Transition System -![statetransition.png](http://vitalik.ca/files/statetransition.png?2) +![statetransition.png](https://raw.githubusercontent.com/vbuterin/diagrams/master/statetransition.png) From a technical standpoint, the ledger of a cryptocurrency such as Bitcoin can be thought of as a state transition system, where there is a "state" consisting of the ownership status of all existing bitcoins and a "state transition function" that takes a state and a transaction and outputs a new state which is the result. In a standard banking system, for example, the state is a balance sheet, a transaction is a request to move $X from A to B, and the state transition function reduces the value in A's account by $X and increases the value in B's account by $X. If A's account has less than $X in the first place, the state transition function returns an error. Hence, one can formally define: @@ -76,7 +76,7 @@ The first half of the first step prevents transaction senders from spending coin ### Mining -![block_picture.jpg](http://vitalik.ca/files/block_picture.png) +![block_picture.jpg](https://raw.githubusercontent.com/vbuterin/diagrams/master/block.png) If we had access to a trustworthy centralized service, this system would be trivial to implement; it could simply be coded exactly as described, using a centralized server's hard drive to keep track of the state. However, with Bitcoin we are trying to build a decentralized currency system, so we will need to combine the state transaction system with a consensus system in order to ensure that everyone agrees on the order of transactions. Bitcoin's decentralized consensus process requires nodes in the network to continuously attempt to produce packages of transactions called "blocks". The network is intended to produce roughly one block every ten minutes, with each block containing a timestamp, a nonce, a reference to (ie. hash of) the previous block and a list of all of the transactions that have taken place since the previous block. Over time, this creates a persistent, ever-growing, "blockchain" that constantly updates to represent the latest state of the Bitcoin ledger. @@ -135,7 +135,7 @@ Even without any extensions, the Bitcoin protocol actually does facilitate a wea However, the scripting language as implemented in Bitcoin has several important limitations: * **Lack of Turing-completeness** - that is to say, while there is a large subset of computation that the Bitcoin scripting language supports, it does not nearly support everything. The main category that is missing is loops. This is done to avoid infinite loops during transaction verification; theoretically it is a surmountable obstacle for script programmers, since any loop can be simulated by simply repeating the underlying code many times with an if statement, but it does lead to scripts that are very space-inefficient. For example, implementing an alternative elliptic curve signature algorithm would likely require 256 repeated multiplication rounds all individually included in the code. -* **Value-blindness** - there is no way for a UTXO script to provide fine-grained control over the amount that can be withdrawn. For example, one powerful use case of an oracle contract would be a hedging contract, where A and B put in $1000 worth of BTC and after 30 days the script sends $1000 worth of BTC to A and the rest to B. This would require an oracle to determine the value of 1 BTC in USD, but even then it is a massive improvement in terms of trust and infrastructure requirement over the fully centralized solutions that are available now. However, because UTXO are all-or-nothing, the only way to achieve this is through the very inefficient hack of having many UTXO of varying denominations (eg. one UTXO of 2k for every k up to 30) and having O pick which UTXO to send to A and which to B. +* **Value-blindness** - there is no way for a UTXO script to provide fine-grained control over the amount that can be withdrawn. For example, one powerful use case of an oracle contract would be a hedging contract, where A and B put in $1000 worth of BTC and after 30 days the script sends $1000 worth of BTC to A and the rest to B. This would require an oracle to determine the value of 1 BTC in USD, but even then it is a massive improvement in terms of trust and infrastructure requirement over the fully centralized solutions that are available now. However, because UTXO are all-or-nothing, the only way to achieve this is through the very inefficient hack of having many UTXO of varying denominations (eg. one UTXO of 2k for every k up to 30) and having the oracle pick which UTXO to send to A and which to B. * **Lack of state** - UTXO can either be spent or unspent; there is no opportunity for multi-stage contracts or scripts which keep any other internal state beyond that. This makes it hard to make multi-stage options contracts, decentralized exchange offers or two-stage cryptographic commitment protocols (necessary for secure computational bounties). It also means that UTXO can only be used to build simple, one-off contracts and not more complex "stateful" contracts such as decentralized organizations, and makes meta-protocols difficult to implement. Binary state combined with value-blindness also mean that another important application, withdrawal limits, is impossible. * **Blockchain-blindness** - UTXO are blind to blockchain data such as the nonce, the timestamp and previous block hash. This severely limits applications in gambling, and several other categories, by depriving the scripting language of a potentially valuable source of randomness. @@ -189,7 +189,7 @@ Note that the gas allowance assigned by a transaction or contract applies to the ### Ethereum State Transition Function -![ethertransition.png](http://vitalik.ca/files/ethertransition.png?1) +![ethertransition.png](https://raw.githubusercontent.com/vbuterin/diagrams/master/ethertransition.png) The Ethereum state transition function, `APPLY(S,TX) -> S'` can be defined as follows: @@ -232,7 +232,7 @@ The formal execution model of EVM code is surprisingly simple. While the Ethereu ### Blockchain and Mining -![apply_block_diagram.png](http://vitalik.ca/files/apply_block_diagram.png) +![apply_block_diagram.png](https://raw.githubusercontent.com/vbuterin/diagrams/master/apply_block_diagram.png) The Ethereum blockchain is in many ways similar to the Bitcoin blockchain, although it does have some differences. The main difference between Ethereum and Bitcoin with regard to the blockchain architecture is that, unlike Bitcoin, Ethereum blocks contain a copy of both the transaction list and the most recent state. Aside from that, two other values, the block number and the difficulty, are also stored in the block. The basic block validation algorithm in Ethereum is as follows: @@ -348,12 +348,12 @@ As described by Sompolinsky and Zohar, GHOST solves the first issue of network s Ethereum implements a simplified version of GHOST which only goes down seven levels. Specifically, it is defined as follows: * A block must specify a parent, and it must specify 0 or more uncles -* An uncle included in block B must have the following properties: - * It must be a direct child of the kth generation ancestor of B, where 2 <= k <= 7. - * It cannot be an ancestor of B +* An uncle included in block `B` must have the following properties: + * It must be a direct child of the `k`-th generation ancestor of `B`, where `2 <= k <= 7`. + * It cannot be an ancestor of `B` * An uncle must be a valid block header, but does not need to be a previously verified or even valid block * An uncle must be different from all uncles included in previous blocks and all other uncles included in the same block (non-double-inclusion) -* For every uncle U in block B, the miner of B gets an additional 3.125% added to its coinbase reward and the miner of U gets 93.75% of a standard coinbase reward. +* For every uncle `U` in block `B`, the miner of `B` gets an additional 3.125% added to its coinbase reward and the miner of `U` gets 93.75% of a standard coinbase reward. This limited version of GHOST, with uncles includable only up to 7 generations, was used for two reasons. First, unlimited GHOST would include too many complications into the calculation of which uncles for a given block are valid. Second, unlimited GHOST with compensation as used in Ethereum removes the incentive for a miner to mine on the main chain and not the chain of a public attacker. @@ -379,7 +379,7 @@ However, there are several important deviations from those assumptions in realit (1) provides a tendency for the miner to include fewer transactions, and (2) increases `NC`; hence, these two effects at least partially cancel each other out. (3) and (4) are the major issue; to solve them we simply institute a floating cap: no block can have more operations than `BLK_LIMIT_FACTOR` times the long-term exponential moving average. Specifically: - blk.oplimit = floor((blk.parent.oplimit * (EMAFACTOR - 1) + floor(parent.opcount * BLK_LIMIT_FACTOR)) / EMA_FACTOR) + blk.oplimit = floor((blk.parent.oplimit * (EMA_FACTOR - 1) + floor(parent.opcount * BLK_LIMIT_FACTOR)) / EMA_FACTOR) `BLK_LIMIT_FACTOR` and `EMA_FACTOR` are constants that will be set to 65536 and 1.5 for the time being, but will likely be changed after further analysis. @@ -435,8 +435,6 @@ The issuance model will be as follows: **Long-Term Supply Growth Rate (percent)** -![SPV in bitcoin](https://www.ethereum.org/gh_wiki/inflation.svg) - _Despite the linear currency issuance, just like with Bitcoin over time the supply growth rate nevertheless tends to zero_ The two main choices in the above model are (1) the existence and size of an endowment pool, and (2) the existence of a permanently growing linear supply, as opposed to a capped supply as in Bitcoin. The justification of the endowment pool is as follows. If the endowment pool did not exist, and the linear issuance reduced to 0.217x to provide the same inflation rate, then the total quantity of ether would be 16.5% less and so each unit would be 19.8% more valuable. Hence, in the equilibrium 19.8% more ether would be purchased in the sale, so each unit would once again be exactly as valuable as before. The organization would also then have 1.198x as much BTC, which can be considered to be split into two slices: the original BTC, and the additional 0.198x. Hence, this situation is _exactly equivalent_ to the endowment, but with one important difference: the organization holds purely BTC, and so is not incentivized to support the value of the ether unit. From ab5b41742625df9d93c6a34802a51ce0f5afd79b Mon Sep 17 00:00:00 2001 From: jamesray1 <16969914+jamesray1@users.noreply.github.com> Date: Sat, 7 Apr 2018 14:07:11 +1000 Subject: [PATCH 03/22] Move readme into the top directory --- pages/Readme.md | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 pages/Readme.md diff --git a/pages/Readme.md b/pages/Readme.md deleted file mode 100644 index 6e4b622fe..000000000 --- a/pages/Readme.md +++ /dev/null @@ -1,14 +0,0 @@ -Newcomers and those seeking an introduction to Ethereum may go to https://ethereum.org or https://github.com/ethereum/wiki/wiki. - -Note that you can proofread while you read and learn about anything. - -# Contribution guidelines -Please just **edit the pages in the wiki directly** as shown in the sidebar here: https://github.com/ethereum/wiki/wiki, rather than making **pull requests**. - -Please only create an **issue** if you can't fix it by editing yourself, and only if it is related to the wiki. If it is a technical issue e.g. with [web3 or JSON.RPC](https://github.com/ethereum/web3.js/issues), [geth](https://github.com/ethereum/go-ethereum/issues), [Mist](https://github.com/ethereum/mist) (although note that Mist isn't really user-ready yet, so using alternatives like [MyEtherWallet](https://www.myetherwallet.com/) is recommended instead), etc., please post an issue in the repo for that project as well, and reference the issue that you create in this repo (by copying and pasting the link to the issue in this repo in a comment in the issue in the relevant project repo). - -If you are **translating** an article, please **create a new page** and create the translation in that. Do not edit an existing article by translating it. Someone did this with the home wiki, changing the title, and this actually caused the home page to just direct to a list of pages in the wiki, and made it hard to find the edited home page as the title was changed to Arabic. So **do not edit the title of an article**. - -If you have experience with editing on Wikipedia, then that will help with knowing how to edit this wiki, although the contribution rules are less strict. Referencing facts is a key writing and proofreading task, as well as checking that information is up-to-date (and updating it if otherwise), correcting grammar, typos, and spelling; and making the wiki comprehensive and easy to understand. - -Other rules, such as a neutral point of view and no original research are desirable, but may be hard to maintain. Notability is less relevant. From 39a3d89343e78421e69c1248f947fef6650e8750 Mon Sep 17 00:00:00 2001 From: jamesray1 <16969914+jamesray1@users.noreply.github.com> Date: Sat, 7 Apr 2018 14:09:37 +1000 Subject: [PATCH 04/22] Rename Readme.md to README --- README | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 README diff --git a/README b/README new file mode 100644 index 000000000..6e4b622fe --- /dev/null +++ b/README @@ -0,0 +1,14 @@ +Newcomers and those seeking an introduction to Ethereum may go to https://ethereum.org or https://github.com/ethereum/wiki/wiki. + +Note that you can proofread while you read and learn about anything. + +# Contribution guidelines +Please just **edit the pages in the wiki directly** as shown in the sidebar here: https://github.com/ethereum/wiki/wiki, rather than making **pull requests**. + +Please only create an **issue** if you can't fix it by editing yourself, and only if it is related to the wiki. If it is a technical issue e.g. with [web3 or JSON.RPC](https://github.com/ethereum/web3.js/issues), [geth](https://github.com/ethereum/go-ethereum/issues), [Mist](https://github.com/ethereum/mist) (although note that Mist isn't really user-ready yet, so using alternatives like [MyEtherWallet](https://www.myetherwallet.com/) is recommended instead), etc., please post an issue in the repo for that project as well, and reference the issue that you create in this repo (by copying and pasting the link to the issue in this repo in a comment in the issue in the relevant project repo). + +If you are **translating** an article, please **create a new page** and create the translation in that. Do not edit an existing article by translating it. Someone did this with the home wiki, changing the title, and this actually caused the home page to just direct to a list of pages in the wiki, and made it hard to find the edited home page as the title was changed to Arabic. So **do not edit the title of an article**. + +If you have experience with editing on Wikipedia, then that will help with knowing how to edit this wiki, although the contribution rules are less strict. Referencing facts is a key writing and proofreading task, as well as checking that information is up-to-date (and updating it if otherwise), correcting grammar, typos, and spelling; and making the wiki comprehensive and easy to understand. + +Other rules, such as a neutral point of view and no original research are desirable, but may be hard to maintain. Notability is less relevant. From c087d5b310e30671ad7eb2fdb516f38a6142ad84 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Sat, 7 Apr 2018 14:10:18 +1000 Subject: [PATCH 05/22] Rename README to README.md --- README => README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README => README.md (100%) diff --git a/README b/README.md similarity index 100% rename from README rename to README.md From 6cf14d1cfd8bbafca4b3a9fd5902631ed1a46c02 Mon Sep 17 00:00:00 2001 From: jamesray1 <16969914+jamesray1@users.noreply.github.com> Date: Tue, 10 Apr 2018 20:52:47 +1000 Subject: [PATCH 06/22] Delete everything except the readme as it's all in the wiki/wiki and backed up. --- drafts/[english]-old-ethereum-whitepaper.md | 639 ----- drafts/[english]-patricia-tree-draft.md | 7 - images/natspec1.png | Bin 82697 -> 0 bytes images/natspec2.png | Bin 83621 -> 0 bytes images/natspec3.png | Bin 93201 -> 0 bytes images/natspec4.png | Bin 90201 -> 0 bytes images/natspec5.png | Bin 103151 -> 0 bytes pages/Licensing.md | 34 - pages/Middleware-and-Dapp-Project-Ideas.md | 112 - pages/Open-job-positions-&-Schemes.md | 45 - pages/_Sidebar.md | 75 - .../Fortnight-In-Ethereum-Template.md | 412 --- .../Template:-This-Week-in-Ethereum-w-YY.md | 26 - .../This Week In Ethereum 47.2014.md | 60 - pages/blog-and-notes/Todo-before-alpha.md | 10 - pages/blog-and-notes/stubs/Which-Client?.md | 6 - .../Contract-Metadata-Docs-(NatSpec,-ABI).md | 92 - .../Dapp-Developer-Resources.md | 17 - pages/dapp-development/Dapp-using-Meteor.md | 209 -- .../dapp-development/Ethereum-Contract-ABI.md | 383 --- .../Ethereum-Development-Tutorial.md | 166 -- .../First-steps-with-ethereum-JSON-RPC.md | 82 - pages/dapp-development/JSON-RPC.md | 2381 ---------------- pages/dapp-development/JavaScript-API.md | 2416 ----------------- .../Javascript-Development-Deficiencies.md | 20 - pages/dapp-development/Mix-Features.md | 183 -- pages/dapp-development/Mix:-The-DApp-IDE.md | 181 -- pages/dapp-development/RPC-Testing.md | 17 - .../Standardized_Contract_APIs.md | 295 -- .../Useful-\303\220app-Patterns.md" | 17 - .../serpent/Serpent-1.0-(old).md | 281 -- pages/dapp-development/serpent/Serpent.md | 494 ---- pages/dapp-development/serpent/Serpent_3.0.md | 33 - .../solidity/Solidity,-Docs-and-ABI.md | 231 -- .../solidity/Solidity-Changelog.md | 73 - .../solidity/Solidity-Features.md | 1084 -------- .../solidity/Solidity-Tutorial.md | 18 - .../solidity/Solidity-standard-library.md | 156 -- pages/dapp-development/solidity/Solidity.md | 128 - ...Tags-for-Solidity-in-code-documentation.md | 1 - .../The-Solidity-Programming-Language.md | 239 -- .../[english]-design-rationale.md | 223 -- .../Node-discovery-protocol.md | 13 - .../Web3-Secret-Storage-Definition.md | 172 -- pages/dev-technologies/enode-url-format.md | 21 - pages/dev-technologies/libp2p-Whitepaper.md | 42 - pages/dev-technologies/web.js-0.9.md | 50 - .../\303\220\316\236Vp2p-Wire-Protocol.md" | 90 - pages/eip/Geth-Dapp-loading-proposal.md | 27 - ...ON-RPC-Error-Codes-Improvement-Proposal.md | 63 - pages/eip/Mix-improvement-proposal.md | 24 - pages/eip/Proposal:-BlockHashesFromNumbers.md | 20 - ...-Extend-GetBlockHashes-with-target-hash.md | 47 - pages/eip/Proposal:-NewBlockHashes.md | 21 - pages/eip/Proposal:-Reversion-Notification.md | 109 - .../eip/Proposal:-Transaction-Proxy-Hooks.md | 55 - .../newBlockFilter-Improvement-Proposal.md | 57 - .../sendTransaction-return-value-proposal.md | 22 - .../Dagger-Hashimoto.md | 338 --- pages/ethash-dagger-hashimoto/Dagger.md | 96 - pages/ethash-dagger-hashimoto/Ethash-C-API.md | 59 - .../Ethash-DAG-Disk-Storage-Format.md | 26 - .../Ethash-Design-Rationale.md | 26 - pages/ethash-dagger-hashimoto/Ethash.md | 998 ------- .../Ethash_revision_11.md | 249 -- .../Bad-Block-Reporting.md | 126 - .../Bad-Chain-Canary.md | 19 - .../Block-Protocol-2.0.md | 255 -- ...ockchain-import-and-export-instructions.md | 39 - .../Distributed-Preimage-Archive.md | 86 - .../EVM-Subtleties.md | 74 - .../Ethereum-Natural-Specification-Format.md | 138 - .../Ethereum-Wire-Protocol.md | 116 - .../Light-client-protocol.md | 39 - .../Morden.md | 61 - .../[english]-patricia-tree.md | 141 - .../[english]-rlp.md | 68 - .../research/CLL.md | 166 -- .../research/Chain-Fibers-Redux.md | 121 - .../research/Generalized_Merkle_DHT.md | 33 - .../research/HPOC_2015.md | 92 - .../research/Parallel-Block-Downloads.md | 37 - .../research/Problems.md | 388 --- .../research/Security-Categorization.md | 105 - .../research/Security-Issue-Process.md | 48 - .../research/Serenity_Wishlist.md | 70 - .../Adaptive-Message-IDs.md | 70 - .../Adaptive-Peer-Time.md | 25 - .../infrastructure-networking/Brain-Wallet.md | 38 - .../Clearinghouse.md | 63 - .../Default-Extra-Data-Standard.md | 16 - .../Deterministic_Wallet_Spec.md | 22 - .../EVM-JIT-Binary-Interface.md | 79 - ...ereum-Raspberry-Pi-e\317\200-Programme.md" | 21 - .../Exchange-Integration.md | 14 - ...-Inter-exchange-Client-Address-Protocol.md | 116 - pages/infrastructure-networking/IPv6.md | 20 - .../Kademlia-Peer-Selection.md | 46 - pages/infrastructure-networking/Layers.md | 80 - pages/infrastructure-networking/Mining.md | 81 - .../NatSpec-Determination.md | 17 - .../Natspec-Example.md | 48 - .../Network-Status.md | 101 - .../NewBlock-Message.md | 23 - .../Raspberry-Pi-instructions.md | 120 - .../Registrar-ABI.md | 48 - .../URL-Hint-Protocol.md | 49 - .../Decentralized-apps-(dapps).md | 83 - pages/introduction/Ethereum-introduction.md | 277 -- pages/introduction/FAQ.md | 263 -- pages/introduction/Gitter-Channels.md | 44 - pages/introduction/Glossary.md | 82 - pages/introduction/Home.md | 30 - pages/introduction/What-is-Ethereum.md | 66 - .../other-languages/[German]-Clearinghaus.md | 47 - ...l-proprio-ambiente-di-sviluppo-Ethereum.md | 36 - ...-Introduzione-allo-sviluppo-su-Ethereum.md | 64 - .../other-languages/[Italian]-Libro-Bianco.md | 503 ---- ...panese]-Cryptocurrency-Current-Problems.md | 512 ---- ...Japanese]-Ethereum-Development-Tutorial.md | 249 -- .../[Japanese]-Ethereum-TOC.md | 25 - pages/other-languages/[Japanese]-HPOC_2015.md | 201 -- .../[Japanese]-Javascript-API.md | 2040 -------------- pages/other-languages/[Japanese]-License.md | 51 - .../[Japanese]-Solidity-Tutorial.md | 954 ------- ...71\343\203\221\343\203\274\357\274\211.md" | 127 - .../[Japenese]-Ethereum-TOC.md | 34 - .../other-languages/[Persian]-Ethereum-TOC.md | 8 - .../[Romanian]-Block-Protocol-2.0.md | 205 -- pages/other-languages/[Romanian]-CLL.md | 151 -- pages/other-languages/[Romanian]-Cuprins.md | 26 - pages/other-languages/[Romanian]-Dagger.md | 58 - pages/other-languages/[Romanian]-Layers.md | 66 - ...omanian]-Limbajul-de-programare-Serpent.md | 79 - .../[Romanian]-Wire-Protocol.md | 82 - .../other-languages/[chinese]-ethereum-toc.md | 16 - pages/other-languages/[chinese]-rlp.md | 68 - .../other-languages/[chinese]-white-paper.md | 477 ---- .../other-languages/[french]-ethereum-toc.md | 93 - .../other-languages/[german]-ethereum-toc.md | 24 - pages/other-languages/[german]-rlp.md | 66 - pages/other-languages/[german]-white-paper.md | 630 ----- .../other-languages/[italian]-ethereum-toc.md | 30 - .../[japanese]-design-rationale.md | 610 ----- .../[japanese]-patricia-tree.md | 139 - pages/other-languages/[japanese]-rlp.md | 70 - .../other-languages/[japanese]-white-paper.md | 1315 --------- pages/other-languages/[korean]-white-paper.md | 553 ---- .../other-languages/[persian]-white-paper.md | 14 - .../[romanian]-patricia-tree.md | 137 - pages/other-languages/[romanian]-rlp.md | 62 - .../other-languages/[romanian]-white-paper.md | 559 ---- .../other-languages/[spanish]-ethereum-toc.md | 24 - ...6\207]-Serpent\346\214\207\345\215\227.md" | 487 ---- ...45\235\212Wiki\347\233\256\345\275\225.md" | 11 - ...00\345\217\221\350\256\241\345\210\222.md" | 278 -- ...12\346\234\257\350\257\255\350\241\250.md" | 128 - ...12\347\231\275\347\232\256\344\271\246.md" | 475 ---- ...346\230\216\346\251\237\345\210\266FAQ.md" | 239 -- ...21\347\273\234\347\212\266\346\200\201.md" | 93 - ...\262\320\276-\320\277\320\276-Solidity.md" | 1256 --------- pages/swarm/Swarm-Hash.md | 42 - pages/whisper/Whisper-Overview.md | 112 - pages/whisper/Whisper-PoC-2-Protocol-Spec.md | 141 - pages/whisper/Whisper-PoC-2-Wire-Protocol.md | 57 - pages/whisper/Whisper-Wire-Protocol.md | 23 - pages/whisper/Whisper.md | 63 - pages/white-paper/[english]-white-paper.md | 500 ---- 168 files changed, 31945 deletions(-) delete mode 100644 drafts/[english]-old-ethereum-whitepaper.md delete mode 100644 drafts/[english]-patricia-tree-draft.md delete mode 100644 images/natspec1.png delete mode 100644 images/natspec2.png delete mode 100644 images/natspec3.png delete mode 100644 images/natspec4.png delete mode 100644 images/natspec5.png delete mode 100644 pages/Licensing.md delete mode 100644 pages/Middleware-and-Dapp-Project-Ideas.md delete mode 100644 pages/Open-job-positions-&-Schemes.md delete mode 100644 pages/_Sidebar.md delete mode 100644 pages/blog-and-notes/Fortnight-In-Ethereum-Template.md delete mode 100644 pages/blog-and-notes/Template:-This-Week-in-Ethereum-w-YY.md delete mode 100644 pages/blog-and-notes/This Week In Ethereum 47.2014.md delete mode 100644 pages/blog-and-notes/Todo-before-alpha.md delete mode 100644 pages/blog-and-notes/stubs/Which-Client?.md delete mode 100644 pages/dapp-development/Contract-Metadata-Docs-(NatSpec,-ABI).md delete mode 100644 pages/dapp-development/Dapp-Developer-Resources.md delete mode 100644 pages/dapp-development/Dapp-using-Meteor.md delete mode 100644 pages/dapp-development/Ethereum-Contract-ABI.md delete mode 100644 pages/dapp-development/Ethereum-Development-Tutorial.md delete mode 100644 pages/dapp-development/First-steps-with-ethereum-JSON-RPC.md delete mode 100644 pages/dapp-development/JSON-RPC.md delete mode 100644 pages/dapp-development/JavaScript-API.md delete mode 100644 pages/dapp-development/Javascript-Development-Deficiencies.md delete mode 100644 pages/dapp-development/Mix-Features.md delete mode 100644 pages/dapp-development/Mix:-The-DApp-IDE.md delete mode 100644 pages/dapp-development/RPC-Testing.md delete mode 100644 pages/dapp-development/Standardized_Contract_APIs.md delete mode 100644 "pages/dapp-development/Useful-\303\220app-Patterns.md" delete mode 100644 pages/dapp-development/serpent/Serpent-1.0-(old).md delete mode 100644 pages/dapp-development/serpent/Serpent.md delete mode 100644 pages/dapp-development/serpent/Serpent_3.0.md delete mode 100644 pages/dapp-development/solidity/Solidity,-Docs-and-ABI.md delete mode 100644 pages/dapp-development/solidity/Solidity-Changelog.md delete mode 100644 pages/dapp-development/solidity/Solidity-Features.md delete mode 100644 pages/dapp-development/solidity/Solidity-Tutorial.md delete mode 100644 pages/dapp-development/solidity/Solidity-standard-library.md delete mode 100644 pages/dapp-development/solidity/Solidity.md delete mode 100644 pages/dapp-development/solidity/Tags-for-Solidity-in-code-documentation.md delete mode 100644 pages/dapp-development/solidity/The-Solidity-Programming-Language.md delete mode 100644 pages/design-rationale/[english]-design-rationale.md delete mode 100644 pages/dev-technologies/Node-discovery-protocol.md delete mode 100644 pages/dev-technologies/Web3-Secret-Storage-Definition.md delete mode 100644 pages/dev-technologies/enode-url-format.md delete mode 100644 pages/dev-technologies/libp2p-Whitepaper.md delete mode 100644 pages/dev-technologies/web.js-0.9.md delete mode 100644 "pages/dev-technologies/\303\220\316\236Vp2p-Wire-Protocol.md" delete mode 100644 pages/eip/Geth-Dapp-loading-proposal.md delete mode 100644 pages/eip/JSON-RPC-Error-Codes-Improvement-Proposal.md delete mode 100644 pages/eip/Mix-improvement-proposal.md delete mode 100644 pages/eip/Proposal:-BlockHashesFromNumbers.md delete mode 100644 pages/eip/Proposal:-Extend-GetBlockHashes-with-target-hash.md delete mode 100644 pages/eip/Proposal:-NewBlockHashes.md delete mode 100644 pages/eip/Proposal:-Reversion-Notification.md delete mode 100644 pages/eip/Proposal:-Transaction-Proxy-Hooks.md delete mode 100644 pages/eip/newBlockFilter-Improvement-Proposal.md delete mode 100644 pages/eip/sendTransaction-return-value-proposal.md delete mode 100644 pages/ethash-dagger-hashimoto/Dagger-Hashimoto.md delete mode 100644 pages/ethash-dagger-hashimoto/Dagger.md delete mode 100644 pages/ethash-dagger-hashimoto/Ethash-C-API.md delete mode 100644 pages/ethash-dagger-hashimoto/Ethash-DAG-Disk-Storage-Format.md delete mode 100644 pages/ethash-dagger-hashimoto/Ethash-Design-Rationale.md delete mode 100644 pages/ethash-dagger-hashimoto/Ethash.md delete mode 100644 pages/ethash-dagger-hashimoto/Ethash_revision_11.md delete mode 100644 pages/ethereum-and-blockchain-technologies-and-research/Bad-Block-Reporting.md delete mode 100644 pages/ethereum-and-blockchain-technologies-and-research/Bad-Chain-Canary.md delete mode 100644 pages/ethereum-and-blockchain-technologies-and-research/Block-Protocol-2.0.md delete mode 100644 pages/ethereum-and-blockchain-technologies-and-research/Blockchain-import-and-export-instructions.md delete mode 100644 pages/ethereum-and-blockchain-technologies-and-research/Distributed-Preimage-Archive.md delete mode 100644 pages/ethereum-and-blockchain-technologies-and-research/EVM-Subtleties.md delete mode 100644 pages/ethereum-and-blockchain-technologies-and-research/Ethereum-Natural-Specification-Format.md delete mode 100644 pages/ethereum-and-blockchain-technologies-and-research/Ethereum-Wire-Protocol.md delete mode 100644 pages/ethereum-and-blockchain-technologies-and-research/Light-client-protocol.md delete mode 100644 pages/ethereum-and-blockchain-technologies-and-research/Morden.md delete mode 100644 pages/ethereum-and-blockchain-technologies-and-research/[english]-patricia-tree.md delete mode 100644 pages/ethereum-and-blockchain-technologies-and-research/[english]-rlp.md delete mode 100644 pages/ethereum-and-blockchain-technologies-and-research/research/CLL.md delete mode 100644 pages/ethereum-and-blockchain-technologies-and-research/research/Chain-Fibers-Redux.md delete mode 100644 pages/ethereum-and-blockchain-technologies-and-research/research/Generalized_Merkle_DHT.md delete mode 100644 pages/ethereum-and-blockchain-technologies-and-research/research/HPOC_2015.md delete mode 100644 pages/ethereum-and-blockchain-technologies-and-research/research/Parallel-Block-Downloads.md delete mode 100644 pages/ethereum-and-blockchain-technologies-and-research/research/Problems.md delete mode 100644 pages/ethereum-and-blockchain-technologies-and-research/research/Security-Categorization.md delete mode 100644 pages/ethereum-and-blockchain-technologies-and-research/research/Security-Issue-Process.md delete mode 100644 pages/ethereum-and-blockchain-technologies-and-research/research/Serenity_Wishlist.md delete mode 100644 pages/infrastructure-networking/Adaptive-Message-IDs.md delete mode 100644 pages/infrastructure-networking/Adaptive-Peer-Time.md delete mode 100644 pages/infrastructure-networking/Brain-Wallet.md delete mode 100644 pages/infrastructure-networking/Clearinghouse.md delete mode 100644 pages/infrastructure-networking/Default-Extra-Data-Standard.md delete mode 100644 pages/infrastructure-networking/Deterministic_Wallet_Spec.md delete mode 100644 pages/infrastructure-networking/EVM-JIT-Binary-Interface.md delete mode 100644 "pages/infrastructure-networking/Ethereum-Raspberry-Pi-e\317\200-Programme.md" delete mode 100644 pages/infrastructure-networking/Exchange-Integration.md delete mode 100644 pages/infrastructure-networking/ICAP:-Inter-exchange-Client-Address-Protocol.md delete mode 100644 pages/infrastructure-networking/IPv6.md delete mode 100644 pages/infrastructure-networking/Kademlia-Peer-Selection.md delete mode 100644 pages/infrastructure-networking/Layers.md delete mode 100644 pages/infrastructure-networking/Mining.md delete mode 100644 pages/infrastructure-networking/NatSpec-Determination.md delete mode 100644 pages/infrastructure-networking/Natspec-Example.md delete mode 100644 pages/infrastructure-networking/Network-Status.md delete mode 100644 pages/infrastructure-networking/NewBlock-Message.md delete mode 100644 pages/infrastructure-networking/Raspberry-Pi-instructions.md delete mode 100644 pages/infrastructure-networking/Registrar-ABI.md delete mode 100644 pages/infrastructure-networking/URL-Hint-Protocol.md delete mode 100644 pages/introduction/Decentralized-apps-(dapps).md delete mode 100644 pages/introduction/Ethereum-introduction.md delete mode 100644 pages/introduction/FAQ.md delete mode 100644 pages/introduction/Gitter-Channels.md delete mode 100644 pages/introduction/Glossary.md delete mode 100644 pages/introduction/Home.md delete mode 100644 pages/introduction/What-is-Ethereum.md delete mode 100644 pages/other-languages/[German]-Clearinghaus.md delete mode 100644 pages/other-languages/[Italian]-Impostare-il-proprio-ambiente-di-sviluppo-Ethereum.md delete mode 100644 pages/other-languages/[Italian]-Introduzione-allo-sviluppo-su-Ethereum.md delete mode 100644 pages/other-languages/[Italian]-Libro-Bianco.md delete mode 100644 pages/other-languages/[Japanese]-Cryptocurrency-Current-Problems.md delete mode 100644 pages/other-languages/[Japanese]-Ethereum-Development-Tutorial.md delete mode 100644 pages/other-languages/[Japanese]-Ethereum-TOC.md delete mode 100644 pages/other-languages/[Japanese]-HPOC_2015.md delete mode 100644 pages/other-languages/[Japanese]-Javascript-API.md delete mode 100644 pages/other-languages/[Japanese]-License.md delete mode 100644 pages/other-languages/[Japanese]-Solidity-Tutorial.md delete mode 100644 "pages/other-languages/[Japanese]-Whisper-\357\274\210\343\202\246\343\202\243\343\202\271\343\203\221\343\203\274\357\274\211.md" delete mode 100644 pages/other-languages/[Japenese]-Ethereum-TOC.md delete mode 100644 pages/other-languages/[Persian]-Ethereum-TOC.md delete mode 100644 pages/other-languages/[Romanian]-Block-Protocol-2.0.md delete mode 100644 pages/other-languages/[Romanian]-CLL.md delete mode 100644 pages/other-languages/[Romanian]-Cuprins.md delete mode 100644 pages/other-languages/[Romanian]-Dagger.md delete mode 100644 pages/other-languages/[Romanian]-Layers.md delete mode 100644 pages/other-languages/[Romanian]-Limbajul-de-programare-Serpent.md delete mode 100644 pages/other-languages/[Romanian]-Wire-Protocol.md delete mode 100644 pages/other-languages/[chinese]-ethereum-toc.md delete mode 100644 pages/other-languages/[chinese]-rlp.md delete mode 100644 pages/other-languages/[chinese]-white-paper.md delete mode 100644 pages/other-languages/[french]-ethereum-toc.md delete mode 100644 pages/other-languages/[german]-ethereum-toc.md delete mode 100644 pages/other-languages/[german]-rlp.md delete mode 100644 pages/other-languages/[german]-white-paper.md delete mode 100644 pages/other-languages/[italian]-ethereum-toc.md delete mode 100644 pages/other-languages/[japanese]-design-rationale.md delete mode 100644 pages/other-languages/[japanese]-patricia-tree.md delete mode 100644 pages/other-languages/[japanese]-rlp.md delete mode 100644 pages/other-languages/[japanese]-white-paper.md delete mode 100644 pages/other-languages/[korean]-white-paper.md delete mode 100644 pages/other-languages/[persian]-white-paper.md delete mode 100644 pages/other-languages/[romanian]-patricia-tree.md delete mode 100644 pages/other-languages/[romanian]-rlp.md delete mode 100644 pages/other-languages/[romanian]-white-paper.md delete mode 100644 pages/other-languages/[spanish]-ethereum-toc.md delete mode 100644 "pages/other-languages/[\344\270\255\346\226\207]-Serpent\346\214\207\345\215\227.md" delete mode 100644 "pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212Wiki\347\233\256\345\275\225.md" delete mode 100644 "pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\345\274\200\345\217\221\350\256\241\345\210\222.md" delete mode 100644 "pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\346\234\257\350\257\255\350\241\250.md" delete mode 100644 "pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\347\231\275\347\232\256\344\271\246.md" delete mode 100644 "pages/other-languages/[\344\270\255\346\226\207]-\346\254\212\347\233\212\350\255\211\346\230\216\346\251\237\345\210\266FAQ.md" delete mode 100644 "pages/other-languages/[\344\270\255\346\226\207]-\347\275\221\347\273\234\347\212\266\346\200\201.md" delete mode 100644 "pages/other-languages/\320\240\321\203\320\272\320\276\320\262\320\276\320\264\321\201\321\202\320\262\320\276-\320\277\320\276-Solidity.md" delete mode 100644 pages/swarm/Swarm-Hash.md delete mode 100644 pages/whisper/Whisper-Overview.md delete mode 100644 pages/whisper/Whisper-PoC-2-Protocol-Spec.md delete mode 100644 pages/whisper/Whisper-PoC-2-Wire-Protocol.md delete mode 100644 pages/whisper/Whisper-Wire-Protocol.md delete mode 100644 pages/whisper/Whisper.md delete mode 100644 pages/white-paper/[english]-white-paper.md diff --git a/drafts/[english]-old-ethereum-whitepaper.md b/drafts/[english]-old-ethereum-whitepaper.md deleted file mode 100644 index 939ca7ff1..000000000 --- a/drafts/[english]-old-ethereum-whitepaper.md +++ /dev/null @@ -1,639 +0,0 @@ ---- -name: Old Ethereum Whitepaper -category: ---- - -### A Next-Generation Smart Contract and Decentralized Application Platform - -In the last few months, there has been a great amount of interest into the area of using Bitcoin-like blockchains - the mechanism that allows for the entire world to agree on the state of a public ownership database - for more than just money. Commonly cited applications include using on-blockchain digital assets to represent custom currencies and financial instruments (["colored coins"](https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit)), ["smart property"](https://en.bitcoin.it/wiki/Smart_Property) devices such as cars which track a colored coin on a blockchain to determine their present legitimate owner, as well as more advanced applications such as decentralized exchange, financial derivatives, peer-to-peer gambling and on-blockchain identity and reputation systems. Perhaps the most ambitious of all cited applications is the concept of autonomous agents or [decentralized autonomous organizations](http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/) (DAOs) - autonomous entities that operate on the blockchain without any central control whatsoever, eschewing all dependence on legal contracts and organizational bylaws in favor of having resources and funds autonomously managed by a self-enforcing smart contract on a cryptographic blockchain. - -However, most of these applications are difficult to implement today, simply because the scripting systems of Bitcoin, and even next-generation cryptocurrency protocols such as the Bitcoin-based colored coins protocol and so-called "metacoins", are far too limited to allow the kind of arbitrarily complex computation that DAOs require. What this project intends to do is take the innovations that such protocols bring, and generalize them - create a fully-fledged, Turing-complete (but heavily fee-regulated) cryptographic ledger that allows participants to encode arbitrarily complex contracts, autonomous agents and relationships that will be mediated entirely by the blockchain. Rather than being limited to a specific set of transaction types, users will be able to use Ethereum as a sort of "Lego of crypto-finance" - that is to say, one will be able to implement any feature that one desires simply by coding it in the protocol's internal scripting language. Custom currencies, financial derivatives, identity systems and decentralized organizations will all be easy to do, but more importantly, unlike previous systems, it will also be possible to construct transaction types that even the Ethereum developers did not imagine. Altogether, we believe that this design is a solid step toward the realization of "cryptocurrency 2.0"; we hope that Ethereum will be as significant an addition to the cryptocurrency ecosystem as the advent of Web 2.0 was to the static-content-only internet of 1999. - - -### Table of Contents - -* [Why A New Platform](#why-a-new-platform) - * [Colored Coins](#colored-coins) - * [Metacoins](#metacoins) -* [Philosophy](#philosophy) -* [Basic Building Blocks](#basic-building-blocks) - * [Modified GHOST Implementation](#modified-ghost-implementation) - * [Ethereum Client P2P Protocol](#ethereum-client-p2p-protocol) - * [Currency and Issuance](#currency-and-issuance) - * [Data Format](#data-format) - * [Mining Algorithm](#mining-algorithm) - * [Transactions](#transactions) - * [Difficulty Adjustment](#difficulty-adjustment) - * [Block Rewards and Limits](#block-rewards-and-limits) -* [Contracts](#contracts) - * [Applications](#applications) - * [Sub-currencies](#sub-currencies) - * [Financial derivatives](#financial-derivatives) - * [Identity and Reputation Systems](#identity-and-reputation-systems) - * [Decentralized File Storage](#decentralized-file-storage) - * [Decentralized Autonomous Organizations](#decentralized-autonomous-organizations) - * [Further Applications](#further-applications) - * [How Do Contracts Work?](#how-do-contracts-work) - * [Language Specification](#language-specification) -* [Fees](#fees) -* [Conclusion](#conclusion) -* [References and Further Reading](#references-and-further-reading) - - -## Why A New Platform? - -When one wants to create a new application, especially in an area as delicate as cryptography or cryptocurrency, the immediate, and correct, first instinct is to use existing protocols as much as possible. There is no need to create a new currency, or even a new protocol, when the problem can be solved entirely by using existing technologies. Indeed, the puzzle of attempting to solve the problems of [smart property](https://en.bitcoin.it/wiki/Smart_Property), [smart contracts](https://en.bitcoin.it/wiki/Contracts) and [decentralized autonomous corporations](http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/) on top of Bitcoin is how our interest in next-generation cryptocurrency protocols originally started. Over the course of our research, however, it became evident that while the Bitcoin protocol is more than adequate for currency, basic multisignature escrow and certain simple versions of smart contracts, there are fundamental limitations that make it non-viable for anything beyond a certain very limited scope of features. - - -### Colored Coins - -The first attempt to implement a system for managing smart property and custom currencies and assets on top of a blockchain was built as a sort of overlay protocol on top of Bitcoin, with many advocates making a comparison to the way that, in the [internet protocol stack](http://en.wikipedia.org/wiki/Internet_protocol_suite), [HTTP](http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol) serves as a layer on top of [TCP](http://en.wikipedia.org/wiki/Transmission_Control_Protocol). The [colored coins](https://docs.google.com/a/ursium.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit) protocol is roughly defined as follows: - -1. A colored coin issuer determines that a given transaction output H:i (H being the transaction hash and `i` the output index) represents a certain asset, and publishes a "color definition" specifying this transaction output alongside what it represents (eg. 1 satoshi from `H:i` = 1 ounce of gold redeemable at Stephen's Gold Company) -2. Others "install" the color definition file in their colored coin clients. -3. When the color is first released, output H:i is the only transaction output to have that color. -4. If a transaction spends inputs with color X, then its outputs will also have color X. For example, if the owner of H:i immediately makes a transaction to split that output among five addresses, then those transaction outputs will all also have color X. If a transaction has inputs of different colors, then a "color transfer rule" or "color kernel" determines which colors which outputs are (eg. a very naive implementation may say that output 0 has the same color as input 0, output 1 the same color as input 1, etc). -5. When a colored coin client notices that it received a new transaction output, it uses a back-tracing algorithm based on the color kernel to determine the color of the output. Because the rule is deterministic, all clients will agree on what color (or colors) each output has. - -However, the protocol has several fundamental flaws: - - -**Simplified Payment Verification in Bitcoin ** - -![SPV in bitcoin](https://www.ethereum.org/gh_wiki/spv_bitcoin.png) - -_Left: it suffices to present only a small number of nodes in a Merkle tree to give a proof of the validity of a branch._ - -_Right: any attempt to change any part of the Merkle tree will eventually lead to an inconsistency somewhere up the chain._ - - -1. **Difficulty of simplified payment verification** - Bitcoin's [Merkle Tree](http://en.wikipedia.org/wiki/Merkle_tree) construction allows for a protocol known as "[simplified payment verification](https://en.bitcoin.it/wiki/Scalability#Simplified_payment_verification)", where a client that does not download the full blockchain can quickly determine the validity of a transaction output by asking other nodes to provide a cryptographic proof of the validity of a single branch of the tree. The client will still need to download the block headers to be secure, but the amount of data bandwidth and verification time required drops by a factor of nearly a thousand. With colored coins, this is much harder. The reason is that one cannot determine the color of a transaction output simply by looking up the Merkle tree; rather, one needs to employ the backward scanning algorithm, fetching potentially thousands of transactions and requesting a Merkle tree validity proof of each one, before a client can be fully satisfied that a transaction has a certain color. After over a year of investigation, including help from ourselves, no solution has been found to this problem. -2. **Incompatibility with scripting** - as mentioned above, Bitcoin does have a moderately flexible scripting system, for example allowing users to sign transactions of the form "I release this transaction output to anyone willing to pay to me 1 BTC". Other examples include [assurance contracts](http://en.wikipedia.org/wiki/Assurance_contract), [efficient micropayments](https://en.bitcoin.it/wiki/Contracts#Example_7:_Rapidly-adjusted_.28micro.29payments_to_a_pre-determined_party) and on-blockchain auctions. However, this system is inherently not color-aware; that is to say, one cannot make a transaction of the form "I release this transaction output to anyone willing to pay me one gold coin defined by the genesis H:i", because the scripting language has no idea that a concept of "colors" even exists. One major consequence of this is that, while trust-free swapping of two different colored coins is possible, a full decentralized exchange is not since there is no way to place an enforceable order to buy or sell. -3. **Same limitations as Bitcoin** - ideally, on-blockchain protocols would be able to support advanced derivatives, bets and many forms of conditional transfers. Unfortunately, colored coins inherits the limitations of Bitcoin in terms of the impossibility of many such arrangements. - -### Metacoins - -Another concept, once again in the spirit of sitting on top of Bitcoin much like HTTP over TCP, is that of "metacoins". The concept of a metacoin is simple: the metacoin protocol provides for a way of encoding metacoin transaction data into the outputs of a Bitcoin transaction, and a metacoin node works by processing all Bitcoin transactions and evaluating Bitcoin transactions that are valid metacoin transactions in order to determine the current account balances at any given time. For example, a simple metacoin protocol might require a transaction to have four outputs: MARKER, FROM, TO and VALUE. MARKER would be a specific marker address to identify a transaction as a metacoin transaction. FROM would be the address that coins are sent from. `TO` would be the address that coins are sent to, and VALUE would be an address encoding the amount sent. Because the Bitcoin protocol is not metacoin-aware, and thus will not reject invalid metacoin transactions, the metacoin protocol must treat all transactions with the first output going to MARKER as valid and react accordingly. For example, an implementation of the transaction processing part of the above described metacoin protocol might look like this: - - if tx.output[0] != MARKER: - break - else if balance[tx.output[1]] < decode_value(tx.output[3]): - break - else if not tx.hasSignature(tx.output[1]): - break - else: - balance[tx.output[1]] -= decode_value(tx.output[3]); - balance[tx.output[2]] += decode_value(tx.output[3]); - - -The advantage of a metacoin protocol is that the protocol can allow for more advanced transaction types, including custom currencies, decentralized exchange, derivatives, etc, that are impossible to implement using the underlying Bitcoin protocol by itself. However, metacoins on top of Bitcoin have one major flaw: simplified payment verification, already difficult with colored coins, is outright impossible on a metacoin. The reason is that while one can use SPV to determine that there is a transaction sending 30 metacoins to address X, that by itself does not mean that address X has 30 metacoins. What if the sender of the transaction did not have 30 metacoins to start with and so the transaction is invalid? Ultimately, finding out any part of the current state requires scanning through all transactions since the metacoin's original launch to figure out which transactions are valid and which ones are not. This makes it impossible to have a truly secure client without downloading the entire, arguably prohibitively large, Bitcoin blockchain. - -In both cases, the conclusion is as follows. The effort to build more advanced protocols on top of Bitcoin, like HTTP over TCP, is admirable, and is indeed the correct way to go in terms of implementing advanced decentralized applications. However, the attempt to build colored coins and metacoins on top of Bitcoin is more like building HTTP over SMTP. The intention of SMTP was to transfer email messages, not serve as a backbone for generic internet communications, and one would have had to implement many inefficient and architecturally ugly practices in order to make it effective. Similarly, while Bitcoin is a great protocol for making simple transactions and storing value, the evidence above shows that Bitcoin is absolutely not intended to function, and cannot function, as a base layer for financial peer-to-peer protocols in general. - -Ethereum solves the scalability issues by being hosted on its own blockchain, and by storing a distinct "state tree" in each block along with a transaction list. Each "state tree" represents the current state of the entire system, including address balances and contract states. Ethereum contracts are allowed to store data in a persistent memory storage. This storage, combined with the Turing-complete scripting language, allows us to encode an entire currency inside of a single contract, alongside countless other types of cryptographic assets. Thus, the intention of Ethereum is not to replace the colored coins and metacoin protocols described above. Rather, Ethereum intends to serve as a superior foundational layer offering a uniquely powerful scripting system on top of which arbitrarily advanced contracts, currencies and other decentralized applications can be built. If existing colored coins and metacoin projects were to move onto Ethereum, they would gain the benefits of Ethereum's simplified payment verification, the option to be compatible with Ethereum's financial derivatives and decentralized exchange, and the ability to work together on a single network. With Ethereum, someone with an idea for a new contract or transaction type that might drastically improve the state of what can be done with cryptocurrency would not need to start their own coin; they could simply implement their idea in Ethereum script code. In short, Ethereum is a foundation for innovation. - - -## Philosophy - -The design behind Ethereum is intended to follow the following principles: - -1. **Simplicity** - the Ethereum protocol should be as simple as possible, even at the cost of some data storage or time inefficiency. An average programmer should ideally be able to follow and implement the entire specification, so as to fully realize the unprecedented democratizing potential that cryptocurrency brings and further the vision of Ethereum as a protocol that is open to all. Any optimization which adds complexity should not be included unless that optimization provides very substantial benefit. -2. **Universality** - a fundamental part of Ethereum's design philosophy is that Ethereum does not have "features". Instead, Ethereum provides an internal Turing-complete scripting language, which a programmer can use to construct any smart contract or transaction type that can be mathematically defined. Want to invent your own financial derivative? With Ethereum, you can. Want to make your own currency? Set it up as an Ethereum contract. Want to set up a full-scale Daemon or Skynet? You may need to have a few thousand interlocking contracts, and be sure to feed them generously, to do that, but nothing is stopping you with Ethereum at your fingertips. -3. **Modularity** - the parts of the Ethereum protocol should be designed to be as modular and separable as possible. Over the course of development, our goal is to create a program where if one was to make a small protocol modification in one place, the application stack would continue to function without any further modification. Innovations such as [Dagger](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Dagger), [Patricia trees](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree) and [RLP](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP) should be implemented as separate libraries and made to be feature-complete even if Ethereum does not require certain features so as to make them usable in other protocols as well. Ethereum development should be maximally done so as to benefit the entire cryptocurrency ecosystem, not just itself. -4. **Agility** - details of the Ethereum protocol are not set in stone. Although we will be extremely judicious about making modifications to high-level constructs such as the [C-like language](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-CLL) and the address system, computational tests later on in the development process may lead us to discover that certain modifications to the algorithm or scripting language will substantially improve scalability or security. If any such opportunities are found, we will exploit them. -5. **Non-discrimination** - the protocol should not attempt to actively restrict or prevent specific categories of usage. All regulatory mechanisms in the protocol should be designed to directly regulate the harm and not attempt to oppose specific undesirable applications. A programmer can even run an infinite loop script on top of Ethereum for as long as they are willing to keep paying the per-computational-step transaction fee. - - -## Basic Building Blocks - -At its core, Ethereum starts off as a fairly regular memory-hard proof-of-work mined cryptocurrency without many extra complications. In fact, Ethereum is in some ways simpler than the Bitcoin-based cryptocurrencies that we use today. The concept of a transaction having multiple inputs and outputs, for example, is gone, replaced by a more intuitive balance-based model (to prevent transaction replay attacks, as part of each account balance we also store an incrementing nonce). Sequence numbers and lock times are also removed, and all transaction and block data is encoded in a single format. Instead of addresses being the RIPEMD160 hash of the SHA256 hash of the public key prefixed with 04, addresses are simply the last 20 bytes of the SHA3 hash of the public key. Unlike other cryptocurrencies, which aim to offer a large number of "features", Ethereum intends to take features away, and instead provide its users with near-infinite power through an all-encompassing mechanism known as "contracts". - -### Modified GHOST Implementation - -The "Greedy Heavist Observed Subtree" (GHOST) protocol is an innovation first introduced by Yonatan Sompolinsky and Aviv Zohar in [December 2013](http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf). The motivation behind GHOST is that blockchains with fast confirmation times currently suffer from reduced security due to a high stale rate - because blocks take a certain time to propagate through the network, if miner A mines a block and then miner B happens to mine another block before miner A's block propagates to B, miner B's block will end up wasted and will not contribute to network security. Furthermore, there is a centralization issue: if miner A is a mining pool with 30% hashpower and B has 10% hashpower, A will have a risk of producing stale blocks 70% of the time whereas B will have a risk of producing stale blocks 90% of the time. Thus, if the stale rate is high, A will be substantially more efficient simply by virtue of its size. With these two effects combined, blockchains which produce blocks quickly are very likely to lead to one mining pool having a large enough percentage of the network hashpower to have de facto control over the mining process. - -As described by Sompolinsky and Zohar, GHOST solves the first issue of network security loss by including stale blocks in the calculation of which chain is the "longest"; that is to say, not just the parent and further ancestors of a block, but also the stale descendants of the block's ancestor (in Ethereum jargon, "uncles") are added to the calculation of which block has the largest total proof of work backing it. To solve the second issue of centralization bias, we go beyond the protocol described by Sompolinsky and Zohar, and also provide block rewards to stales: a stale block receives 87.5% of its base reward, and the nephew that includes the stale block receives the remaining 12.5%. Transaction fees, however, are not awarded to uncles. - -Ethereum implements a simplified version of GHOST which only goes down one level. Specifically, a stale block can only be included as an uncle by the direct child of one of its direct siblings, and not any block with a more distant relation. This was done for several reasons. First, unlimited GHOST would include too many complications into the calculation of which uncles for a given block are valid. Second, unlimited GHOST with compensation as used in Ethereum removes the incentive for a miner to mine on the main chain and not the chain of a public attacker. Finally, calculations show that single-level GHOST has over 80% of the benefit of unlimited GHOST, and provides a stale rate comparable to the 2.5 minute Litecoin even with a 40-second block time. However, we will be conservative and still retain a Primecoin-like 60-second block time because individual blocks may take a longer time to verify. - - -### Ethereum Client P2P Protocol - -**P2P Protocol** -![SPV in bitcoin](https://www.ethereum.org/gh_wiki/minerchart.png) - -The Ethereum client P2P protocol is a fairly standard cryptocurrency protocol, and can just as easily be used for any other cryptocurrency; the only modification is the introduction of the GHOST protocol described above. The Ethereum client will be mostly reactive; if not provoked, the only thing the client will do by itself is have the networking daemon maintain connections and periodically send a message asking for blocks whose parent is the current block. However, the client will also be more powerful. Unlike bitcoind, which only stores a limited amount of data about the blockchain, the Ethereum client will also act as a fully functional backend for a block explorer. - -When the client reads a message, it will perform the following steps: - -1. Hash the data, and check if the data with that hash has already been received. If so, exit. -2. Determine the data type. If the data is a transaction, if the transaction is valid add it to the local transaction list, process it onto the current block and publish it to the network. If the data item is a message, respond to it. If the data item is a block, go to step 3. -3. Check if the parent of the block is already stored in the database. If it is not, exit. -4. Check if the proof of work on the block header and all block headers in the "uncle list" is valid. If any are not, exit. -5. Check if every block header in the "uncle list" in the block has the block's parent's parent as its own parent. If any is not, exit. Note that uncle block headers do not need to be in the database; they just need to have the correct parent and a valid proof of work. Also, make sure that uncles are unique and distinct from the parent. -6. Check if the timestamp of the block is at most 15 minutes into the future and that it is ahead of the timestamp of the parent. Check if the difficulty of the block and the block number are correct. If either of these checks fails, exit. -7. Start with the state of the parent of the block, and sequentially apply every transaction in the block to it. At the end, add the miner rewards. If the root hash of the resulting state tree does not match the state root in the block header, exit. If it does, add the block to the database and advance to the next step. -8. Determine TD(block) ("total difficulty") for the new block. TD is defined recursively by TD(genesis_block) = 0 and TD(B) = TD(B.parent) + sum([u.difficulty for u in B.uncles]) + B.difficulty. If the new block has higher TD than the current block, set the current block to the new block and continue to the next step. Otherwise, exit. -9. If the new block was changed, apply all transactions in the transaction list to it, discarding from the transaction list any that turn out to be invalid, and rebroadcast the block and those transactions to the network. - -The "current block" is a pointer maintained by each node that refers to the block that the node deems as representing the current official state of the network. All messages asking for balances, contract states, etc, have their responses computed by looking at the current block. If a node is mining, the process is only slightly changed: while doing all of the above, the node also continuously mines on the current block, using its transaction list as the transaction list of the block. - - -### Currency and Issuance - -The Ethereum network includes its own built-in currency, ether. The main reason for including a currency in the network is twofold. First, like Bitcoin, ether is rewarded to miners so as to incentivize network security. Second, it serves as a mechanism for paying transaction fees for anti-spam purposes. Of the two main alternatives to fees, per-transaction proof of work similar to [Hashcash](http://en.wikipedia.org/wiki/Hashcash) and zero-fee laissez-faire, the former is wasteful of resources and unfairly punitive against weak computers and smartphones and the latter would lead to the network being almost immediately overwhelmed by an infinitely looping "logic bomb" contract. For convenience and to avoid future argument (see the current mBTC/uBTC/satoshi debate), the denominations will be pre-labelled: - -* 1: wei -* 10^3: lovelace -* 10^6: babbage -* 10^9: turing -* 10^12: szabo -* 10^15: finney -* 10^18: ether - -This should be taken as an expanded version of the concept of "dollars" and "cents" or "BTC" and "satoshi" that is intended to be future proof. In the near future, we expect "ether" to be the primary unit in the system, much like the dollar or bitcoin; "finney" will likely be used for microtransactions, "szabo" for per-step fees and "wei" to refer specifically to the lowest-level "base" unit much like the satoshi in Bitcoin. The remaining denominations will likely only come into play if Ethereum grows much larger or computers get much more efficient and it makes sense to use lower units than szabo to measure fees. - -The issuance model will be as follows: - -* Ether will be released in a fundraiser at the price of 1000-2000 ether per BTC, with earlier funders getting a better price to compensate for the increased uncertainty of participating at an earlier stage. The minimum funding amount will be 0.01 BTC. Suppose that X ether gets released in this way -* 0.225X ether will be allocated to the fiduciary members and early contributors who substantially participated in the project before the start of the fundraiser. This share will be stored in a time-lock contract; about 40% of it will be spendable after one year, 70% after two years and 100% after 3 years. -* 0.05X ether will be allocated to a fund to use to pay expenses and rewards in ether between the start of the fundraiser and the launch of the currency -* 0.225X ether will be allocated as a long-term reserve pool to pay expenses, salaries and rewards in ether after the launch of the currency -* 0.4X ether will be mined per year forever after that point - - -| Group | After 1 year | After 5 years -| ------------- | ------------- |-------------| -| Currency units | 1.9X | 3.5X | -| Fundraiser participants | 52.6% | 28.6% | -| Fiduciary members and early contributors | 11.8% | 6.42% | -| Additional pre-launch allocations | 2.63% | 1.42% | -| Reserve | 11.8% | 6.42% | -| Miners | 21.1% | 57.1% | - - -**Long-Term Inflation Rate (percent)** - -![SPV in bitcoin](https://www.ethereum.org/gh_wiki/inflation.svg) - -_Despite the linear currency issuance, just like with Bitcoin over time the inflation rate nevertheless tends to zero_ - - -For example, after five years and assuming no transactions, 28.6% of the ether will be in the hands of the fundraiser participants, 6.42% in the fiduciary member and early contributor pool, 6.42% paid to the reserve pool, and 57.1% will belong to miners. The permanent linear inflation model reduces the risk of what some see as excessive wealth concentration in Bitcoin, and gives individuals living in present and future eras a fair chance to acquire currency units, while at the same time retaining a strong incentive to obtain and hold ether because the inflation "rate" still tends to zero over time (eg. during year 1000001 the money supply would increase from 500001.5 * X to 500002 * X, an inflation rate of 0.0001%). Furthermore, much of the interest in Ethereum will be medium-term; we predict that if Ethereum succeeds it will see the bulk of its growth on a 1-10 year timescale, and supply during that period will be very much limited. - -We also theorize that because coins are always lost over time due to carelessness, death, etc, and coin loss can be modeled as a percentage of the total supply per year, that the total currency supply in circulation will in fact eventually stabilize at a value equal to the annual issuance divided by the loss rate (eg. at a loss rate of 1%, once the supply reaches 40X then 0.4X will be mined and 0.4X lost every year, creating an equilibrium). - - -### Data Format - -All data in Ethereum will be stored in [recursive length prefix encoding](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP), which serializes arrays of strings of arbitrary length and dimension into strings. For example, ['dog', 'cat'] is serialized (in byte array format) as [ 130, 67, 100, 111, 103, 67, 99, 97, 116]; the general idea is to encode the data type and length in a single byte followed by the actual data (eg. converted into a byte array, 'dog' becomes [ 100, 111, 103 ], so its serialization is [ 67, 100, 111, 103 ]. Note that RLP encoding is, as suggested by the name, recursive; when RLP encoding an array, one is really encoding a string which is the concatenation of the RLP encodings of each of the elements. Additionally, note that block number, timestamp, difficulty, memory deposits, account balances and all values in contract storage are integers, and Patricia tree hashes, root hashes, addresses, transaction list hashes and all keys in contract storage are strings. The main difference between the two is that strings are stored as fixed-length data (20 bytes for addresses, 32 bytes for everything else), and integers take up only as much space as they need. Integers are stored in big-endian base 256 format (eg. 32767 in byte array format as [ 127, 255 ]). - -A full block is stored as: - - [ - block_header, - transaction_list, - uncle_list - ] - -Where: - - transaction_list = [ - transaction 1, - transaction 2, - ... - ] - - uncle list = [ - uncle_block_header_1, - uncle_block_header_2, - ... - ] - - block_header = [ - parent hash, - sha3(rlp_encode(uncle_list)), - coinbase address, - state_root, - sha3(rlp_encode(transaction_list)), - difficulty, - timestamp, - extra_data, - nonce - ] - -Each transaction and uncle block header is itself a list. The data for the proof of work is the RLP encoding of the block WITHOUT the nonce. `uncle_list` and `transaction_list` are the lists of the uncle block headers and transactions in the block, respectively. `nonce` and `extra_data` are both limited to a maximum of 32 bytes, except the genesis block where the `extra_data` parameter will be much larger. - -The `state_root` is the root of a [Merkle Patricia tree](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree) containing (key, value) pairs for all accounts where each address is represented as a 20-byte binary string. At the address of each account, the value stored in the Merkle Patricia tree is a string which is the RLP-serialized form of an object of the form: - - [ balance, nonce, contract_root ] - -The nonce is the number of transactions made from the account, and is incremented every time a transaction is made. The purpose of this is to (1) make each transaction valid only once to prevent replay attacks, and (2) to make it impossible (more precisely, cryptographically infeasible) to construct a contract with the same hash as a pre-existing contract. `balance` refers to the account's balance, denominated in wei. `contract_root` is the root of yet another Patricia tree, containing the contract's memory, if that account is controlled by a contract. If an account is not controlled by a contract, the contract root will simply be the empty string. - -### Mining algorithm - -One highly desirable property in mining algorithms is resistance to optimization through specialized hardware. Originally, Bitcoin was conceived as a highly democratic currency, allowing anyone to participate in the mining process with a CPU. In 2010, however, much faster miners exploiting the rapid parallelization offered by graphics processing units (GPUs) rapidly took over, increasing network hashpower by a factor of 100 and leaving CPUs essentially in the dust. In 2013, a further category of specialized hardware, application-specific integrated circuits (ASICs) outcompeted the GPUs in turn, achieving another 100x speedup by using chips fabricated for the sole purpose of computing SHA256 hashes. Today, it is virtually impossible to mine without first purchasing a mining device from one of these companies, and some people are concerned that in 5-10 years' time mining will be entirely dominated by large centralized corporations such as AMD and Intel. - -To date, the main way of achieving this goal has been "memory-hardness", constructing proof of work algorithms that require not only a large number of computations, but also a large amount of memory, to validate, thereby making highly parallelized specialized hardware implementations less effective. There have been several implementations of memory-hard proof of work, all of which have their flaws: - -* **Scrypt** - Scrypt is a function which is designed to take 128 KB of memory [to compute](https://litecoin.info/User:Iddo/Comparison_between_Litecoin_and_Bitcoin#SHA256_mining_vs_scrypt_mining). The algorithm essentially works by filling a memory array with hashes, and then computing intermediate values and finally a result based on the values in the memory array. However, the 128 KB parameter is a very weak threshold, and ASICs for Litecoin are [already under development](https://axablends.com/merchants-accepting-bitcoin/litecoin-discussion/litecoin-scrypt-asic-miners/). Furthermore, there is a natural limit to how much memory hardness with Scrypt can be tweaked up to achieve, as the verification process takes just as much memory, and just as much computation, as one round of the mining process. -* **Birthday attacks** - the idea behind birthday-based proofs of work is simple: find values xn, i, j such that i < k, j < k and abs(H(data+xn+i) - H(data+xn+j)) < 2^256 / d^2. The d parameter sets the computational difficulty of finding a block, and the k parameter sets the memory hardness. Any birthday algorithm must somehow store all computations of H(data+xn+i) in memory so that future computations can be compared against them. Here, computation is memory-hard, but verification is memory-easy, allowing for extreme memory hardness without compromising the ease of verification. However, the algorithm is problematic for two reasons. First, there is a time-memory tradeoff attack where users 2x less memory can compensate with 2x more computational power, so its memory hardness is not absolute. Second, it may be easy to build specialized hardware devices for the problem, especially once one moves beyond traditional chip and processor architecture and into various classes of hardware-based hash tables or probabilistic analog computing. -* **Dagger** - the idea behind [Dagger](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Dagger), an in-house algorithm developed by the Ethereum team, is to have an algorithm that is similar to Scrypt, but which is specially designed so that each individual nonce only depends on a small portion of the data tree that gets built up for each group of ~10 million nonces. Computing nonces with any reasonable level of efficiency requires building up the entire tree, taking up over 100 MB of memory, whereas verifying a nonce only takes about 100 KB. However, Dagger-style algorithms are vulnerable to devices that have multiple computational circuits sharing the same memory, and although this threat can be mitigated it is arguably impossible to fully remove. - -One of the key ingredients in a standard cryptocurrency is the idea of proof of work. A proof of work, in general, is a function which is hard to compute, but easy to verify, allowing it to serve as a probabilistic cryptographic proof of the quantity of computational resources controlled by a given node. In Bitcoin, and Ethereum, this mechanism is intimately tied in with the blockchain: every block requires a proof of work of some prespecified difficulty level in order to be valid, and in the event of multiple competing blockchains the chain with the largest total quantity of proof of work is considered to be valid. Thus, in order to reverse a transaction, an attacker needs to start a new fork of the blockchain from before the block the transaction was confirmed in, and then apply more computational power than the rest of the network combined in order to overtake the legitimate fork. - -However, one of the key requirements for a proof of work algorithm to, well, work is decentralization. If the proof of work algorithm is designed in such a way that the proof of work computation can only be efficiently done by entities with the millions of dollars of capital required to develop specialized hardware, then the number of participants in the process will be small enough that it will be possible for the majority of miners to conspire and reverse transactions. Alternatively, if the proof of work algorithm encourages miners to outsource their block verification work to centralized entities, then that is another way that centralization can creep in, and it would be the mining pools that have the potential to form conspiracies. Ideally, proof of work algorithms should solve both of those problems. - -#### Blockchain Based PoW Specification - -This mining algorithm is based on Adam Back's Hashcash, also used by Bitcoin. In Hashcash, we take a hash function `H` (assume 256-bit length) which takes as input data and a nonce and a difficulty parameter, and say that a valid nonce is one where `H(data,nonce) < 2^256 / difficulty`. Completing the proof of work essentially entails trying different nonces until one works, and verifying means applying the hash function to the data and nonce provided and making sure that the result is indeed below the target. In Bitcoin, `H` is a simple computation of `sha256(block_header + nonce)`. Here, however, `H` is much more complex, taking in as data not just the block header but also the state data and transactions from the last 16 blocks. - -In this early sketch of the mining algorithm, `H` is defined as follows: - -1. Let `h[i] = sha3(sha3(block_header) ++ nonce ++ i)` for `1 <= i <= 16` -2. Let `S` be the blockchain state 16 blocks ago. -3. Let `C[i]` be the transaction count of the block `i` blocks ago. Let `T[i]` be the `(h[i] mod C[i])`th transaction from the block `i` blocks ago. -4. Apply `T[0]`, `T[1]` … `T[15]` sequentially to `S`. However, every time the transaction leads to processing a contract, (pseudo-)randomly make minor modifications to the code of all contracts affected. -5. Let `S'` be the resulting state. Let `r` be the sha3 of the root of `S'`. - -#### Properties - -1. The algorithm is memory-hard; mining requires the miner to store the full state of the last 16 blocks in order to be able to query the blockchain. However, the algorithm is not sequentially memory-hard and is vulnerable to shared memory optimizations. -2. The algorithm requires every node to store the entire blockchain state and be able to process transactions. Furthermore, as new blocks are created, it will likely be more efficient to generate the new blockchain state by computing it rather than by asking for and downloading the missing Patricia tree nodes. Hence, there is no reason why a miner would not want to be a full node. -3. The EVM (Ethereum Virtual Machine) code is Turing-complete. Hence, an ASIC that performs transaction processing vastly more efficiently than existing CPUs would necessarily be a general-purpose computing device vastly more efficient than existing CPUs. Thus, if you can make an Ethereum ASIC, you can push the entire computing industry forward by about 5 years. -4. Because every miner must have the full blockchain, there is no equivalent to the Bitcoin mining strategy of only downloading headers from a centralized source. Hence, centralized mining pools offer no benefits over p2pools, and so miners are more likely to use p2pools. -5. The algorithm is relatively computationally quick to verify, although there is no "nice" verification formula that can be run inside EVM code. - -(3) and (4) combined basically mean that this proof of work algorithm provides both forms of decentralization, and (2) helps prevent centralization due to blockchain bloat since it helps ensure that at least miners will store the chain. - -In the above given form, the algorithm has several faults. First, due to the Pareto effect, it is likely that over 90% of transactions will use up less than 10% of the blockchain, so a truly full node will not be required to mine. Second, some targeted optimizations involving executing contracts and caching results may be possible. Finally, arguably most importantly, a deep 51% attack becomes possible, where attackers start hundreds of blocks back, produce 16 blocks with transactions optimized for themselves to process quickly (eg. obfuscated loops, weakened trapdoor functions), and then mine much faster than the legitimate chain. For the last two reasons, we expect that very heavy use (perhaps even dominance) of contract corruption/randomization will be necessary in the final version of the algorithm. - -### Transactions - -A transaction is stored as: - - [ nonce, receiving_address, value, [ data item 0, data item 1 ... data item n ], v, r, s ] - -nonce is the number of transactions already sent by that account, encoded in binary form (eg. 0 -> '', 7 -> '\x07', 1000 -> '\x03\xd8'). (v,r,s) is the raw Electrum-style signature of the transaction without the signature made with the private key corresponding to the sending account, with 0 <= v <= 3. From an Electrum-style signature (65 bytes) it is possible to extract the public key, and thereby the address, directly. A valid transaction is one where (i) the signature is well-formed (ie. 0 <= v <= 3, 0 <= r < P, 0 <= s < N, 0 <= r < P - N if v >= 2), and (ii) the sending account has enough funds to pay the fee and the value. A valid block cannot contain an invalid transaction; however, if a contract generates an invalid transaction that transaction will simply have no effect. Transaction fees will be included automatically. If one wishes to voluntarily pay a higher fee, one is always free to do so by constructing a contract which forwards transactions but automatically sends a certain amount or percentage to the miner of the current block. - -Transactions sent to the empty string as an address are a special type of transaction, creating a "contract". - - -### Difficulty adjustment - -Difficulty is adjusted by the formula: - - D(genesis_block) = 2^36 - D(block) = - if anc(block,1).timestamp >= anc(block,501).timestamp + 60 * 500: D(block.parent) - floor(D(block.parent) / 1000) - else: D(block.parent) + floor(D(block.parent) / 1000) - -`anc(block,n)` is the nth generation ancestor of the block; all blocks before the genesis block are assumed to have the same timestamp as the genesis block. This stabilizes around a block time of 60 seconds automatically. The choice of 500 was made in order to balance the concern that for smaller values miners with sufficient hashpower to often produce two blocks in a row would have the incentive to provide an incorrect timestamp to maximize their own reward and the fact that with higher values the difficulty oscillates too much; with the constant of 500, simulations show that a constant hashpower produces a variance of about +/-20%. - -### Block Rewards and Limits - -A miner receives three kinds of rewards: a static block reward for producing a block, fees from transactions, and nephew/uncle rewards as described in the GHOST section above. The miner will receive 100% of the block reward and transaction fees for themselves. As described in the GHOST section, uncles only receive 87.5% of their block reward, with the remaining 12.5% going to the including nephew; the transaction fees from the stale block do not go to anyone. - -The default approach is to have no mandatory fees, allowing miners to include any transactions that they deem profitable to include. This approach has been received very favorably in the Bitcoin community particularly because it is "market-based" - that is, there is a market with miners on one side and transaction senders on the other where supply and demand determine the price. However, the problem with this line of reasoning is that transaction processing is not a market; although it is intuitively attractive to construe transaction processing as a service that the miner is making the effort to offer to transaction senders that needs to be paid for at an agreed-upon rate, in reality every transaction that a single miner includes needs to be processed by every node in the network, so the external costs of transaction processing borne by the network, which has no say in whether or not a transaction takes place, are thousands of times higher than the internal costs borne by the miner. - -However, as it turns out this flaw in the market-based mechanism, when given a particular inaccurate simplifying assumption, magically cancels itself out. The argument is as follows. Suppose that: - -1. The mining block reward is `B`. -2. A transaction leads to `k` operations, offering the reward `kR` to any miner that includes it where `R` is set by the sender and `k` and `R` are visible to the miner beforehand. -3. An operation has a processing cost of `C` to any node (ie. all nodes have equal efficiency) -4. There are `N` mining nodes, each with exactly equal processing power (ie. `1/N` of total) -5. No non-mining full nodes exist. - -A miner would be willing to process a transaction if the expected reward is greater than the cost. The expected reward is `kR/N` since the miner has a `1/N` chance of processing the next block. The cost is simply `kC`. Thus, the miner is willing to process transactions where: - - kR/N > kC - kR > kNC - R > NC - -Note that `R` is the per-operation fee, and `NC` is the cost to the entire network together of processing an operation. Hence, miners have the incentive to include only those transactions for which the total utilitarian benefit exceeds the cost. However, there are three important deviations from those assumptions in reality: - -1. The miner does pay a higher cost to process the transaction than the other verifying nodes, since the extra verification time delays block propagation and thus increases the chance the block will become a stale. -2. There do exist nonmining full nodes. -3. The mining power distribution may end up radically inegalitarian in practice. -4. Speculators, political enemies and crazies whose utility function includes causing harm to the network do exist, and they can cleverly set up contracts where their cost is much lower than the cost paid by other verifying nodes. - -(1) provides a tendency for the miner to include fewer transactions, and (2) increases `NC`; hence, these two effects at least partially cancel each other out. (3) and (4) are the major issue; to solve them we simply institute a floating cap: no block can have more operations than 150% of the long-term exponential moving average (exact figure subject to change pending further economic analysis). - -## Contracts - -In Ethereum, there are two types of entities that can generate and receive transactions: actual people (or bots, as cryptographic protocols cannot distinguish between the two) and contracts. A contract is essentially an automated agent that lives on the Ethereum network, has an Ethereum address and balance, and can send and receive transactions. A contract is "activated" every time someone sends a transaction to it, at which point it runs its code, perhaps modifying its internal state or even sending some transactions, and then shuts down. The "code" for a contract is written in a special-purpose low-level language consisting of a stack, which is not persistent, 2^256 memory entries, which are also not persistent, and 2^256 storage entries which constitute the contract's permanent state. Note that Ethereum users will not need to code in this low-level stack language; we are providing a simple [C-Like language](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-CLL) with variables, expressions, conditionals, arrays and while loops, and provide a compiler down to Ethereum script code. - -### Applications - -Here are some examples of what can be done with Ethereum contracts, with all code examples written in our C-like language. The variables `call.sender`, `call.value`, `call.data` and `call.datasize` are properties of the incoming transaction, `contract.storage`, and `contract.address` of the contract itself, and `block.account_balance`, `block.number`, `block.difficulty`, `block.parenthash`, `block.basefee` and `block.timestamp` properties of the block. `block.basefee` is the "base fee" which all transaction fees in Ethereum are calculated as a multiple of; for more info see the "fees" section below. All variables expressed as capital letters (eg. `A`) are constants, to be replaced by actual values by the contract creator when actually releasing the contract. - - -### Sub-currencies - -Sub-currencies have many applications ranging from currencies representing assets such as USD or gold to company stocks and even currencies with only one unit issued to represent collectibles or smart property. Advanced special-purpose financial protocols sitting on top of Ethereum may also wish to organize themselves with an internal currency. Sub-currencies are surprisingly easy to implement in Ethereum; this section describes a fairly simple contract for doing so. - -The idea is that if someone wants to send X currency units to account A in currency contract C, they will need to make a transaction of the form `(C, 100 * block.basefee, [A, X])`, and the contract parses the transaction and adjusts balances accordingly. For a transaction to be valid, it must send 100 times the base fee worth of ether to the contract in order to "feed" the contract (as each computational step after the first 16 for any contract costs the contract a small fee and the contract will stop working if its balance drains to zero). - - if tx.value < 100 * block.basefee: - stop - elif contract.storage[1000]: - from = tx.sender - to = tx.data[0] - value = tx.data[1] - if to <= 1000: - stop - if contract.storage[from] < value: - stop - contract.storage[from] = contract.storage[from] - value - contract.storage[to] = contract.storage[to] + value - else: - contract.storage[MYCREATOR] = 10^18 - contract.storage[1000] = 1 - - -Ethereum sub-currency developers may also wish to add some other more advanced features: - -* Include a mechanism by which people can buy currency units in exchange for ether, perhaps auctioning off a set number of units every day. -* Allow transaction fees to be paid in the internal currency, and then refund the ether transaction fee to the sender. This solves one major problem that all other "sub-currency" protocols have had to date: the fact that sub-currency users need to maintain a balance of sub-currency units to use and units in the main currency to pay transaction fees in. Here, a new account would need to be "activated" once with ether, but from that point on it would not need to be recharged. -* Allow for a trust-free decentralized exchange between the currency and ether. Note that trust-free decentralized exchange between any two contracts is theoretically possible in Ethereum even without special support, but special support will allow the process to be done about ten times more cheaply. - - -### Financial derivatives - -The underlying key ingredient of a financial derivative is a data feed to provide the price of a particular asset as expressed in another asset (in Ethereum's case, the second asset will usually be ether). There are many ways to implement a data feed; one method, pioneered by the developers of [Mastercoin](http://mastercoin.org/), is to include the data feed in the blockchain. Here is the code: - - if tx.sender != FEEDOWNER: - stop - contract.storage[data[0]] = data[1] - -Any other contract will then be able to query index I of data store D by using `block.contract_storage(D)[I]`. A more advanced way to implement a data feed may be to do it off-chain - have the data feed provider sign all values and require anyone attempting to trigger the contract to include the latest signed data, and then use Ethereum's internal scripting functionality to verify the signature. Pretty much any derivative can be made from this, including leveraged trading, options, and even more advanced constructions like collateralized debt obligations (no bailouts here though, so be mindful of black swan risks). - -To show an example, let's make a hedging contract. The basic idea is that the contract is created by party A, who puts up 4000 ether as a deposit. The contract then lies open for any party to accept it by putting in 1000 ether. Say that 1000 ether is worth $25 at the time the contract is made, according to index I of data store D. If party B accepts it, then after 30 days anyone can send a transaction to make the contract process, sending the same dollar value worth of ether (in our example, $25) back to B and the rest to A. B gains the benefit of being completely insulated against currency volatility risk without having to rely on any issuers. The only risk to B is if the value of ether falls by over 80% in 30 days - and even then, if B is online B can simply quickly hop onto another hedging contract. The benefit to A is the implicit 0.2% fee in the contract, and A can hedge against losses by separately holding USD in another location (or, alternatively, A can be an individual who is optimistic about the future of Ethereum and wants to hold ether at 1.25x leverage, in which case the fee may even be in B's favor). - - if tx.value < 200 * block.basefee: - stop - if contract.storage[1000] == 0: - if tx.value < 1000 * 10^18: - stop - contract.storage[1000] = 1 - contract.storage[1001] = 998 * block.contract_storage(D)[I] - contract.storage[1002] = block.timestamp + 30 * 86400 - contract.storage[1003] = tx.sender - else: - ethervalue = contract.storage[1001] / block.contract_storage(D)[I] - if ethervalue >= 5000: - mktx(contract.storage[1003],5000 * 10^18,0,0) - else if block.timestamp > contract.storage[1002]: - mktx(contract.storage[1003],ethervalue * 10^18,0,0) - mktx(A,(5000 - ethervalue) * 10^18,0,0) - -More advanced financial contracts are also possible; complex multi-clause options (eg. "Anyone, hereinafter referred to as X, can claim this contract by putting in 2 USD before Dec 1. X will have a choice on Dec 4 between receiving 1.95 USD on Dec 29 and the right to choose on Dec 11 between 2.20 EUR on Dec 28 and the right to choose on Dec 18 between 1.20 GBP on Dec 30 and paying 1 EUR and getting 3.20 EUR on Dec 29") can be defined simply by storing a state variable just like the contract above but having more clauses in the code, one clause for each possible state. Note that financial contracts of any form do need to be fully collateralized; the Ethereum network controls no enforcement agency and cannot collect debt. - - -### Identity and Reputation Systems - -The earliest alternative cryptocurrency of all, [Namecoin](http://namecoin.org/), attempted to use a Bitcoin-like blockchain to provide a name registration system, where users can register their names in a public database alongside other data. The major cited use case is for a [DNS](http://en.wikipedia.org/wiki/Domain_Name_System) system, mapping domain names like "bitcoin.org" (or, in Namecoin's case, "bitcoin.bit") to an IP address. Other use cases include email authentication and potentially more advanced reputation systems. Here is a simple contract to provide a Namecoin-like name registration system on Ethereum: - - if tx.value < block.basefee * 200: - stop - if contract.storage[tx.data[0]] or tx.data[0] < 100: - stop - contract.storage[tx.data[0]] = tx.data[1] - -One can easily add more complexity to allow users to change mappings, automatically send transactions to the contract and have them forwarded, and even add reputation and web-of-trust mechanics. - - -### Decentralized Autonomous Organizations - -The general concept of a "decentralized autonomous organization" is that of a virtual entity that has a certain set of members or shareholders which, perhaps with a 67% majority, have the right to spend the entity's funds and modify its code. The members would collectively decide on how the organization should allocate its funds. Methods for allocating a DAO's funds could range from bounties, salaries to even more exotic mechanisms such as an internal currency to reward work. This essentially replicates the legal trappings of a traditional company or nonprofit but using only cryptographic blockchain technology for enforcement. So far much of the talk around DAOs has been around the "capitalist" model of a "decentralized autonomous corporation" (DAC) with dividend-receiving shareholders and tradable shares; an alternative, perhaps described as a "decentralized autonomous community", would have all members have an equal share in the decision making and require 67% of existing members to agree to add or remove a member. The requirement that one person can only have one membership would then need to be enforced collectively by the group. - -Some "skeleton code" for a DAO might look as follows. - -There are three transaction types: - -* [0,k] to register a vote in favor of a code change -* [1,k,L,v0,v1...vn] to register a code change at code k in favor of setting memory starting from location L to v0, v1 ... vn -* [2,k] to finalize a given code change - -Note that the design relies on the randomness of addresses and hashes for data integrity; the contract will likely get corrupted in some fashion after about 2^128 uses, but that is acceptable since nothing close to that volume of usage will exist in the foreseeable future. 2^255 is used as a magic number to store the total number of members, and a membership is stored with a 1 at the member's address. The last three lines of the contract are there to add C as the first member; from there, it will be C's responsibility to use the democratic code change protocol to add a few other members and code to bootstrap the organization. - - if tx.value < tx.basefee * 200: - stop - if contract.storage[tx.sender] == 0: - stop - k = sha3(32,tx.data[1]) - if tx.data[0] == 0: - if contract.storage[k + tx.sender] == 0: - contract.storage[k + tx.sender] = 1 - contract.storage[k] += 1 - else if tx.data[0] == 1: - if tx.value <= tx.datan * block.basefee * 200 or contract.storage[k]: - stop - i = 2 - while i < tx.datan: - contract.storage[k + i] = tx.data[i] - i = i + 1 - contract.storage[k] = 1 - contract.storage[k+1] = tx.datan - else if tx.data[0] == 2: - if contract.storage[k] >= contract.storage[2 ^ 255] * 2 / 3: - if tx.value <= tx.datan * block.basefee * 200: - stop - i = 3 - L = contract.storage[k+1] - loc = contract.storage[k+2] - while i < L: - contract.storage[loc+i-3] = tx.data[i] - i = i + 1 - if contract.storage[2 ^ 255 + 1] == 0: - contract.storage[2 ^ 255 + 1] = 1 - contract.storage[C] = 1 - -This implements the "egalitarian" DAO model where members have equal shares. One can easily extend it to a shareholder model by also storing how many shares each owner holds and providing a simple way to transfer shares. - -DAOs and DACs have already been the topic of a large amount of interest among cryptocurrency users as a future form of economic organization, and we are very excited about the potential that DAOs can offer. In the long term, the Ethereum fund itself intends to transition into being a fully self-sustaining DAO. - - -### Further Applications - -1. **Savings wallets**. Suppose that Alice wants to keep her funds safe, but is worried that she will lose or someone will hack her private key. She puts ether into a contract with Bob, a bank, as follows: Alice alone can withdraw a maximum of 1% of the funds per day, Alice and Bob together can withdraw everything, and Bob alone can withdraw a maximum of 0.05% of the funds. Normally, 1% per day is enough for Alice, and if Alice wants to withdraw more she can contact Bob for help. If Alice's key gets hacked, she runs to Bob to move the funds to a new contract. If she loses her key, Bob will get the funds out eventually. If Bob turns out to be malicious, she can still withdraw 20 times faster than he can. - -2. **Crop insurance**. One can easily make a financial derivatives contract but using a data feed of the weather instead of any price index. If a farmer in Iowa purchases a derivative that pays out inversely based on the precipitation in Iowa, then if there is a drought, the farmer will automatically receive money and if there is enough rain the farmer will be happy because their crops would do well. - -3. **A decentralized (non-centrally managed) data feed**, using proof-of-stake voting to give an average (or more likely, median) of everyone's opinion on the price of a commodity, the weather or any other relevant data. - -4. **Smart multisignature escrow**. Bitcoin allows multisignature transaction contracts where, for example, three out of a given five keys can spend the funds. Ethereum allows for more granularity; for example, four out of five can spend everything, three out of five can spend up to 10% per day, and two out of five can spend up to 0.5% per day. Additionally, Ethereum multisig is asynchronous - two parties can register their signatures on the blockchain at different times and the last signature will automatically send the transaction. - -5. **Peer-to-peer gambling**. Any number of peer-to-peer gambling protocols, such as Frank Stajano and Richard Clayton's [Cyberdice](http://www.cl.cam.ac.uk/~fms27/papers/2008-StajanoCla-cyberdice.pdf), can be implemented on the Ethereum blockchain. The simplest gambling protocol is actually simply a contract for difference on the next block hash. From there, entire gambling services such as SatoshiDice can be replicated on the blockchain either by creating a unique contract per bet or by using a quasi-centralized contract. - -6. A full-scale **on-chain stock market**. Prediction markets are also easy to implement as a trivial consequence. - -7. An **on-chain decentralized marketplace**, using the identity and reputation system as a base. - -8. **Decentralized Dropbox**. One setup is to encrypt a file, build a Merkle tree out of it, put the Merkle root into a contract alongside a certain quantity of ether, and distribute the file across some secondary network. Every day, the contract would randomly select a branch of the Merkle tree depending on the block hash, and give X ether to the first node to provide that branch to the contract, thereby encouraging nodes to store the data for the long term in an attempt to earn the prize. If one wants to download any portion of the file, one can use a [micropayment-channel](https://bitcointalk.org/index.php?topic=244656.0)-style contract to download the file from a few nodes a block at a time. - - -### How do contracts work? - -A contract making transaction is encoded as follows: - - [ - nonce, - '', - value, - [ - data item 0, - data item 1, - ... - ], - v, - r, - s - ] - - -The data items will, in most cases, be script codes (more on this below). Contract creation transaction validation happens as follows: - -Deserialize the transaction, and extract its sending address from its signature. -Calculate the transaction's fee as NEWCONTRACTFEE plus storage fees for the code. Check that the balance of the creator is at least the transaction value plus the fee. If not, exit. -Take the last 20 bytes of the sha3 hash of the RLP encoding of the transaction making the contract. If an account with that address already exists, exit. Otherwise, create the contract at that address -Copy data item i to storage slot i in the contract for all i in [0 ... n-1] where n is the number of data items in the transaction, and initialize the contract with the transaction's value as its value. Subtract the value and fee from the creator's balance. - - -### Language Specification - -The contract scripting language is a hybrid of assembly language and Bitcoin's stack-based language, maintaining an index pointer that usually increments by one after every operation and continuously processing the operation found at the current index pointer. All opcodes are numbers in the range [0 ... 63]; labels further in this description such as STOP, EXTRO and BALANCE refer to specific values and are defined further below. The scripting language has access to three kinds of memory: - -* **Stack** - a form of temporary storage that is reset to an empty list every time a contract is executed. Operations typically add and remove values to and from the top of the stack, so the total length of the stack will shrink and grow over the course of the program's execution. -* **Memory** - a temporary key/value store that is reset to containing all zeroes every time a contract is executed. Keys and values in memory are integers in the range [0 ... 2^256-1] -* **Storage** - a persistent key/value store that is initially set to contain all zeroes, except for some script code inserted at the beginning when the contract is created as described above. Keys and values in storage are integers in the range [0 ... 2^256-1] - -Whenever a transaction is sent to a contract, the contract executes its scripting code. The precise steps that happen when a contract receives a transaction are as follows: - -**Contract Script Interpretation ** - -![SPV in bitcoin](https://www.ethereum.org/gh_wiki/flowchart.png) - -1. The contract's ether balance increases by the amount sent -2. The index pointer is set to zero, and STEPCOUNT = 0 -3. Repeat forever: - -* if the command at the index pointer is STOP, invalid or greater than 63, exit from the loop -* set MINERFEE = 0, VOIDFEE = 0 -* set STEPCOUNT <- STEPCOUNT + 1 -* if STEPCOUNT > 16, set MINERFEE <- MINERFEE + STEPFEE -* see if the command is LOAD or STORE. If so, set MINERFEE <- MINERFEE + DATAFEE -* see if the command will modify a storage field, say modifying KEY from OLDVALUE to NEWVALUE. Let F(K,V) be 0 if V == 0 else (len(K) + len(V)) * STORAGEFEE in bytes. Set VOIDFEE <- VOIDFEE - F(KEY,OLDVALUE) + F(KEY,NEWVALUE). Computing len(K) ignores leading zero bytes. -* see if the command is EXTRO or BALANCE. If so, set MINERFEE <- MINERFEE + EXTROFEE -* see if the command is a crypto operation. If so, set MINERFEE <- MINERFEE + CRYPTOFEE -* if MINERFEE + VOIDFEE > CONTRACT.BALANCE, HALT and exit from the loop -* subtract MINERFEE from the contract's balance and add MINERFEE to a running counter that will be added to the miner's balance once all transactions are parsed. -* set DELTA = max(-CONTRACT.STORAGE_DEPOSIT,VOIDFEE) and CONTRACT.BALANCE <- CONTRACT.BALANCE - DELTA and CONTRACT.STORAGE_DEPOSIT <- CONTRACT.STORAGE_DEPOSIT + DELTA. Note that DELTA can be positive or negative; the only restriction is that the contract's deposit cannot go below zero. -* run the command -* if the command did not exit with an error, update the index pointer and return to the start of the loop. If the contract did exit with an error, break out of the loop. Note that a contract exiting with an error does not make the transaction or the block invalid; it simply means that the contract execution halts midway through. - -In the following descriptions, S[-1], S[-2], etc represent the topmost, second topmost, etc items on the stack. The individual opcodes are defined as follows: - -* (0) STOP - halts execution -* (1) ADD - pops two items and pushes S[-2] + S[-1] mod 2^256 -* (2) MUL - pops two items and pushes S[-2] * S[-1] mod 2^256 -* (3) SUB - pops two items and pushes S[-2] - S[-1] mod 2^256 -* (4) DIV - pops two items and pushes floor(S[-2] / S[-1]). If S[-1] = 0, halts execution. -* (5) SDIV - pops two items and pushes floor(S[-2] / S[-1]), but treating values above 2^255 - 1 as negative (ie. x -> 2^256 - x). If S[-1] = 0, halts execution. -* (6) MOD - pops two items and pushes S[-2] mod S[-1]. If S[-1] = 0, halts execution. -* (7) SMOD - pops two items and pushes S[-2] mod S[-1], but treating values above 2^255 - 1 as negative (ie. x -> 2^256 - x). If S[-1] = 0, halts execution. -* (8) EXP - pops two items and pushes S[-2] ^ S[-1] mod 2^256 -* (9) NEG - pops one item and pushes 2^256 - S[-1] -* (10) LT - pops two items and pushes 1 if S[-2] < S[-1] else 0 -* (11) LE - pops two items and pushes 1 if S[-2] <= S[-1] else 0 -* (12) GT - pops two items and pushes 1 if S[-2] > S[-1] else 0 -* (13) GE - pops two items and pushes 1 if S[-2] >= S[-1] else 0 -* (14) EQ - pops two items and pushes 1 if S[-2] == S[-1] else 0 -* (15) NOT - pops one item and pushes 1 if S[-1] == 0 else 0 -* (16) MYADDRESS - pushes the contract's address as a number -* (17) TXSENDER - pushes the transaction sender's address as a number -* (18) TXVALUE - pushes the transaction value -* (19) TXDATAN - pushes the number of data items -* (20) TXDATA - pops one item and pushes data item S[-1], or zero if index out of range -* (21) BLK_PREVHASH - pushes the hash of the previous block (NOT the current one since that's impossible!) -* (22) BLK_COINBASE - pushes the coinbase of the current block -* (23) BLK_TIMESTAMP - pushes the timestamp of the current block -* (24) BLK_NUMBER - pushes the current block number -* (25) BLK_DIFFICULTY - pushes the difficulty of the current block -* (26) BLK_NONCE - pushes the nonce of the current block -* (27) BASEFEE - pushes the base fee (x as defined in the fee section below) -* (32) SHA256 - pops two items, and then constructs a string by taking the ceil(S[-1] / 32) items in memory from index S[-2] to (S[-2] + ceil(S[-1] / 32) - 1) mod 2^256, prepending zero bytes to each one if necessary to get them to 32 bytes, and takes the last S[-1] bytes. Pushes the SHA256 hash of the string -* (33) RIPEMD160 - works just like SHA256 but with the RIPEMD-160 hash -* (34) ECMUL - pops three items. If (S[-2],S[-1]) are a valid point in secp256k1, including both coordinates being less than P, pushes (S[-2],S[-1]) * S[-3], using (0,0) as the point at infinity. Otherwise, pushes (2^256 - 1, 2^256 - 1). Note that there are no restrictions on S[-3] -* (35) ECADD - pops four items and pushes (S[-4],S[-3]) + (S[-2],S[-1]) if both points are valid, otherwise (2^256 - 1,2^256 - 1) -* (36) ECSIGN - pops two items and pushes (v,r,s) as the Electrum-style RFC6979 deterministic signature of message hash S[-1] with private key S[-2] mod N with 0 <= v <= 3 -* (37) ECRECOVER - pops four items and pushes (x,y) as the public key from the signature (S[-3],S[-2],S[-1]) of message hash S[-4]. If the signature has invalid v,r,s values (ie. v not in [27,28], r not in [0,P], s not in [0,N]), return (2^256 - 1,2^256 - 1) -* (38) ECVALID - pops two items and pushes 1 if (S[-2],S[-1]) is a valid secp256k1 point (including (0,0)) else 0 -* (39) SHA3 - works just like SHA256 but with the SHA3 hash, 256 bit version -* (48) PUSH - pushes the item in memory at the index pointer + 1, and advances the index pointer by 2. -* (49) POP - pops one item. -* (50) DUP - pushes S[-1] to the stack. -* (51) SWAP - pops two items and pushes S[-1] then S[-2] -* (52) MLOAD - pops two items and sets the item in memory at index S[-1] to S[-2] -* (53) MSTORE - pops two items and sets the item in memory at index S[-1] to S[-2] -* (54) SLOAD - pops two items and sets the item in storage at index S[-1] to S[-2] -* (55) SSTORE - pops two items and sets the item in storage at index S[-1] to S[-2] -* (56) JMP - pops one item and sets the index pointer to S[-1] -* (57) JMPI - pops two items and sets the index pointer to S[-2] only if S[-1] is nonzero -* (58) IND - pushes the index pointer -* (59) EXTRO - pops two items and pushes memory index S[-2] of contract S[-1] -* (60) BALANCE - pops one item and pushes balance of the account with that address, or zero if the address is invalid -* (61) MKTX - pops four items and initializes a transaction to send S[-2] ether to S[-1] with S[-3] data items. Takes items in memory from index S[-4] to index (S[-4] + S[-3] - 1) mod 2^256 as the transaction's data items. -* (63) SUICIDE - pops one item, destroys the contract and clears all storage, sending the entire balance plus the contract deposit to the account at S[-1] - - -As mentioned above, the intent is not for people to write scripts directly in Ethereum script code; rather, we will release compilers to generate ES from higher-level languages. The first supported language will likely be the simple [C-like language](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-CLL) used in the descriptions above, and the second will be a more complete first-class-function language with support for arrays and arbitrary-length strings. Compiling the C-like language is fairly simple as far as compilers go: variables can be assigned a memory index, and compiling an arithmetic expression essentially involves converting it to reverse Polish notation (eg. `(3 + 5) * (x + y)` -> `PUSH 3 PUSH 5 ADD PUSH 0 MLOAD PUSH 1 MLOAD ADD MUL`). First-class function languages are more involved due to variable scoping, but the problem is nevertheless tractable. The likely solution will be to maintain a linked list of stack frames in memory, giving each stack frame N memory slots where N is the total number of distinct variable names in the program. Variable access will consist of searching down the stack frame list until one frame contains a pointer to the variable, copying the pointer to the top stack frame for memoization purposes, and returning the value at the pointer. However, these are longer term concerns; compilation is separate from the actual protocol, and so it will be possible to continue to research compilation strategies long after the network is set running. - - -## Fees - -In Bitcoin, there are no mandatory transaction fees. Transactions can optionally include fees which are paid to miners, and it is up to the miners to decide what fees they are willing to accept. In Bitcoin, such a mechanism is already imperfect; the need for a 1 MB block size limit alongside the fee mechanism shows this all too well. In Ethereum, because of its Turing-completeness, a purely voluntary fee system would be catastrophic. Instead, Ethereum will have a system of mandatory fees, including a transaction fee and six fees for contract computations. The fees are currently set to: - -* TXFEE (100x) - fee for sending a transaction -* NEWCONTRACTFEE (100x) - fee for creating a new contract, not including the storage fee for each item in script code -* STEPFEE (1x) - fee for every computational step after the first sixteen in contract execution -* STORAGEFEE (5x) - per-byte fee for adding to contract storage. The storage fee is the only fee that is not paid to a miner, and is refunded when storage used by a contract is reduced or removed. -* DATAFEE (20x) - fee for accessing or setting a contract's memory from inside that contract -* EXTROFEE (40x) - fee for accessing memory from another contract inside a contract -* CRYPTOFEE (20x) - fee for using any of the cryptographic operations - - -The coefficients will be revised as more hard data on the relative computational cost of each operation becomes available. The hardest part will be setting the value of x. There are currently two main solutions that we are considering: - -* Make x inversely proportional to the square root of the difficulty, so x = floor(10^21 / floor(difficulty ^ 0.5)). This automatically adjusts fees down as the value of ether goes up, and adjusts fees down as computers get more powerful due to Moore's Law. -* Use proof of stake voting to determine the fees. In theory, stakeholders do not benefit directly from fees going up or down, so their incentives would be to make the decision that would maximize the value of the network. - -A hybrid solution is also possible, using proof of stake voting, but with the inverse square root mechanism as an initial policy. - - -## Conclusion - -The Ethereum protocol's design philosophy is in many ways the opposite from that taken by many other cryptocurrencies today. Other cryptocurrencies aim to add complexity and increase the number of "features"; Ethereum, on the other hand, takes features away. The protocol does not "support" multisignature transactions, multiple inputs and outputs, hash codes, lock times or many other features that even Bitcoin provides. Instead, all complexity comes from a universal, Turing-complete scripting language, which can be used to build up literally any feature that is mathematically describable through the contract mechanism. As a result, we have a protocol with unique potential; rather than being a closed-ended, single-purpose protocol intended for a specific array of applications in data storage, gambling or finance, Ethereum is open-ended by design, and we believe that it is extremely well-suited to serving as a foundational layer for a very large number of both financial and non-financial protocols in the years to come. - - -## References and Further Reading - -1. Colored coins whitepaper: https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit -2. Mastercoin whitepaper: https://github.com/mastercoin-MSC/spec -3. Decentralized autonomous corporations, Bitcoin Magazine: http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/ -4. Smart property: https://en.bitcoin.it/wiki/Smart_Property -5. Smart contracts: https://en.bitcoin.it/wiki/Contracts -6. Simplified payment verification: https://en.bitcoin.it/wiki/Scalability#Simplifiedpaymentverification -7. Merkle trees: http://en.wikipedia.org/wiki/Merkle_tree -8. Patricia trees: http://en.wikipedia.org/wiki/Patricia_tree -9. Bitcoin whitepaper: http://bitcoin.org/bitcoin.pdf -10. GHOST: http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf -11. StorJ and Autonomous Agents, Jeff Garzik: http://garzikrants.blogspot.ca/2013/01/storj-and-bitcoin-autonomous-agents.html -12. Mike Hearn on Smart Property at Turing Festival: http://www.youtube.com/watch?v=Pu4PAMFPo5Y -13. Ethereum RLP: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP -14. Ethereum Merkle Patricia trees: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree -15. Ethereum Dagger: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Dagger -16. Ethereum C-like language: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-CLL -17. Ethereum Slasher: http://blog.ethereum.org/?p=39/slasher-a-punitive-proof-of-stake-algorithm -18. Scrypt parameters: https://litecoin.info/User:Iddo/ComparisonbetweenLitecoinandBitcoin#SHA256miningvsscryptmining -19. Litecoin ASICs: https://axablends.com/merchants-accepting-bitcoin/litecoin-discussion/litecoin-scrypt-asic-miners/ \ No newline at end of file diff --git a/drafts/[english]-patricia-tree-draft.md b/drafts/[english]-patricia-tree-draft.md deleted file mode 100644 index 57f12ab23..000000000 --- a/drafts/[english]-patricia-tree-draft.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -name: Patricia Tree -category: ---- - -The best known tutorial/explanation of the ethereum patricia tree is here: -https://easythereentropy.wordpress.com/2014/06/04/understanding-the-ethereum-trie/ \ No newline at end of file diff --git a/images/natspec1.png b/images/natspec1.png deleted file mode 100644 index cf31fcf24fce2801ffbedaac8ae151d7e5d806d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82697 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

wS*%-n0fWjsb2}4#4rP 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�#pOa+AG7A-y+ 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

5C| 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�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 -![](http://www.kellydessaint.com/wp-content/uploads/2014/08/lyft_ratings3.jpg) - - -And even governments: - -
-[![](https://www.privateinternetaccess.com/blog/wp-content/uploads/2015/10/SesameCredit.jpg)](https://www.privateinternetaccess.com/blog/2015/10/in-china-your-credit-score-is-now-affected-by-your-political-opinions-and-your-friends-political-opinions/) -
- -However, if we want to create a globally accessible system, centralized credit scores are arguably insufficient: not everyone in the world will be willing to trust a particular entity to provide accurate and fair credit scores, particularly in international cases where there are large political differences. Hence, while centralized credit scores may work in particular closed environments, in an international trade context it would be more ideal to have a global framework that allows specialized scoring agencies to exist, but which allows recipients to choose which ones they "listen" to, and even combine their scores. - -A highly effective solution to this problem, which has existed in academia and the public for over a decade, uses the "web of trust" route: essentially, instead of trying to achieve a single universal score for everyone, provide a way for each person to score anyone else from their own point of view. This is accomplished through the trust transitivity heuristic: if A trusts B, and B trusts C, then to some degree that's cause for A to trust C. In some ways, centralized credit scores are a special case of this: everyone trusts the central agency (in theory), the central agency assigns people trust ratings, and so that's how much everyone is induced to trust everyone else. However, the decentralized approach is more general, and ideally allows us to take into account _all_ "chains of trust" between two people, and not just the ones that flow through a particular centralized gateway. - -![](http://vitalik.ca/files/wot_centralized_and_decentralized.png?1) - -One example of an algorithm that does this well is the [Advogato trust metric](http://www.advogato.org/trust-metric.html), a trust score scheme based on [max-flow](https://en.wikipedia.org/wiki/Maximum_flow_problem). - -A useful project would be to create an implementation of such a system on Ethereum, and create a dapp by which anyone can register an identity, and register trust scores for other identities. Then, create a decentralized cloud computing service by which anyone can query "provide a proof, consisting of a list of trust paths, showing the Advogato trust score from A to B" and anyone can reply in exchange for a micropayment (or perhaps create a server that does it for free, and convince a charity to subsidize it); if user A wants to know "what is B's trust score", they can make this query, receive the result, verify the proof, and then display it. - -This system could then be used by many other dapps on ethereum, including financial contract using price feeds and arbitration. - -### Financial Derivatives Market - -Essentially, a polished, working dapp that allows users to make options on any ethereum asset, and derivatives (eg. CFDs) on any ethereum price feed. This should support "multisig price feeds": choosing multiple data feed contract addresses that support a particular ticker symbol, and taking the median of them, so as to remove reliance on any single party. - -Supported actions should ideally include: - -* Entering into CFDs with other parties on any price index, settling in any standards-compatible currency or asset (though perhaps start with ETH) -* Options between any two assets (though perhaps start with asset<->ETH) -* Plain old regular asset exchange -* An order book for all of the above - -### RANDAO - -Essentially, [this](https://forum.ethereum.org/discussion/2031/randao-a-dao-working-as-rng). Set it up as a decentralized service which any lottery or other randomness-based game can use; also, build a "full node software" package/plugin which facilitates participating in the RANDAO by providing random numbers. - -### Interface with national ID - -Create a system, relying on trusting no one other than the original issuer, by which users with electronic identities (eg. Estonian digital ID, other electronic passports, crypto KYC schemes, etc) can prove to the ethereum blockchain that they have that particular ID. Note that this can be plugged into the WoT by, eg, creating a contract which trusts everyone who has an Estonian digital ID with score 1. - -### Zero knowledge proofs - -Create multiple compatible implementations of a ZK-SNARK protocol. - -### Ultrahard KDFs for brainwallets - -A decentralized paid cloud computing service for brainwallet computations, combined with a client-side solution, in order to implement my proposal for ultra-secure brainwallets using blind-outsourceable ultrahard KDFs: https://blog.ethereum.org/2014/10/23/information-theoretic-account-secure-brainwallets/ - -### Estonia ID integration - -Create a system which integrates the Estonian digital ID system into Ethereum; essentially, create a registry where someone can link their address to a particular Estonian digital ID by signing a transaction with their ID. The registry should cryptographically verify that the signature is valid and that it matches a particular ID, and should then store a mapping, eg. `address -> (first name, last name, number)` - -Some developer resources that can help with this include: - -* http://eid.eesti.ee/index.php/Authenticating_in_web_applications -* https://e-estonia.com/e-residents/for-developers/ -* https://sk.ee/en/services/testcard/ -* http://id.ee/index.php?id=30469 - -### Security Deposit-backed Conditional Hashcash - -The key piece of technology that later spawned the advent of blockchains starting with Bitcoin, proof of work, was originally devised for quite a different application: email spam prevention. In order to send an email that would be viewed by recipients' email interfaces, users would need to complete a certain amount of computational work on their computers that could quickly be verified. This would impose a small cost in electricity and CPU power to sending an email (say, $0.01) that would in theory be no problem for ordinary messages, but would be so expensive as to make spam no longer worth it. In practice, this idea never succeeded, in large part because people did not want to pay for their email and because it would only lead to spammers paying more in order to send more well-crafted emails to fewer parties, which would be more likely to receive attention because users think that they already passed the proof of work filter. - -Here, I propose a proof of stake twist on the algorithm that would solve this problem. The key insight is that instead of making the sender _always_ pay the cost, we make the cost a security deposit, and the recipient has the right, only if they wish, to destroy the security deposit at no benefit to themselves (in an actual implementation, "destroy" will hopefully mean something like "donate to protocol developers"). Ordinary "useful" messages would get through unscathed, and spam would be punished in proportion to the percentage of people that find it scammy. The conditional nature of the protocol can theoretically allow the deposits to be increased much higher than the cost of proof of work; deposits of $1 or even higher are quite reasonable. - -There are two possible extensions to this idea: - -1. Use techniques similar to [anti-pre-revelation games](https://blog.ethereum.org/2015/08/28/on-anti-pre-revelation-games/#comment-2230211912) (or possibly other techniques) to allow users to destroy other users' security deposits (either probabilistically or fully) without the victim knowing who did it. This allows the mechanism to be used more effectively in intra-organizational and social situations, so that you can punish people for being annoying without extra-protocol repercussions. Aside from information-theoretic strategies, there may be routes to doing this using Chaumian blinding schemes, cryptographic accumulators and/or zk-SNARK proofs; the goal to target would be in a scenario with one sender and N recipients, with the sender having a deposit of $NX, giving each recipient the right to destroy $X exactly once without revealing which one of the N they are; the main challenge is the sender gleaning this information by simulating the process of each single recipient destroying their deposit and seeing which one(s) fail, and so private information on the recipients' part and perhaps even an interactive protocol is required. -2. Have different levels of deposits, where higher levels of deposits can be used to signal more importance/urgency in the interface; at the highest levels, one could imagine a deposit of $500 leading to one's phone ringing maximally loudly whereas a deposit of $0.1 would only lead to an email appearing next time one opens one's mailbox. \ No newline at end of file diff --git a/pages/Open-job-positions-&-Schemes.md b/pages/Open-job-positions-&-Schemes.md deleted file mode 100644 index fbbdadc61..000000000 --- a/pages/Open-job-positions-&-Schemes.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -name: Open Positions and Schemes -category: ---- - -### Full-time Roles - -Ethereum has a number of full-time employee roles open. For the Berlin team (concentrating mostly around the C++-based implementation and development tools) you'll be based in Kreuzberg, Berlin in our central office/hub/café location, for the Amsterdam team (concentrating mostly around the Go-based implementation and the consumer software) you'll work remotely for now. Roles include security, optimisation, networking and helping make reality our advanced integrated blockchain development environment. We are presently particularly interested in expanding our team for the latter; if you have good knowledge of the Qt5 platform including QtQuick & QML, then please get in touch with `jobs@ethdev.com`. - -For more information on full time positions, see `TODO: Aeron`. - -### Hub-Invitation Scheme - -If you have been working on an Ethereum/ÐΞV-related project, we would love to hear from you. In addition to helping wherever we can with fixes and advice, for promising non-profit, open-source projects where considerable effort has clearly been invested we would like to invite you to collaborate more closely at one of our holons/hubs. At present there are two operational hubs: - -- **ÐΞV Berlin** in Kreuzberg (Berlin), Germany; -- **ÐΞV Amsterdam** near Museum Plein, Netherlands; -- **Ethereum Suisse** in Zug (near Zurich), Switzerland. - -Such an invitation will include travel costs, a small stipend for food costs during the time and shared accommodation. You will have full access to the hub resources during your stay and be free to work and relax around other members of the local ÐΞV & Ethereum communities. - -Projects that are especially interesting to us are: -- alternative implementations of the protocol in esoteric languages; -- legacy-system (web back-end, but perhaps other frameworks/environments, too) integrations; -- education and adoption tools; -- Ðapps & contracts that do something novel; -- Ðapps & contracts that do something well. - -If you believe you have such a project and would like to come visit us for a while, let us know at `visitus@ethdev.com`! - -### Sponsoring Scheme - -Additionally, for interesting projects, we would like to extend financial support in the form of a small bursary. We consider all such projects, as with the Hub Invitation Scheme. Bursary amounts vary from the $1000s to the $10,000s, depending on the size, scope and outlook of the project. - -If you believe you have such a project let us know at `bursary@ethdev.com`, with a proposal for where you would like to take the project and estimates of any expenses that might be involved in taking it forward. - -### FAQ - -Q. I want to make a client in language XYZ. I haven't started yet but was hoping you'd pay me a full developer's salary to do it. Can I have a job? - -A. No. Our resources do not extend so far. We wish you luck with your endeavour and if you get far would certainly invite you to our collaborative environment in the above scheme. - -Q. I have an idea for a contract/Ðapp/integration/... Could I get some money to fund its development? - -A. Ethereum/ÐΞV is not an accelerator, incubator or investment operation. We only wish to lend a hand (financial and otherwise) to those already engrossed in their project. As such our assistance schemes are open only to those whose already have an established project that is Ethereum-centric. \ No newline at end of file diff --git a/pages/_Sidebar.md b/pages/_Sidebar.md deleted file mode 100644 index be20b8059..000000000 --- a/pages/_Sidebar.md +++ /dev/null @@ -1,75 +0,0 @@ -### Basics -- [Home](https://github.com/ethereum/wiki/wiki/) -- [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) -- [FAQ](https://github.com/ethereum/wiki/wiki/FAQ) - -### Ðapp Development -- [Ðapp Developer Resources](https://github.com/ethereum/wiki/wiki/Dapp-Developer-Resources) -- [JavaScript API](https://github.com/ethereum/wiki/wiki/JavaScript-API) -- [JSON RPC API](https://github.com/ethereum/wiki/wiki/JSON-RPC) -- [Solidity](https://ethereum.github.io/solidity/docs/home/) -- [Solidity Features](https://github.com/ethereum/wiki/wiki/Solidity-Features) -- [Useful Ðapp Patterns](https://github.com/ethereum/wiki/wiki/Useful-Ðapp-Patterns) -- [Standardized Contract APIs](https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs) -- [Ðapp using Meteor](https://github.com/ethereum/wiki/wiki/Dapp-using-Meteor) -- [Ethereum development tutorial](https://github.com/ethereum/wiki/wiki/Ethereum-Development-Tutorial) -- [Mix Tutorial](https://github.com/ethereum/wiki/wiki/Mix:-The-DApp-IDE) -- [Mix Features](https://github.com/ethereum/wiki/wiki/Mix-Features) -- [Serpent](https://github.com/ethereum/wiki/wiki/Serpent) -- [LLL](https://github.com/ethereum/cpp-ethereum/wiki/LLL) -- [Mutan](https://github.com/obscuren/mutan) - -### ÐΞV Technologies -- [RLP Encoding](https://github.com/ethereum/wiki/wiki/RLP) -- [RLPx Node Discovery Protocol](https://github.com/ethereum/wiki/wiki/Node-discovery-protocol-(RLPx)) -- [ÐΞVp2p Wire Protocol](https://github.com/ethereum/wiki/wiki/%C3%90%CE%9EVp2p-Wire-Protocol) -- [ÐΞVp2p Whitepaper](https://github.com/ethereum/wiki/wiki/libp2p-Whitepaper) (WiP) -- [Web3 Secret Storage](https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition) - -### Ethereum Technologies -- [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) -- [Subtleties](https://github.com/ethereum/wiki/wiki/Subtleties) -- [Solidity, Docs & ABI](https://github.com/ethereum/wiki/wiki/Solidity,-Docs-and-ABI) -- [NatSpec Format](https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format) -- [Contract ABI](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI) -- [Bad Block Reporting](http://github.com/ethereum/wiki/wiki/Bad-Block-Reporting) -- [Bad Chain Canary](http://github.com/ethereum/wiki/wiki/Bad-Chain-Canary) -- [Extra Data](http://github.com/ethereum/wiki/wiki/Extra-Data) -- [Brain Wallet](https://github.com/ethereum/wiki/wiki/Brain-Wallet) - -### Ethash/Dashimoto -- [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) - -### Infrastructure Development -- [Morden](https://github.com/ethereum/wiki/wiki/Morden) -- [Inter-exchange Client Address Protocol](https://github.com/ethereum/wiki/wiki/ICAP:-Inter-exchange-Client-Address-Protocol) -- [URL Hint Protocol](https://github.com/ethereum/wiki/wiki/URL-Hint-Protocol) -- [NatSpec Determination](https://github.com/ethereum/wiki/wiki/NatSpec-Determination) -- [Exchange Integration](https://github.com/ethereum/wiki/wiki/Exchange-Integration) -- [Mining](https://github.com/ethereum/wiki/wiki/Mining) -- [Licensing](https://github.com/ethereum/wiki/wiki/Licensing) -- [Network Status](https://github.com/ethereum/wiki/wiki/Network-Status) -- [Raspberry Pi](https://github.com/ethereum/wiki/wiki/Raspberry-Pi-instructions) - -### Ethereum Clients -- [AlethZero (C++)](https://github.com/ethereum/wiki/wiki/AlethZero) -- [Mist (Go)](https://github.com/ethereum/wiki/wiki/Ethereal) -- [pyeth (Python)](https://github.com/ethereum/wiki/wiki/Pyeth) - -### Concerning Whisper -- [Whisper Proposal](https://github.com/ethereum/wiki/wiki/Whisper) -- [Whisper Overview](https://github.com/ethereum/wiki/wiki/Whisper-Overview) -- [PoC-1 Wire protocol](https://github.com/ethereum/wiki/wiki/Whisper-Wire-Protocol) -- [PoC-2 Wire protocol](https://github.com/ethereum/wiki/wiki/Whisper-PoC-2-Wire-Protocol) -- [PoC-2 Whitepaper](https://github.com/ethereum/wiki/wiki/Whisper-PoC-2-Protocol-Spec) - -### Misc -- [Hard Problems of Cryptocurrency](https://github.com/ethereum/wiki/wiki/Problems) -- [Chain Fibers](https://github.com/ethereum/wiki/wiki/Chain-Fibers-Redux) -- [Glossary](https://github.com/ethereum/wiki/wiki/Glossary) \ No newline at end of file diff --git a/pages/blog-and-notes/Fortnight-In-Ethereum-Template.md b/pages/blog-and-notes/Fortnight-In-Ethereum-Template.md deleted file mode 100644 index 6f6e934bf..000000000 --- a/pages/blog-and-notes/Fortnight-In-Ethereum-Template.md +++ /dev/null @@ -1,412 +0,0 @@ ---- -name: Fortnight in Ethereum Template -category: ---- - -This document exists to collate information once a fortnight (biweekly) from the various different aspects/projects taking place in Ethereum which will allow everyone to better understand what everyone else is working on. - - -###Current Status of the project - -What is the overall current of status of the Ethereum project? What is the next goal? - - -##Clients/Protocol - -###CPP - -**What's the current status of what you're working on?** -Nearing release of PoC 9 (Mar 6): -* new PoW -* structured logging -* peer selection strategy for node discovery -* rlpx wireline protocol (interop w/Go client) - -**What progress has been made in the last two weeks?** -Release of PoC 8: -* Improved networking & peer discovery -* evm testing -* updates for compliance w/YP -* rpc/ethereum-js updates, bug fixes, interop -* dapp loading -* continued development of solidity features -* continued development for chromium support -* updates for natspec support - -**What are the next steps?** -Further preparation for release. - -###Go/Mist - -**What's the current status of what you're working on?** -Improving networking encryption, optimising block processing, refining Mist UI - -**What progress has been made in the last two weeks?** -Release of PoC 8 including: - - * Improved UI and UX - - * Multithreaded miner - - * Updated RPC interface - - * Improved networking & peer discovery - - * Moved from WebKit to Chromium rendering engine (QtWebEngine) - -**What are the next steps?** -Finalising command-line interface and polishing Mist components in preparation for beta - -###Node Ethereum - -**What's the current status of what you're working on?** -* Networking is the biggest issue ATM. -* RPC compliance - -**What progress has been made in the last two weeks?** -* adding rlpx - + Wrote DHT code (https://github.com/ethereum/ethereumjs-dht) -* Testing - + Fixed a several VM bugs caught be the tests -* Finalized a new ethereumjs-lib version - + Unified block/tx/code processing API - + simplified browser shims - + Cleaned up Docs - -**What are the next steps?** -* RLPx - + added encryption -* More RPC tests - -###Pythereum - -**Status** -PV 52 (currently no interop w/ cpp/go) - -**What's the current status of what you're working on?** -We are currently in a major cleanup and refactoring phase with the goals to: - -* replace threading by an event loop architecture - -* add rlpx/devp2p https://github.com/heikoheiko/pydevp2p - -* split pyetherum up into three repositories, the base library (vm, chain, ...), the networking stack (should work w/o the pyeth lib), and the actual python based client - -**What progress has been made in the last two weeks?** -* devp2p discovery & rlpx is mostly done but not yet integrated with the pyethereum client - -* Solidity & ABI support were added - -* restructured vm tests - -**What are the next steps?** -refactoring sprint to restore interop based on the new architecture - -**Other news?** -Jannik is doing a two month internship in the Berlin office and helps to clean up and document the code. - -###POC8 Protocol -**What's the current status of what you're working on?** -PoC8 protocol is done. - -**What progress has been made in the last two weeks?** -PoC8 has been released. - -**What are the next steps?** -PoC9. - -###POC9 Protocol -**What's the current status of what you're working on?** -There are a number of changes that security auditors have suggested, and we are currently in the process of implementing them. We are also in the process of finalizing our PoW implementation. - -**What progress has been made in the last two weeks?** -Work on mining, and security audit meetings in which we discussed some of the upcoming protocol changes. - -**What are the next steps?** -Finish it. - -###Mix - -**What's the current status of what you're working on?** -First public version was released with poc8 recently. Currently working on new features. - -**What progress has been made in the last two weeks?** -Done major UI redesign for poc8 release. -Deploy contracts to network story has been implemented. -Various issues for Windows and OS X platforms resolved. - -**What are the next steps?** -Solidity source level debugging story. - -###Swarm - -**What's the current status of what you're working on?** -It is in an advanced prototype stage, fully functional, but generating much more than necessary traffic over the network. - -**What progress has been made in the last two weeks?** -Integration with the newest developments in the go client, especially, but not exclusively the new peer discovery system that would allow us to optimize network traffic and client load. - -**What are the next steps?** -Besides merging with the main development branch, which requires unification of command line and configuration options with Whisper (i.e. a similar set of configuration options should be available for Swarm), some documentation needs to be written in order to help people play with it. - -###Whisper - -**What's the current status of what you're working on?** - -**What progress has been made in the last two weeks?** - -**What are the next steps?** - -###Yellow Paper (recent changes) - -**What's the current status of what you're working on?** -We're almost done implementing the new RLPx protocol -in go-ethereum. - -**What progress has been made in the last two weeks?** -We have released the node discovery part of RLPx in PoC 8 -and it seems to be working for most people. -We ran various simulations of peer connecting strategies to study their influence on network well-formedness. https://docs.google.com/spreadsheets/d/1Xsg0367XibBCg1HegKoInrarLmU_ozwlBLPatv0hhEY/edit?usp=sharing - -**What are the next steps?** -We will implement the remaining parts of the protocol (Encryption -Handshake, authenticated packets) and define a peer selection -strategy. - -###Dev P2P - -**What's the current status of what you're working on?** -We're almost done implementing the new RLPx protocol -in go-ethereum. - -**What progress has been made in the last two weeks?** -We have released the node discovery part of RLPx in PoC 8 -and it seems to be working for most people. - -**What are the next steps?** -We will implement the remaining parts of the protocol (Encrytion -Handshake, authenticated packets) and define a peer selection -strategy. - -##Languages - -###Solidity - -**What's the current status of what you're working on?** -Solidity is now able to compile the multisig wallet contract (preliminary version: https://github.com/chriseth/dapp-bin/blob/compilingWallet/wallet/wallet_work_in_progres.sol). - -**What progress has been made in the last two weeks?** -In the last two weeks, we completed enums, visibility specifiers, accessors and a first byte array type. Especially the "external" visibility specifier and the byte array made it possible to "store" call data for later use and implement the forwarding feature of the multisig wallet. - -**What are the next steps?** -The next big features are array types and debugging support. In general, we will probably focus less on generic language features and more on usability. - -###Serpent - -**What's the current status of what you're working on?** -Serpent is close to full-featured, and is the backbone of many projects including augur and btcrelay. Strings and arrays are fully supported, as is the PoC8 contract ABI. - -**What progress has been made in the last two weeks?** -Testing and bug fixing mostly. Also, the pyethereum.tester environment has been substantially improved, making it highly interoperable with serpent functions (and solidity functions). - -**What are the next steps?** -Perhaps proper strong typing, we'll see. But ultimately I would like to see serpent become a community project, and have many others and not just myself maintaining and contributing code. - - -##Release - -###System testing project - -**What's the current status of what you're working on?** -* Infrastructure to automatically - + provision N (5..200) ec2 instances - + with the latest go-client from buildbot - + create deterministic configurations for all N clients - + run basic test scenarios - + log events in a computer readable json format - + collect logs in a central elasticsearch database - + automatically analyze the logs to decide on scenario success - -* Implemented scenarios: - + Start clients - + Connect clients - -**What progress has been made in the last two weeks?** -* finalized log event spec (for the first scenarios) https://github.com/ethereum/system-testing/wiki/Log-Events -* added support for multiple clients -* added go client -* first working scenarios (start/connect clients) - -**What are the next steps?** -* More Basic Scenarios - + Chain consensus scenario with mining clients - + TX propagation scenario - -* Automatic triggering of all scenarios based on new buildbot builds -* Automatic notification of devs in case of failures - -Later advanced scenarios as listed here: https://github.com/ethereum/system-testing/issues?q=is%3Aopen+is%3Aissue+label%3A%22test+scenario%22 - -###Testing - -**What's the current status of what you're working on?** -After the creation of the tools for the block tests, I am now actually writing different tests to ensure that all clients have the same definition on a valid block (in form of an RLP). - -**What progress has been made in the last two weeks?** -Beside the creation of some transaction tests, Block tests have been added (https://github.com/ethereum/tests/wiki/Block-Tests). - -**What are the next steps?** -I will add Blockchain tests, which probably will be the last type of tests. With this we have VM tests, state tests, transaction tests, block tests and blockchain tests. This will be sufficient to test almost eveything written in the YP. - -###Build System - -**What's the current status of what you're working on?** -The build system has received major upgrades and is really starting to cover every aspect of the build process and packaging of the different projects on all platforms. OSX users now benefit from pre-compiled "bottles" using brew along with readily available binaries of Mist and AlethZero for the less technically inclined. There are also packages for Ubuntu for both projects, although the upgrade Qt 5.4 still has unresolved issues. The build server also uses https only for obvious reasons. -Pull requests are now being checked across 7 different builders with even more to come, assuring much better quality code merges. - -**What progress has been made in the last two weeks?** -Half of what is mentioned above, let's say it's all recent enough :) Joris Bontje has also made a very nice looking and useful Buildboard at http://ethereum-buildboard.meteor.com/ - -**What are the next steps?** -Full integration tests, from contract deployments, transactions to those, and full assertions of expected results in a DApp's UI. This should be in place by the end of the week if not today the 24th. - -###JSON RPC - -**What's the current status of what you're working on?** - -**What progress has been made in the last two weeks?** - -**What are the next steps?** - -###Security Audit - -**What's the current status of what you're working on?** -We are currently in the middle of the security audit, our main auditor is looking at the design and the code base, further auditors are looking at focus topics like networking. We are in continuous exchange, responding to raised issues, providing further required information. - -**What progress has been made in the last two weeks?** -Ongoing development of the p2p/networking protocol and PoW algorithm required some recent rearrangement of the auditing schedule. Issues raised by auditors and submitted by bounty hunters have been mitigated. - -**What are the next steps?** -We will focus on the networking and p2p/networking protocol to minimize delays. - -###Dapps - -**What's the current status of what you're working on?** -Improving and streamlining the ethreuem.js APIand RPC endpoints. - -**What progress has been made in the last two weeks?** -Build a full featured whisper chat dapp and the wallet dapp interface. - -**What are the next steps?** -Finalising the wallet app, when the ethereum.js api and RPC is working properly. - -###ET Hash - -**What's the current status of what you're working on?** -We are on Revision 16 now. - -**What progress has been made in the last two weeks?** -There is now a go client, an opencl client. - -**What are the next steps?** -We are working on integration with the Go client and hopefully other clients prior to launch. - -###Vapor - -**What is it?** -Dapp runtime environment + contract browser webapp -think MIST built on node-ethereum - -**What's the current status of what you're working on?** -Early stages. Currently working on basic PoC. - -**What progress has been made in the last two weeks?** -Decided on tools and created multi-target build system. -Started RPC communication with node-ethereum. -Initial wireframes and logos generated by designer (Jef Cavens) - -**What are the next steps?** -Finish basic identity management and wallet view. -Package node-ethereum with native builds. -Build Dapp runtime environment. - -###Launch -**Launch Date?** -Ask me after Zug! - -**Which Apps will be available?** -No idea, I just got hired and I don't know anything yet! - -**Which Exchanges will be integrated?** -I'll ask George! - -##Leadership - -###Foundation - -**What's the current status of what you're working on?** -Currently we are focusing our attention on the Genesis launch, making sure that all the aspects involved in the release are taken care off. We are also experimenting with an open collaboration system designed to create the favorable conditions for developers to unleash their creativity and build amazing things with ethereum. - -**What progress has been made in the last two weeks?** -Intense brainstorming and discussions regarding the launch strategy and how to best nurture the growth of the ethereum community and ecosystem as a whole. - -**What are the next steps?** -Coordinate with comms, dev and the community in order to concretize the ethereum Genesis launch strategy. Regarding post-Genesis plans, there will be a number of exciting announcements coming in the following weeks ^_^ - -##Communications - -###Meetups - -**What's the current status of what you're working on?** -Comms has been focused on ethereum.org and bounty sites for the last month and a half. I was tasked with design and front end development. Have moved back to meetups full time now. Working on Ethereum 101, Genesis Block Party, regrouping and strategizing for launch. - -**What progress has been made in the last two weeks?** -Have moved away from design and development. Developed idea for the Genesis Block Party and have begun to work with meetup organizers to have a day of meetups around launch. Group skypes have occurred every thursday, ramping up to daily meetings. - -**What are the next steps?** -Concretize the Block Party, Finish the slides for 101 series. Get swag together for launch parties. - -###Upcoming Events - -**What's the current status of what you're working on?** -Working with meetup organizers on Genesis Block Parties - -**What progress has been made in the last two weeks?** -Working with Sarah Masare from Silicon Valley, Cameron and Peter Van Garderen from Vancouver on formalizing the Genesis Block Party. - -**What are the next steps?** -Confirm release date, get swag printed, have meetups sign on for block party - -###Comms - -**What's the current status of what you're working on?** -Currently the comms team is working on the new Ethereum website (which is our main focus until complete in the next week or so). We're also continuing maintain the various social media outlets Ethereum utilises to update and interface with the community to reach out to various companies, journalists etc to spread the word of Ethereum. Ken Kappler continues to write various tutorials (which will continue to be released as we reach stability) and content for the future Ethereum Academy website. Unfortunately Stephan Tual has been taken ill and will be unavailable for a week or so :( (get well soon!) - -**What progress has been made in the last two weeks?** -Having completed the bounty website just before, Ian and Konstantine are nearing completion of the Ethereum.org website with content now being provided by myself, Gavin and Vitalik. -In the last two weeks we have also been working on reaching out to various exchanges and possible parters for Ethereum as we move forward to the genesis release. - -**What are the next steps?** -Release the website! Continue reaching out to various entites that could potentially align themselves with Ethereum. We also have raw video footage that will be processed once Ian is free for doing the website design. - -###Ether Academy Website/Ethdev Website - -**What's the current status of what you're working on?** -Jr Bedard (of ether.fund) has been contracted to build a new Code Academy type site for teaching developers to build smart contracts. - -**What progress has been made in the last two weeks?** -Development is continuing nicely, the framework of handling user accounts is almost in place. - -**What are the next steps?** -Design decisions, content creation. - -###In the Media - -**What's the current status of what you're working on?** -Putting together various responses for journalists (spectator, coin telegraph etc) that have been in contact. Working with companies using ethereum for joint press releases/coverage. - -**What progress has been made in the last two weeks?** -We had a great article in Vice/Motherboard... (motherboard.vice.com/read/smart-contracts-sound-boring-but-theyre-more-disruptive-than-bitcoin - -**What are the next steps?** -ojn \ No newline at end of file diff --git a/pages/blog-and-notes/Template:-This-Week-in-Ethereum-w-YY.md b/pages/blog-and-notes/Template:-This-Week-in-Ethereum-w-YY.md deleted file mode 100644 index 8024ddac7..000000000 --- a/pages/blog-and-notes/Template:-This-Week-in-Ethereum-w-YY.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -name: This Week in Ethereum Template -category: ---- - -###Current Status - -### Protocol - -## Clients - -### AlethZero - -### Mist - -###pyethereum - -##Projects - -##People - -##In the Media - -##Upcoming Events - -### Meetups diff --git a/pages/blog-and-notes/This Week In Ethereum 47.2014.md b/pages/blog-and-notes/This Week In Ethereum 47.2014.md deleted file mode 100644 index 614edf743..000000000 --- a/pages/blog-and-notes/This Week In Ethereum 47.2014.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -name: This Week in Ethereum 47 -category: ---- - -###Current Status - -We are in the last days of preparing the POC-7 release. It is scheduled to ship on 21th of November. Latest stable release is Po6, testnet is reachable here, chain explorer here. Release of PoC8 is expected to be on christmas. Alpha releases are expected for mid January 2015. Release of the genesis is scheduled for March 2015. - -### Protocol -* Version update to eth:34 -* Blogs/Blooms/Recipes - There are often going to be situations where contracts need to record events that will be indexible/accessible/provable by light clients and these events are often fire-and-forget. - So filling a storage index for them is very wasteful. - We solve this by adding a an opcode LOG, whose purpose it is to create an event that gets put into the receipt trie of the block but is not stored in the state. The transactions trie is split up into two tries. - (1) transactions only - (2) medstate, gas, and logs (the recipes) - -* Exception severity uniformity - See: https://ethereum.etherpad.mozilla.org/14 - -## Clients -### AlethZero -* Commandline option -v now also reports protocol version -* Cleaned up make files -* ... - -### Mist -* Added LOG opcode -* Refactored XYZ - -###pyethereum -* Added LOG opcode -* Refactored logging to give log structured (machine readable) data - -##Projects - -* Continuous Integration: The bootstrapping node was extended to also host a "eth" protocol node. -* Serpent 2.0: was updated to feature function definitions and proper data structures -* Solidity: First compiled contracts are working and on the PoC7 testnet -* Security Audit - Results of a preliminary GO code audit were provided by Sergio. Jutta is working on contracting external auditors. -* Stress Testing: Sven is working on the infrastructure to run and analyze various scenarios in a synthetic test network. -* Berlin Office: Almost done, move in is scheduled for Monday. - -##People: -* Yann joined DEV Berlin and will work on the IDE -* Jutta joined and will work on security audits - -##In the Media -Worldwide coverage of Vitalik winning the 2014 Software Innovation Award at the World Technology Awards. - -##Upcoming Events - -### Meetups -* Berlin 18.11.14 -* NYC, Paris, Tokio - -###DEVCon-000 -The first Ethereum developer conference is happening during the next week in our new office in Berlin. diff --git a/pages/blog-and-notes/Todo-before-alpha.md b/pages/blog-and-notes/Todo-before-alpha.md deleted file mode 100644 index d4d0a113b..000000000 --- a/pages/blog-and-notes/Todo-before-alpha.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -name: TODO Before Alpha -category: ---- - -## Etereum P2P sub-protocol - -* Fix numbering in [Wire](https://github.com/ethereum/wiki/wiki/Ethereum-Wire-Protocol) protocol. -* Add `gasprice` message - * `[[id, price], [id, price], ...]` \ No newline at end of file diff --git a/pages/blog-and-notes/stubs/Which-Client?.md b/pages/blog-and-notes/stubs/Which-Client?.md deleted file mode 100644 index a72303a4f..000000000 --- a/pages/blog-and-notes/stubs/Which-Client?.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -name: Which Client? -category: ---- - ------ \ No newline at end of file diff --git a/pages/dapp-development/Contract-Metadata-Docs-(NatSpec,-ABI).md b/pages/dapp-development/Contract-Metadata-Docs-(NatSpec,-ABI).md deleted file mode 100644 index 4c845dd8d..000000000 --- a/pages/dapp-development/Contract-Metadata-Docs-(NatSpec,-ABI).md +++ /dev/null @@ -1,92 +0,0 @@ ---- -name: Contract Metadata Docs -category: ---- - -This is the main entry point for NatSpec and generally details a safe and efficient _standard_ for ethereum contract metadata distribution. - -By metadata we mean all information related to a contract that is thought to be relevant to and immutably linked to a specific version of a contract on the ethereum blockchain. -This includes: - -* Contract source code -* [ABI definition](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI) -* [NatSpec user doc](https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format#user-documentation) -* [NatSpec developer's doc](https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format#developer-documentation) - -These resources have their _standard specification_ in json format, ideally meant to be produced by IDE infrastructures or compilers directly. - -For instance, the [solidity](https://github.com/ethereum/wiki/wiki/Solidity-Tutorial) compiler offers a `doxygen` style way of specifying natspec with inline smart comments. Upon compilation it creates both NatSpec user doc as well ABI definition. But note that there is nothing inherently solidity specific about these data, and other contract languages are encouraged to implement their NatSpec/ABI support potentially with IDE-s extending it. - -Since DAPPs and IDEs will typically want to interact with these resources, standardising their deployment and distribution is important for a smooth ethereum experience. - -A specially important example of this is the **NatSpec transaction confirmation notice scheme**, which we will use to illustrate the point. However, the strategy described here trivially extends to arbitrary immutable metadata fixed to an ethereum contract. - -# Transaction Confirmation Notice - -The NatSpec user doc allows contract creators to attach custom confirmation notices to each method. -A powerful feature of NatSpec is to provide templating which allows parts of the user notice to be instantiated depending on the parameters of the actual transaction sent to the contract. - -Trusted ethereum client implementations are required to call back from their backend instantiating the natspec transaction notice from actual transaction data and present it to the user for confirmation. - -This serves as a first line of defense against illegitimate transactions sent by malicious DAPPs in the user's name. - -Surely, this is only feasible if -- the node can trust the authenticity of metadata sources. -- nodes have secure reliable access to the metadata resources - -Let's see how this is achieved. - -## Metadata Authentication - -**Proposal** -The metadocs are assumed to be in a single JSON structure called `cmd` file, that stands for _contract metadata doc_. - -The `cmd` file's content is hashed and content hash is registered on a name registry via a contract on the ethereum blockchain under the code hash, see https://github.com/ethereum/dapp-bin/blob/master/NatSpecReg/contract.sol _Registering_ in this context will simply mean a key value pair is recorded in an immutable contract storage as a result of a transaction sent to the registry contract. - -This provides a public immutable authentication for contract metadata, since: -- the authenticity of the link between the contract and metadata is secured by ethereum consensus -- the authenticity of actual metadata content is secured by content hashing -- the binding is tamper proof - - -DAPP IDE environments are supposed to support the functionality, that when you create a contract, all its standard metadata is -- bundled in a single `cmd` json file -- compiled source code is keccak hashed -> `Sha3()` -- `cmd` json is keccak hashed -> `Sha3()` -- the metadata is registered with the contract by sending a transaction to a trusted name registry. The transaction simply records `Sha3() -> Sha3()` as a key value pair in contract storage. - -In order to avoid malicious agents hijacking metadata by overwriting the namereg entry, we propose the following business process: - -- the link should be registered before a contract is deployed and is immutable from then on. -- before the corresponding contract is deployed, we check if the correct metadata bundle is found in the registry and confirmed to a satisfying level of certainty (X blocks). - -How it looks like in `Alethzero` is illustrated [here]|( -https://github.com/ethereum/wiki/wiki/NatSpec-Example) - -## Metadata Access - -In order to provide a robust (failure resistant, 100% uptime) service, decentralised file storage services can and will be used. In the case of content addressed systems like Swarm, accessing and fetching the resource you will only need the `cmd` content hash (using `BZZHASH(`). - -Until that point is reached, we will fall back to using HTTP distribution. To enable this we will include one or many URLHint contracts, which provide hints of URLs that allow downloading of particular content hashes. Find the contract in dapp-bin. - -The content downloaded should be treated in many ways (and hashed) to discover what the content is. Possible ways include base 64 encoding, hex encoding and raw, and any content-cropping needed (e.g. a HTML page should have everything up to body tags removed). - -It will be up to the dapp/content uploader to keep URLHint entries updated. - -The address of the URLHint contract will be specified on an ad-hoc basis and users will be able to enter additional ones into their browser. - -This functionality of uploading and registering location is supposed to be also supported by IDE and dev infrastructures. Developers (or IDE) are encouraged to register cmd location _before_ content hash registration (and therefore before actual contract creation) in order to avoid metadata hijacking. Note that if content hash registration is correct, hijacking the location cannot allow malicious content (since content hash authenticates the `cmd`), however it can still prevent your metadata from being accessible. Therefore -- the url-hint contract storage should be by definition immutable -- content-hash to url-hint should be registered before contract creation - -(surely with old web urls, we are always exposed to server failure/hacking, etc) - -Read more [here](https://github.com/ethereum/wiki/wiki/NatSpec-Determination) - -## Name registry contracts - -Interoperability requires that clients know where to look to resolve a contract's metadata, i.e., which name registry to use. Currently, we solve this by -- creating the two registry contracts after the genesis block -- and hardwiring their addresses in the client code (e.g., in the natspec transaction confirmation notice module on the client side and the deployment module on the dev/IDE side). - - diff --git a/pages/dapp-development/Dapp-Developer-Resources.md b/pages/dapp-development/Dapp-Developer-Resources.md deleted file mode 100644 index 531ce5405..000000000 --- a/pages/dapp-development/Dapp-Developer-Resources.md +++ /dev/null @@ -1,17 +0,0 @@ -As a Ðapp developer you have three main resources which allow Ðapp development. - -### Main Resources - -- [Web3 JavaScript API](https://github.com/ethereum/wiki/wiki/JavaScript-API) - This is the main JavaScript SDK to use when you want to interact with a nodes API -- [JSON RPC API](https://github.com/ethereum/wiki/wiki/JSON-RPC) - This is the low level JSON RPC 2.0 interface to interface with a node. This API is used by the [Web3 JavaScript API](https://github.com/ethereum/wiki/wiki/JavaScript-API). -- [Solidity Documentation](https://solidity.readthedocs.io/en/latest/) - Solidity is the Ethereum developed Smart Contract language, which compiles to EVM (Ethereum Virtual Machine) opcodes. - -### Other Resources: - -- [Standardized Contract APIs](https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs) - Standard contract API, which should be used to make some contract types accessible by other Ðapps. (Not yet finalised) -- [Useful Ðapp Patterns](https://github.com/ethereum/wiki/wiki/Useful-Ðapp-Patterns) - Code snippets which are useful for Ðapp development. -- [Dapp using Meteor](https://github.com/ethereum/wiki/wiki/Dapp-using-Meteor) - This short tutorial gives an intro on how to start building a Ðapp using [Meteor](https://www.meteor.com), and also why Meteor is a good fit for Ðapps. - -### Useful read -- [FAQ](https://github.com/ethereum/wiki/wiki/FAQ) - Collection of links, useful for understanding the Ethereum eco system. -- [Glossary](https://github.com/ethereum/wiki/wiki/Glossary) - Great explanation of Blockchain related terms. diff --git a/pages/dapp-development/Dapp-using-Meteor.md b/pages/dapp-development/Dapp-using-Meteor.md deleted file mode 100644 index d198e48c0..000000000 --- a/pages/dapp-development/Dapp-using-Meteor.md +++ /dev/null @@ -1,209 +0,0 @@ ---- -name: DAPP Using Meteor -category: ---- - -This tutorial will show you how to setup a Meteor app to be used as a Ðapp and probably answer a few questions on why Meteor should used. - -1. [Create your Ðapp](#create-your-%C3%90app) -2. [Start your Ðapp](#start-your-%C3%90app) -3. [Connect your Ðapp](#connect-your-%C3%90app) -4. [Run your Ðapp](#run-your-%C3%90app) -5. [Add Ðapp styles](#add-%C3%90app-styles) -6. [Using ethereum:elements](#using-ethereumelements) -7. [Ðapp code structure](#%C3%90app-code-structure) -8. [Bundle your Ðapp](#bundle-your-%C3%90app) - - -## FAQ - -### Isn't Meteor a full stack framework, how does that fit into Ðapp development - -True, Meteor is a full stack framework and its main improvement is realtime web applications, but Meteor is also the first framework (i know of), which fully embraced *s*ingle *p*age *a*pp (SPA) development and provided all necessary tools. - -5 reasons why Meteor is a perfect fit: - -1. Its purely written in JS and has all the tools a SPA needs (Templating engine, Model, on-the-fly compiling, bundling) -2. You get a development environment, which has live reload, CSS injection and support for many pre-compilers (LESS, Coffeescript, etc) out of the box -3. You can get all frontend code as single `index.html` with one `js` and `css` file plus your assets, using [meteor-build-client](https://github.com/frozeman/meteor-build-client). You can then host it everywhere or simple run the `index.html` itself or distribute it later on *swarm*. -4. It embraces full reactivity, which make building consistent interface much easier (similar to angualr.js `$scope` or binding) -5. It has a great model called Minimongo, which gives you a mongoDB like interface for a reactive in-memory database, which can also be [auto-persistet to localstorage](https://atmospherejs.com/frozeman/persistent-minimongo) or [indexedDB](https://atmospherejs.com/frozeman/persistent-minimongo2) - -### Do i need to host my Ðapp on a server? - -No, using [meteor-build-client](https://github.com/frozeman/meteor-build-client) you can get all the static assets of you Ðapp to run without any server, though if you use a router like [iron-](https://atmospherejs.com/iron/router) or [flow-router](https://atmospherejs.com/meteorhacks/flow-router), you need to use hash (`index.html#!/mypath`) routes instead of clean HTML5 pushstate routes. - -*** - -## Create your Ðapp - -Install Meteor if don't have already: - -```bash -$ curl https://install.meteor.com/ | sh -``` - -Then create an app: -```bash -$ meteor create myDapp -$ cd myDapp -``` - -Next add the web3 package: -```bash -$ meteor add ethereum:web3 -``` - -I recommend also to add the following packages: - -- [ethereum:dapp-styles](https://atmospherejs.com/ethereum/dapp-styles) - The LESS/CSS framework which gives your dapp a nice Mist-consistent look. -- [ethereum:tools](https://atmospherejs.com/ethereum/tools) - This package gives you the `EthTools` object with a set of formatting an conversion functions and template helpers for ether. -- [ethereum:elements](https://atmospherejs.com/ethereum/elements) - A set of interface elements specifically made for ethereum, see this [Demo](http://ethereum-elements.meteor.com) for more. -- [ethereum:accounts](https://atmospherejs.com/ethereum/accounts) - Gives you the reactive `EthAccounts` collection with all current available ethereum accounts, where balances will be automatically updated. -- [ethereum:blocks](https://atmospherejs.com/ethereum/blocks) - Gives you the reactive `EthBlocks` collection with the latest 50 blocks. To get the lastest block use `EthBlocks.latest` (It will also have the latest default gasPrice) -- [frozeman:template-var](https://atmospherejs.com/frozeman/template-var) - Gives you the `TemplateVar` object, that allows you to set reactive variables, which are template instance specific. See the [readme](https://atmospherejs.com/frozeman/template-var) for more. -- [frozeman:persistent-minimongo2](https://atmospherejs.com/frozeman/persistent-minimongo2) - Allows you to auto persist your minimongo collection in local storage - - -## Start your Ðapp - -### A short excursion into Meteors folder structure - -Meteor doesn't force you to have a specifc folder structure, though some folders have specifc meaning and will be treated differently when bundling/running your application. - -Folders with specific treatment -- `client` - files in a folder called `client` will only be loaded by the client part of your app and as we are building a Ðapp, thats where most of our files go. -- `lib` - files in folders called `lib` will load before other files in the same folder. This is an ideal place your init files, libraries, or ethereum specifc files. -- `public` - a folder called `public` contains assets meteor will make available on the root of your webserver (or later bundled Ðapp) -- There are a few more specifc folders like `server`, `tests`, `packages`, etc. If you want to get to know them take a look at the [Meteor docs](http://docs.meteor.com/#/full/structuringyourapp) - -So to build a Ðapp we ideally create the following folder structure in our `myDapp` folder: - -``` -- myDapp - - client - - lib - - myDapp.html - - myDapp.js - - myDapp.css - - public -``` - -**Note** The community provides also Meteor Ðapp Boilerplates like this on from Nick Dodson: https://github.com/SilentCicero/meteor-dapp-boilerplate - -### Connect your Ðapp -To connect our dapp we need to start `geth` with the right CORS headers in another terminal: - -```bash -$ geth --rpc --rpccorsdomain "http://localhost:3000" -``` - -We also need to set the provider. Ideally we create a file in our lib folder called `init.js` and add the following line: - -```js -// set providor -if(!web3.currentProvider) // make sure we don't overwrite a provider set by Mist later on - web3.setProvider(new web3.providers.HttpProvider("http://localhost:8545")); -``` - -### Run your Ðapp - -Now we can run our Ðapp by simply running: - -```bash -$ meteor -``` - -If we go to `http://localhost:3000`, we should see a website appear and if we open the browser console we can use the web3 object to query the geth node: - -```js -> web3.eth.accounts -['0xfff2b43a7433ddf50bb82227ed519cd6b142d382'] -``` - -## Add Ðapp styles - -If you want your Ðapp to nicely fit later into Mist and have follow the official look use the [dapp-styles css css/less framework](https://atmospherejs.com/ethereum/dapp-styles). - -*Note that they are under heavy development and the class names and elements may change.* - -To add it simple add the following packages to your Ðapp: - -```bash -$ meteor add less -$ meteor add ethereum:dapp-styles -``` - -Now rename you `myDapp.css` to `myDapp.less` and add the following line inside: - -```css -// libs -@import '{ethereum:dapp-styles}/dapp-styles.less'; -``` - -Now you can use all dapp-styles classes and also overwrite all variables of the framework. You can find them [in the repo](https://github.com/ethereum/dapp-styles/blob/master/constants.import.less). Overwrite them by copying them to your `myDapp.less` file and set different values. - -## Using ethereum packages - -To make your live as a Ðapp developer easier we provide some packages that help you build Ðapps faster. - -If you add the recommended packages above you should have the [ethereum:tools](https://atmospherejs.com/ethereum/tools), [accounts](https://atmospherejs.com/ethereum/accounts) and [ethereum:blocks](https://atmospherejs.com/ethereum/blocks) packages available. - -These 3 packages give you the `EthTools`, `EthAccounts` and `Ethblocks` objects, which give you formatter functions, a collection with the accounts from `web3.eth.accounts` (with auto updated balance) and a collection of the last 50 blocks. - -Most of these functions are reactive so they should make building interfaces a breeze. - -### Example usage - -If you look into you `myDapp.html` you will find the `hello` template. -Just add a helper called `{{currentBlock}}` some where between the `` tags. - -Now open the `myDapp.js` and add after the `counter: function..` the `currentBlock` helper: -```js -Template.elements.helpers({ - counter: function () { - ... - }, - currentBlock: function(){ - return EthBlocks.latest.number; - } - }); -``` - -Then initialize EthBlocks by adding `EthBlocks.init();` after `Session.setDefault('counter', 0);` - -If you now check your Ðapp in the browser you should see the latest block number, which will increase once you mine. - - -*For more examples please checkout the packages readmes and the [demo](http://ethereum-elements.meteor.com) ([source](https://github.com/frozeman/meteor-ethereum-elements-demo)) for more.* - -## Ðapp code structure - -*This tutorial won't go into building apps with Meteor. For this please refer to the [Meteor's tutorials](https://www.meteor.com/tutorials/blaze/creating-an-app), [A list of good resources](https://www.meteor.com/tools/resources), [EventMinded](https://www.eventedmind.com) (payed tutorials) or books like [Building Single-page Web Apps with Meteor](https://www.packtpub.com/web-development/building-single-page-web-apps-meteor) or [Discover Meteor](http://discovermeteor.com).* - - -TODO -Short: -- put ethereum related stuff into `client/lib/ethereum/somefile.js` -- use `myCollection.observe({added: func, changed: func, removed: func})` to communicate to ethereum, keep ethereum logic out of your app as much as possible. This way you just write and read from your reactive collections and the observe functions will handle the rest (e.g. sendTransactions) -- Filters etc will add logs etc to your collections. So you keep all the callback mess out of your app logic. - -For an example see the [Ethereum-Wallet](https://github.com/ethereum/meteor-dapp-wallet). - -## Bundle your Ðapp - -To bundle your Ðapp into a local standalone file use [meteor-build-client](https://github.com/frozeman/meteor-build-client): - -```bash -$ npm install -g meteor-build-client -$ cd myDapp -$ meteor-build-client ../build --path "" -``` - -This will put your Ðapps static files into the build folder, above your `myDapp` folder. - -The last option `--path` will make the linking of all files relative, allowing you to start the app by simply clicking the `build/index.html`. - -Be aware that when running your app on the `file://` protocol, you won't be able to use client side routing, due to web security. Later in mist you will be able to use client side routing, as dapps are severed over the `eth://` protocol. - -In the future you will be able to simply upload your Ðapp on swarm. \ No newline at end of file diff --git a/pages/dapp-development/Ethereum-Contract-ABI.md b/pages/dapp-development/Ethereum-Contract-ABI.md deleted file mode 100644 index 1bec785cd..000000000 --- a/pages/dapp-development/Ethereum-Contract-ABI.md +++ /dev/null @@ -1,383 +0,0 @@ ---- -name: Ethereum Contract ABI -category: ---- - -# Functions - -## Basic design - -We assume the ABI is strongly typed, known at compilation time and static. No introspection mechanism will be provided. We assert that all contracts will have the interface definitions of any contracts they call available at compile-time. - -This specification does not address contracts whose interface is dynamic or otherwise known only at run-time. Should these cases become important they can be adequately handled as facilities built within the Ethereum ecosystem. - -## Function Selector - -The first four bytes of the call data for a function call specifies the function to be called. It is the -first (left, high-order in big-endian) four bytes of the Keccak (SHA-3) hash of the signature of the function. The signature is defined as the canonical expression of the basic prototype, i.e. -the function name with the parenthesised list of parameter types. Parameter types are split by a single comma - no spaces are used. - -## Argument Encoding - -Starting from the fifth byte, the encoded arguments follow. This encoding is also used in other places, e.g. the return values and also event arguments are encoded in the same way, without the four bytes specifying the function. - -### Types - -The following elementary types exist: -- `uint`: unsigned integer type of `N` bits, `0 < N <= 256`, `N % 8 == 0`. e.g. `uint32`, `uint8`, `uint256`. -- `int`: two's complement signed integer type of `N` bits, `0 < N <= 256`, `N % 8 == 0`. -- `address`: equivalent to `bytes20`, except for the assumed interpretation and language typing. -- `uint`, `int`: synonyms for `uint256`, `int256` respectively (not to be used for computing the function selector). -- `bool`: equivalent to `uint8` restricted to the values 0 and 1 -- `realx`: fixed-point signed number of `N+M` bits, `0 < N + M <= 256`, `N % 8 == M % 8 == 0`. Corresponds to the int256 equivalent binary value divided by `2^M`. -- `urealx`: unsigned variant of `realx`. -- `real`, `ureal`: synonyms for `real128x128`, `ureal128x128` respectively (not to be used for computing the function selector). -- `bytes`: binary type of `N` bytes, `N >= 0`. - -The following (fixed-size) array type exists: -- `[N]`: a fixed-length array of the given fixed-length type. - -The following non-fixed-size types exist: -- `bytes`: dynamic sized byte sequence. -- `string`: dynamic sized unicode string assumed to be UTF-8 encoded. -- `[]`: a variable-length array of the given fixed-length type. - -### Formal Specification of the Encoding - -We will now formally specify the encoding, such that it will have the following -properties, which are especially useful if some arguments are nested arrays: - -**Properties:** - -1. The number of reads necessary to access a value is at most the depth of the -value inside the argument array structure, i.e. four reads are needed to -retrieve `a_i[k][l][r]`. In a previous version of the ABI, the number of reads scaled -linearly with the total number of dynamic parameters in the worst case. - -2. The data of a variable or array element is not interleaved with other data -and it is relocatable, i.e. it only uses relative "addresses" - -We distinguish static and dynamic types. Static types are encoded in-place and dynamic types are encoded at a separately allocated location after the current block. - -**Definition:** The following types are called "dynamic": -* `bytes` -* `string` -* `T[]` for any `T` -* `T[k]` for any dynamic `T` and any `k > 0` - -All other types are called "static". - -**Definition:** `len(a)` is the number of bytes in a binary string `a`. -The type of `len(a)` is assumed to be `uint256`. - -We define `enc`, the actual encoding, as a mapping of values of the ABI types to binary strings such -that `len(enc(X))` depends on the value of `X` if and only if the type of `X` -is dynamic. - -**Definition:** For any ABI value `X`, we recursively define `enc(X)`, depending -on the type of `X` being - -- `T[k]` for any `T` and `k`: - - `enc(X) = head(X[0]) ... head(X[k-1]) tail(X[0]) ... tail(X[k-1])` - - where `head` and `tail` are defined for `X[i]` being of a static type as - `head(X[i]) = enc(X[i])` and `tail(X[i]) = ""` (the empty string) - and as - `head(X[i]) = enc(len(head(X[0]) ... head(X[k-1]) tail(X[0]) ... tail(X[i-1])))` - `tail(X[i]) = enc(X[i])` - otherwise. - - Note that in the dynamic case, `head(X[i])` is well-defined since the lengths of - the head parts only depend on the types and not the values. Its value is the offset - of the beginning of `tail(X[i])` relative to the start of `enc(X)`. - -- `T[]` where `X` has `k` elements (`k` is assumed to be of type `uint256`): - - `enc(X) = enc(k) enc([X[1], ..., X[k]])` - - i.e. it is encoded as if it were an array of static size `k`, prefixed with - the number of elements. - -- `bytes`, of length `k` (which is assumed to be of type `uint256`): - - `enc(X) = enc(k) pad_right(X)`, i.e. the number of bytes is encoded as a - `uint256` followed by the actual value of `X` as a byte sequence, followed by - the minimum number of zero-bytes such that `len(enc(X))` is a multiple of 32. - -- `string`: - - `enc(X) = enc(enc_utf8(X))`, i.e. `X` is utf-8 encoded and this value is interpreted as of `bytes` type and encoded further. Note that the length used in this subsequent encoding is the number of bytes of the utf-8 encoded string, not its number of characters. - -- `uint`: `enc(X)` is the big-endian encoding of `X`, padded on the higher-order (left) side with zero-bytes such that the length is a multiple of 32 bytes. -- `address`: as in the `uint160` case -- `int`: `enc(X)` is the big-endian two's complement encoding of `X`, padded on the higher-oder (left) side with `0xff` for negative `X` and with zero bytes for positive `X` such that the length is a multiple of 32 bytes. -- `bool`: as in the `uint8` case, where `1` is used for `true` and `0` for `false` -- `realx`: `enc(X)` is `enc(X * 2**M)` where `X * 2**M` is interpreted as a `int256`. -- `real`: as in the `real128x128` case -- `urealx`: `enc(X)` is `enc(X * 2**M)` where `X * 2**M` is interpreted as a `uint256`. -- `ureal`: as in the `ureal128x128` case -- `bytes`: `enc(X)` is the sequence of bytes in `X` padded with zero-bytes to a length of 32. - -Note that for any `X`, `len(enc(X))` is a multiple of 32. - -## Function Selector and Argument Encoding - -All in all, a call to the function `f` with parameters `a_1, ..., a_n` is encoded as - - `function_selector(f) enc([a_1, ..., a_n])` - -and the return values `v_1, ..., v_k` of `f` are encoded as - - `enc([v_1, ..., v_k])` - -where the types of `[a_1, ..., a_n]` and `[v_1, ..., v_k]` are assumed to be -fixed-size arrays of length `n` and `k`, respectively. Note that strictly, -`[a_1, ..., a_n]` can be an "array" with elements of different types, but the -encoding is still well-defined as the assumed common type `T` (above) is not -actually used. - -## Examples - -Given the contract: - -```js -contract Foo { - function bar(real[2] xy) {} - function baz(uint32 x, bool y) returns (bool r) { r = x > 32 || y; } - function sam(bytes name, bool z, uint[] data) {} -} -``` - -Thus for our `Foo` example if we wanted to call `baz` with the parameters `69` and `true`, we would pass 68 bytes total, which can be broken down into: - -- `0xcdcd77c0`: the Method ID. This is derived as the first 4 bytes of the Keccak hash of the ASCII form of the signature `baz(uint32,bool)`. -- `0x0000000000000000000000000000000000000000000000000000000000000045`: the first parameter, a uint32 value `69` padded to 32 bytes -- `0x0000000000000000000000000000000000000000000000000000000000000001`: the second parameter - boolean `true`, padded to 32 bytes - -In total: -``` -0xcdcd77c000000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000001 -``` -It returns a single `bool`. If, for example, it were to return `false`, its output would be the single byte array `0x0000000000000000000000000000000000000000000000000000000000000000`, a single bool. - -If we wanted to call `bar` with the argument `[2.125, 8.5]`, we would pass 68 bytes total, broken down into: -- `0x3e279860`: the Method ID. This is derived from the signature `bar(real128x128[2])`. Note that `real` is substituted for its canonical representation `real128x128`. -- `0x0000000000000000000000000000000240000000000000000000000000000000`: the first part of the first parameter, a real128x128 value `2.125`. -- `0x0000000000000000000000000000000880000000000000000000000000000000`: the first part of the first parameter, a real128x128 value `8.5`. - -In total: -``` -0x3e27986000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000880000000000000000000000000000000 -``` - -If we wanted to call `sam` with the arguments `"dave"`, `true` and `[1,2,3]`, we would pass 292 bytes total, broken down into: -- `0x8FF261B0`: the Method ID. This is derived from the signature `sam(bytes,bool,uint256[])`. Note that `uint` is substituted for its canonical representation `uint256`. -- `0x0000000000000000000000000000000000000000000000000000000000000060`: the location of the data part of the first parameter (dynamic type), measured in bytes from the start of the arguments block. In this case, `0x60`. -- `0x0000000000000000000000000000000000000000000000000000000000000001`: the second parameter: boolean true. -- `0x00000000000000000000000000000000000000000000000000000000000000c0`: the location of the data part of the third parameter (dynamic type), measured in bytes. In this case, `0xc0`. -- `0x0000000000000000000000000000000000000000000000000000000000000004`: the data part of the first argument, it starts with the length of the byte array in elements, in this case, 4. -- `0x6461766500000000000000000000000000000000000000000000000000000000`: the contents of the first argument: the UTF-8 (equal to ASCII in this case) encoding of `"dave"`, padded on the right to 32 bytes. -- `0x0000000000000000000000000000000000000000000000000000000000000003`: the data part of the third argument, it starts with the length of the array in elements, in this case, 3. -- `0x0000000000000000000000000000000000000000000000000000000000000001`: the first entry of the third parameter. -- `0x0000000000000000000000000000000000000000000000000000000000000002`: the second entry of the third parameter. -- `0x0000000000000000000000000000000000000000000000000000000000000003`: the third entry of the third parameter. - -In total: -``` -0x8FF261B00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003 -``` - - -### Use of Dynamic Types - -A call to a function with the signature `f(uint,uint32[],bytes10,bytes)` with values `(0x123, [0x456, 0x789], "1234567890", "Hello, world!")` is encoded in the following way: - -We take the first four bytes of `sha3("f(uint256,uint32[],bytes10,bytes)")`, i.e. `0x8be65246`. -Then we encode the head parts of all four arguments. For the static types `uint256` and `bytes10`, these are directly the values we want to pass, whereas for the dynamic types `uint32[]` and `bytes`, we use the offset in bytes to the start of their data area, measured from the start of the value encoding (i.e. not counting the first four bytes containing the hash of the function signature). These are: - - - `0x0000000000000000000000000000000000000000000000000000000000000123` (`0x123` padded to 32 bytes) - - `0x0000000000000000000000000000000000000000000000000000000000000080` (offset to start of data part of second parameter, 4*32 bytes, exactly the size of the head part) - - `0x3132333435363738393000000000000000000000000000000000000000000000` (`"1234567890"` padded to 32 bytes on the right) - - `0x00000000000000000000000000000000000000000000000000000000000000e0` (offset to start of data part of fourth parameter = offset to start of data part of first dynamic parameter + size of data part of first dynamic parameter = 4*32 + 3*32 (see below)) - -After this, the data part of the first dynamic argument, `[0x456, 0x789]` follows: - - - `0x0000000000000000000000000000000000000000000000000000000000000002` (number of elements of the array, 2) - - `0x0000000000000000000000000000000000000000000000000000000000000456` (first element) - - `0x0000000000000000000000000000000000000000000000000000000000000789` (second element) - -Finally, we encode the data part of the second dynamic argument, `"Hello, world!"`: - - - `0x000000000000000000000000000000000000000000000000000000000000000d` (number of elements (bytes in this case): 13) - - `0x48656c6c6f2c20776f726c642100000000000000000000000000000000000000` (`"Hello, world!"` padded to 32 bytes on the right) - -All together, the encoding is (spaces added for clarity): - -`0x8be65246 0000000000000000000000000000000000000000000000000000000000000123 0000000000000000000000000000000000000000000000000000000000000080 3132333435363738393000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000e0 0000000000000000000000000000000000000000000000000000000000000002 0000000000000000000000000000000000000000000000000000000000000456 0000000000000000000000000000000000000000000000000000000000000789 000000000000000000000000000000000000000000000000000000000000000d 48656c6c6f2c20776f726c642100000000000000000000000000000000000000` - - -# Events - -Events are an abstraction of the Ethereum logging/event-watching protocol. Log entries provide the contract's address, a series of up to four topics and some arbitrary length binary data. Events leverage the existing function ABI in order to interpret this (together with an interface spec) as a properly typed structure. - -Given an event name and series of event parameters, we split them into two sub-series: those which are indexed and those which are not. Those which are indexed, which may number up to 3, are used alongside the Keccak hash of the event signature to form the topics of the log entry. Those which as not indexed form the byte array of the event. - -In effect, a log entry using this ABI is described as: - -- `address`: the address of the contract (intrinsically provided by Ethereum); -- `topics[0]`: `keccak(EVENT_NAME+"("+EVENT_ARGS.map(canonical_type_of).join(",")+")")` (`canonical_type_of` is a function that simply returns the canonical type of a given argument, e.g. for `uint indexed foo`, it would return `uint256`). If the event is declared as `anonymous` the `topics[0]` is not generated; -- `topics[n]`: `EVENT_INDEXED_ARGS[n - 1]` (`EVENT_INDEXED_ARGS` is the series of `EVENT_ARGS` that are indexed); -- `data`: `abi_serialise(EVENT_NON_INDEXED_ARGS)` (`EVENT_NON_INDEXED_ARGS` is the series of `EVENT_ARGS` that are not indexed, `abi_serialise` is the ABI serialisation function used for returning a series of typed values from a function, as described above). - -# JSON - -The JSON format for a contract's interface is given by an array of function and/or event descriptions. A function description is a JSON object with the fields: - -- `type`: `"function"` or `"constructor"` (can be omitted, defaulting to function); -- `name`: the name of the function (only present for function types); -- `inputs`: an array of objects, each of which contains: -* `name`: the name of the parameter; -* `type`: the canonical type of the parameter. -- `outputs`: an array of objects similar to `inputs`, can be omitted. - -An event description is a JSON object with fairly similar fields: - -- `type`: always `"event"` -- `name`: the name of the event; -- `inputs`: an array of objects, each of which contains: -* `name`: the name of the parameter; -* `type`: the canonical type of the parameter. -* `indexed`: `true` if the field is part of the log's topics, `false` if it one of the log's data segment. -* `anonymous`: `true` if the event was declared as `anonymous`. - -For example, - -```js -contract Test { -function Test(){ b = 0x12345678901234567890123456789012; } -event Event(uint indexed a, bytes32 b) -event Event2(uint indexed a, bytes32 b) -function foo(uint a) { Event(a, b); } -bytes32 b; -} -``` - -would result in the JSON: - -```js -[{ -"type":"event", -"inputs": [{"name":"a","type":"uint256","indexed":true},{"name":"b","type":"bytes32","indexed":false}], -"name":"Event" -}, { -"type":"event", -"inputs": [{"name":"a","type":"uint256","indexed":true},{"name":"b","type":"bytes32","indexed":false}], -"name":"Event2" -}, { -"type":"event", -"inputs": [{"name":"a","type":"uint256","indexed":true},{"name":"b","type":"bytes32","indexed":false}], -"name":"Event2" -}, { -"type":"function", -"inputs": [{"name":"a","type":"uint256"}], -"name":"foo", -"outputs": [] -}] -``` - -# Example Javascript Usage - -```js -var Test = eth.contract( -[{ -"type":"event", -"inputs": [{"name":"a","type":"uint256","indexed":true},{"name":"b","type":"bytes32","indexed":false}], -"name":"Event" -}, { -"type":"event", -"inputs": [{"name":"a","type":"uint256","indexed":true},{"name":"b","type":"bytes32","indexed":false}], -"name":"Event2" -}, { -"type":"function", -"inputs": [{"name":"a","type":"uint256"}], -"name":"foo", -"outputs": [] -}]); -var theTest = new Test(addrTest); - -// examples of usage: -// every log entry ("event") coming from theTest (i.e. Event & Event2): -var f0 = eth.filter(theTest); -// just log entries ("events") of type "Event" coming from theTest: -var f1 = eth.filter(theTest.Event); -// also written as -var f1 = theTest.Event(); -// just log entries ("events") of type "Event" and "Event2" coming from theTest: -var f2 = eth.filter([theTest.Event, theTest.Event2]); -// just log entries ("events") of type "Event" coming from theTest with indexed parameter 'a' equal to 69: -var f3 = eth.filter(theTest.Event, {'a': 69}); -// also written as -var f3 = theTest.Event({'a': 69}); -// just log entries ("events") of type "Event" coming from theTest with indexed parameter 'a' equal to 69 or 42: -var f4 = eth.filter(theTest.Event, {'a': [69, 42]}); -// also written as -var f4 = theTest.Event({'a': [69, 42]}); - -// options may also be supplied as a second parameter with `earliest`, `latest`, `offset` and `max`, as defined for `eth.filter`. -var options = { 'max': 100 }; -var f4 = theTest.Event({'a': [69, 42]}, options); - -var trigger; -f4.watch(trigger); - -// call foo to make an Event: -theTest.foo(69); - -// would call trigger like: -//trigger(theTest.Event, {'a': 69, 'b': '0x12345678901234567890123456789012'}, n); -// where n is the block number that the event triggered in. -``` - -Implementation: - -```js -// e.g. f4 would be similar to: -web3.eth.filter({'max': 100, 'address': theTest.address, 'topics': [ [69, 42] ]}); -// except that the resultant data would need to be converted from the basic log entry format like: -{ - 'address': theTest.address, - 'topics': [web3.sha3("Event(uint256,bytes32)"), 0x00...0045 /* 69 in hex format */], - 'data': '0x12345678901234567890123456789012', - 'number': n -} -// into data good for the trigger, specifically the three fields: - Test.Event // derivable from the first topic - {'a': 69, 'b': '0x12345678901234567890123456789012'} // derivable from the 'indexed' bool in the interface, the later 'topics' and the 'data' - n // from the 'number' -``` - -Event result: -```js -[ { - 'event': Test.Event, - 'args': {'a': 69, 'b': '0x12345678901234567890123456789012'}, - 'number': n - }, - { ... - } ... -] -``` - -### JUST DONE! [develop branch] -**NOTE: THIS IS OLD - IGNORE IT unless reading for historical purposes** - -- Internal LogFilter, log-entry matching mechanism and eth_installFilter needs to support matching multiple values (OR semantics) *per* topic index (at present it will only match topics with AND semantics and set-inclusion, not per-index). - -i.e. at present you can only ask for each of a number of given topic values to be matched throughout each topic: - -- `topics: [69, 42, "Gav"]` would match against logs with 3 topics `[42, 69, "Gav"]`, `["Gav", 69, 42]` but **not** against logs with topics `[42, 70, "Gav"]`. - -we need to be able to provide one of a number of topic values, and, each of these options for each topic index: - -- `topics: [[69, 42], [] /* anything */, "Gav"]` should match against logs with 3 topics `[42, 69, "Gav"]`, `[42, 70, "Gav"]` but **not** against `["Gav", 69, 42]`. \ No newline at end of file diff --git a/pages/dapp-development/Ethereum-Development-Tutorial.md b/pages/dapp-development/Ethereum-Development-Tutorial.md deleted file mode 100644 index 8706a29fe..000000000 --- a/pages/dapp-development/Ethereum-Development-Tutorial.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -name: Ethereum Development Tutorial -category: ---- - -The purpose of this page is to serve as an introduction to the basics of Ethereum that you will need to understand from a development standpoint, in order to produce contracts and decentralized applications. For a general introduction to Ethereum, see [the white paper](https://github.com/ethereum/wiki/wiki/White-Paper), and for a full technical spec see the [yellow](http://gavwood.com/Paper.pdf) papers, although those are not prerequisites for this page; that is to say, this page is meant as an alternative introduction to Ethereum specifically targeted toward application developers. - -### Introduction - -Ethereum is a platform that is intended to allow people to easily write decentralized applications (Đapps) using blockchain technology. A decentralized application is an application which serves some specific purpose to its users, but which has the important property that the application itself does not depend on any specific party existing. Rather than serving as a front-end for selling or providing a specific party's services, a Đapp is a tool for people and organizations on different sides of an interaction use to come together without any centralized intermediary. - -Even necessary "intermediary" functions that are typically the domain of centralized providers, such as filtering, identity management, escrow and dispute resolution, are either handled directly by the network or left open for anyone to participate, using tools like internal token systems and reputation systems to ensure that users get access to high-quality services. Early examples of Đapps include BitTorrent for file sharing and Bitcoin for currency. Ethereum takes the primary developments used by BitTorrent and Bitcoin, the peer to peer network and the blockchain, and generalizes them in order to allow developers to use these technologies for any purpose. - -The Ethereum blockchain can be alternately described as a blockchain with a built-in programming language, or as a consensus-based globally executed virtual machine. The part of the protocol that actually handles internal state and computation is referred to as the Ethereum Virtual Machine (EVM). From a practical standpoint, the EVM can be thought of as a large decentralized computer containing millions of objects, called "accounts", which have the ability to maintain an internal database, execute code and talk to each other. - -There are two types of accounts: - -1. **Externally owned account (EOAs)**: an account controlled by a private key, and if you own the private key associated with the EOA you have the ability to send ether and messages from it. -2. **Contract**: an account that has its own code, and is controlled by code. - -By default, the Ethereum execution environment is lifeless; nothing happens and the state of every account remains the same. However, any user can trigger an action by sending a transaction from an externally owned account, setting Ethereum's wheels in motion. If the destination of the transaction is another EOA, then the transaction may transfer some ether but otherwise does nothing. However, if the destination is a contract, then the contract in turn activates, and automatically runs its code. - -The code has the ability to read/write to its own internal storage (a database mapping 32-byte keys to 32-byte values), read the storage of the received message, and send messages to other contracts, triggering their execution in turn. Once execution stops, and all sub-executions triggered by a message sent by a contract stop (this all happens in a deterministic and synchronous order, ie. a sub-call completes fully before the parent call goes any further), the execution environment halts once again, until woken by the next transaction. - -Contracts generally serve four purposes: - -1. Maintain a data store representing something which is useful to either other contracts or to the outside world; one example of this is a contract that simulates a currency, and another is a contract that records membership in a particular organization. - -2. Serve as a sort of externally owned account with a more complicated access policy; this is called a "forwarding contract" and typically involves simply resending incoming messages to some desired destination only if certain conditions are met; for example, one can have a forwarding contract that waits until two out of a given three private keys have confirmed a particular message before resending it (ie. multisig). More complex forwarding contracts have different conditions based on the nature of the message sent; the simplest use case for this functionality is a withdrawal limit that is overrideable via some more complicated access procedure. - -3. Manage an ongoing contract or relationship between multiple users. Examples of this include a financial contract, an escrow with some particular set of mediators, or some kind of insurance. One can also have an open contract that one party leaves open for any other party to engage with at any time; one example of this is a contract that automatically pays a bounty to whoever submits a valid solution to some mathematical problem, or proves that it is providing some computational resource. - -4. Provide functions to other contracts; essentially serving as a software library. - -Contracts interact with each other through an activity that is alternately called either "calling" or "sending messages". A "message" is an object containing some quantity of ether (a special internal currency used in Ethereum with the primary purpose of paying transaction fees), a byte-array of data of any size, the addresses of a sender and a recipient. When a contract receives a message it has the option of returning some data, which the original sender of the message can then immediately use. In this way, sending a message is exactly like calling a function. - -Because contracts can play such different roles, we expect that contracts will be interacting with each other. As an example, consider a situation where Alice and Bob are betting 100 GavCoin that the temperature in San Francisco will not exceed 35ºC at any point in the next year. However, Alice is very security-conscious, and as her primary account uses a forwarding contract which only sends messages with the approval of two out of three private keys. Bob is paranoid about quantum cryptography, so he uses a forwarding contract which passes along only messages that have been signed with [Lamport signatures](https://en.wikipedia.org/wiki/Lamport_signature) alongside traditional ECDSA (but because he's old fashioned, he prefers to use a version of Lamport sigs based on SHA256, which is not supported in Ethereum directly). - -The betting contract itself needs to fetch data about the San Francisco weather from some contract, and it also needs to talk to the GavCoin contract when it wants to actually send the GavCoin to either Alice or Bob (or, more precisely, Alice or Bob's forwarding contract). We can show the relationships between the accounts thus: - -![img](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/contract_relationship.png) - -When Bob wants to finalize the bet, the following steps happen: - -1. A transaction is sent, triggering a message from Bob's EOA to Bob's forwarding contract. -2. Bob's forwarding contract sends the hash of the message and the Lamport signature to a contract which functions as a Lamport signature verification library. -3. The Lamport signature verification library sees that Bob wants a SHA256-based Lamport sig, so it calls the SHA256 library many times as needed to verify the signature. -4. Once the Lamport signature verification library returns 1, signifying that the signature has been verified, it sends a message to the contract representing the bet. -5. The bet contract checks the contract providing the San Francisco temperature to see what the temperature is. -6. The bet contract sees that the response to the messages shows that the temperature is above 35ºC, so it sends a message to the GavCoin contract to move the GavCoin from its account to Bob's forwarding contract. - -Note that the GavCoin is all "stored" as entries in the GavCoin contract's database; the word "account" in the context of step 6 simply means that there is a data entry in the GavCoin contract storage with a key for the bet contract's address and a value for its balance. After receiving this message, the GavCoin contract decreases this value by some amount and increases the value in the entry corresponding to Bob's forwarding contract's address. We can see these steps in the following diagram: - -![img](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/contract_relationship2.png?1) - -### State Machine - -Computation in the EVM is done using a stack-based bytecode language that is like a cross between Bitcoin Script, traditional assembly and Lisp (the Lisp part being due to the recursive message-sending functionality). A program in EVM is a sequence of opcodes, like this: - - PUSH1 0 CALLDATALOAD SLOAD NOT PUSH1 9 JUMPI STOP JUMPDEST PUSH1 32 CALLDATALOAD PUSH1 0 CALLDATALOAD SSTORE - -The purpose of this particular contract is to serve as a name registry; anyone can send a message containing 64 bytes of data, 32 for the key and 32 for the value. The contract checks if the key has already been registered in storage, and if it has not been then the contract registers the value at that key. - -During execution, an infinitely expandable byte-array called "memory", the "program counter" pointing to the current instruction, and a stack of 32-byte values is maintained. At the start of execution, memory and stack are empty and the PC is zero. Now, let us suppose the contract with this code is being accessed for the first time, and a message is sent in with 123 wei (1018 wei = 1 ether) and 64 bytes of data where the first 32 bytes encode the number 54 and the second 32 bytes encode the number 2020202020. - -Thus, the state at the start is: - - PC: 0 STACK: [] MEM: [], STORAGE: {} - -The instruction at position 0 is PUSH1, which pushes a one-byte value onto the stack and jumps two steps in the code. Thus, we have: - - PC: 2 STACK: [0] MEM: [], STORAGE: {} - -The instruction at position 2 is CALLDATALOAD, which pops one value from the stack, loads the 32 bytes of message data starting from that index, and pushes that on to the stack. Recall that the first 32 bytes here encode 54. - - PC: 3 STACK: [54] MEM: [], STORAGE: {} - -SLOAD pops one from the stack, and pushes the value in contract storage at that index. Since the contract is used for the first time, it has nothing there, so zero. - - PC: 4 STACK: [0] MEM: [], STORAGE: {} - -NOT pops one value and pushes 1 if the value is zero, else 0 - - PC: 5 STACK: [1] MEM: [], STORAGE: {} - -Next, we PUSH1 9. - - PC: 7 STACK: [1, 9] MEM: [], STORAGE: {} - -The JUMPI instruction pops 2 values and jumps to the instruction designated by the first only if the second is nonzero. Here, the second is nonzero, so we jump. If the value in storage index 54 had not been zero, then the second value from top on the stack would have been 0 (due to NOT), so we would not have jumped, and we would have advanced to the STOP instruction which would have led to us stopping execution. - - PC: 9 STACK: [] MEM: [], STORAGE: {} - -Here, we PUSH1 32. - - PC: 11 STACK: [32] MEM: [], STORAGE: {} - -Now, we CALLDATALOAD again, popping 32 and pushing the bytes in message data starting from byte 32 until byte 63. - - PC: 13 STACK: [2020202020] MEM: [], STORAGE: {} - -Next, we PUSH1 0. - - PC: 14 STACK: [2020202020, 0] MEM: [], STORAGE: {} - -Now, we load message data bytes 0-31 again (loading message data is just as cheap as loading memory, so we don't bother to save it in memory) - - PC: 16 STACK: [2020202020, 54] MEM: [], STORAGE: {} - -Finally, we SSTORE to save the value 2020202020 in storage at index 54. - - PC: 17 STACK: [] MEM: [], STORAGE: {54: 2020202020} - -At index 17, there is no instruction, so we stop. If there was anything left in the stack or memory, it would be deleted, but the storage will stay and be available next time someone sends a message. Thus, if the sender of this message sends the same message again (or perhaps someone else tries to reregister 54 to 3030303030), the next time the `JUMPI` at position 7 would not process, and execution would STOP early at position 8. - -Fortunately, you do not have to program in low-level assembly; a high-level language exists, especially designed for writing contracts, known as [Solidity](https://github.com/ethereum/wiki/wiki/Solidity) exists to make it much easier for you to write contracts (there are several others, too, including [LLL](https://github.com/ethereum/cpp-ethereum/wiki/LLL-PoC-5), [Serpent](https://github.com/ethereum/wiki/wiki/Serpent) and [Mutan](https://github.com/ethereum/go-ethereum/wiki/Mutan-0.2), which you may find easier to learn or use depending on your experience). Any code you write in these languages gets compiled into EVM, and to create the contracts you send the transaction containing the EVM bytecode. - -There are two types of transactions: a sending transaction and a contract creating transaction. A sending transaction is a standard transaction, containing a receiving address, an ether amount, a data bytearray and some other parameters, and a signature from the private key associated with the sender account. A contract creating transaction looks like a standard transaction, except the receiving address is blank. When a contract creating transaction makes its way into the blockchain, the data bytearray in the transaction is interpreted as EVM code, and the value returned by that EVM execution is taken to be the code of the new contract; hence, you can have a transaction do certain things during initialization. The address of the new contract is deterministically calculated based on the sending address and the number of times that the sending account has made a transaction before (this value, called the account nonce, is also kept for unrelated security reasons). Thus, the full code that you need to put onto the blockchain to produce the above name registry is as follows: - - PUSH1 16 DUP PUSH1 12 PUSH1 0 CODECOPY PUSH1 0 RETURN STOP PUSH1 0 CALLDATALOAD SLOAD NOT PUSH1 9 JUMPI STOP PUSH1 32 CALLDATALOAD PUSH1 0 CALLDATALOAD SSTORE - -The key opcodes are CODECOPY, copying the 16 bytes of code starting from byte 12 into memory starting at index 0, and RETURN, returning memory bytes 0-16, ie. code byes 12-28 (feel free to "run" the execution manually on paper to verify that those parts of the code and memory actually get copied and returned). Code bytes 12-28 are, of course, the actual code as we saw above. - -### Gas - -One important aspect of the way the EVM works is that every single operation that is executed inside the EVM is actually simultaneously executed by every full node. This is a necessary component of the Ethereum 1.0 consensus model, and has the benefit that any contract on the EVM can call any other contract at almost zero cost, but also has the drawback that computational steps on the EVM are very expensive. Roughly, a good heuristic to use is that you will not be able to do anything on the EVM that you cannot do on a smartphone from 1999. Acceptable uses of the EVM include running business logic ("if this then that") and verifying signatures and other cryptographic objects; at the upper limit of this are applications that verify parts of other blockchains (eg. a decentralized ether-to-bitcoin exchange); unacceptable uses include using the EVM as a file storage, email or text messaging system, anything to do with graphical interfaces, and applications best suited for cloud computing like genetic algorithms, graph analysis or machine learning. - -In order to prevent deliberate attacks and abuse, the Ethereum protocol charges a fee per computational step. The fee is market-based, though mandatory in practice; a floating limit on the number of operations that can be contained in a block forces even miners who can afford to include transactions at close to no cost to charge a fee commensurate with the cost of the transaction to the entire network; see [the whitepaper section on fees](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-White-Paper#fees) for more details on the economic underpinnings of our fee and block operation limit system. - -The way the fee works is as follows. Every transaction must contain, alongside its other data, a `GASPRICE` and `STARTGAS` value. `STARTGAS` is the amount of "gas" that the transaction assigns itself, and `GASPRICE` is the fee that the transaction pays per unit of gas; thus, when a transaction is sent, the first thing that is done during evaluation is subtracting `STARTGAS * GASPRICE` wei plus the transaction's value from the sending account balance. `GASPRICE` is set by the transaction sender, but miners will likely refuse to process transactions whose `GASPRICE` is too low. - -Gas can be roughly thought of as a counter of computational steps, and is something that exists during transaction execution but not outside of it. When transaction execution starts, the gas remaining is set to `STARTGAS - 21000 - 68 * TXDATALEN` where `TXDATALEN` is the number of bytes in transaction data (note: zero bytes are charged only 4 gas due to the greater compressibility of long strings of zero bytes). Every computational step, a certain amount (usually 1, sometimes more depending on the operation) of gas is subtracted from the total. If gas goes down to zero, then all execution reverts, but the transaction is still valid and the sender still has to pay for gas. If transaction execution finishes with `N >= 0` gas remaining, then the sending account is refunded with `N * GASPRICE` wei. - -During contract execution, when a contract sends a message, that message call itself comes with a gas limit, and the sub-execution works the same way (namely, it can either run out of gas and revert or execute successfully and return a value). If sub-execution runs out of gas, the parent execution continues; thus, it is perfectly "safe" for a contract to call another contract if you set a gas limit on the sub-execution. If sub-execution has some gas remaining, then that gas is returned to the parent execution to continue using. - -### Virtual machine opcodes - -A complete listing of the opcodes in the EVM can be found in the [yellow paper](http://gavwood.com/Paper.pdf). Note that high-level languages will often have their own wrappers for these opcodes, sometimes with very different interfaces. - -### Basics of the Ethereum Blockchain - -The Ethereum blockchain (or "ledger") is the decentralized, massively replicated database in which the current state of all accounts is stored. The blockchain uses a database called a [Patricia tree](https://github.com/ethereum/wiki/wiki/Patricia-Tree) (or "trie") to store all accounts; this is essentially a specialized kind of Merkle tree that acts as a generic key/value store. Like a standard Merkle tree, a Patricia tree has a "root hash" that can be used to refer to the entire tree, and the contents of the tree cannot be modified without changing the root hash. For each account, the tree stores a 4-tuple containing `[account_nonce, ether_balance, code_hash, storage_root]`, where `account_nonce` is the number of transactions sent from the account (kept to prevent replay attacks), `ether_balance` is the balance of the account, `code_hash` the hash of the code if the account is a contract and "" otherwise, and `storage_root` is the root of yet another Patricia tree which stores the storage data. - -![we](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/chaindiag.png) - -Every minute, a miner produces a new block (the concept of mining in Ethereum is exactly the same as in Bitcoin; see any Bitcoin tutorial for more info on this), and that block contains a list of transactions that happened since the last block and the root hash of the Patricia tree representing the new state ("state tree") after applying those transactions and giving the miner an ether reward for creating the block. - -Because of the way the Patricia tree works, if few changes are made then most parts of the tree will be exactly the same as in the last block; hence, there is no need to store data twice as nodes in the new tree will simply be able to point back to the same memory address that stores the nodes of the old tree in places where the new tree and the old tree are exactly the same. If a thousand pieces of data are changed between block `N` and block `N + 1`, even if the total size of the tree is many gigabytes, the amount of new data that needs to be stored for block `N + 1` is at most a few hundred kilobytes and often substantially less (especially if multiple changes happen inside the same contract). Every block contains the hash of the previous block (this is what makes the block set a "chain") as well as ancillary data like the block number, timestamp, address of the miner and gas limit. - -### Graphical Interfaces - -A contract by itself is a powerful thing, but it is not a complete Đapp. A Đapp, rather, is defined as a combination of a contract and a graphical interface for using that contract (note: this is only true for now; future versions of Ethereum will include whisper, a protocol for allowing nodes in a Đapp to send direct peer-to-peer messages to each other without the blockchain). Right now, the interface is implemented as an HTML/CSS/JS webpage, with a special Javascript API in the form of the `eth` object for working with the Ethereum blockchain. The key parts of the Javascript API are as follows: - -* `eth.transact(from, ethervalue, to, data, gaslimit, gasprice)` - sends a transaction to the desired address from the desired address (note: `from` must be a private key and `to` must be an address in hex form) with the desired parameters -* `(string).pad(n)` - converts a number, encoded as a string, to binary form `n` bytes long -* `eth.gasPrice` - returns the current gas price -* `eth.secretToAddress(key)` - converts a private key into an address -* `eth.storageAt(acct, index)` - returns the desired account's storage entry at the desired index -* `eth.key` - the user's private key -* `eth.watch(acct, index, f)` - calls `f` when the given storage entry of the given account changes - -You do not need any special source file or library to use the `eth` object; however, your Đapp will only work when opened in an Ethereum client, not a regular web browser. For an example of the Javascript API being used in practice, see [the source code of this webpage](http://gavwood.com/gavcoin.html). - -### Fine Points To Keep Track Of - -See [https://github.com/ethereum/wiki/wiki/Subtleties](https://github.com/ethereum/wiki/wiki/Subtleties) \ No newline at end of file diff --git a/pages/dapp-development/First-steps-with-ethereum-JSON-RPC.md b/pages/dapp-development/First-steps-with-ethereum-JSON-RPC.md deleted file mode 100644 index dc9aa988a..000000000 --- a/pages/dapp-development/First-steps-with-ethereum-JSON-RPC.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -name: First Steps wih Ethereum JSON RPC -category: ---- - -# First steps with ethereum JSON-RPC - - -#### 1. clone cpp-ethereum or install it - -##### manual installation - -```bash -git clone https://github.com/ethereum/cpp-ethereum -cd cpp-ethereum -mkdir build -cd build -cmake .. -make -j 4 -``` - -##### automatic installation - -build instructions are [here](https://github.com/ethereum/cpp-ethereum/wiki/Installing-clients) - - -#### 2. run eth (headless client) - -```bash -eth -j -``` - -`-j` option will start ethereum node with jsonrpc http server at port 8080 - -etheruem should be ready to use now - -type in console to check if everything is working fine - -``` -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":83}' http://localhost:8080 -``` - -#### 3. mine and connect to the network - -try running - -```bash -eth -j -m true -f -b -``` - -where: -- `-m true` - to do anything in ethereum, you need some ethere, let's mine -- `-f` - mine with force, even if there are no transactions to mine -- `-b` - connect to ethereum network - -*with latest version of cpp-ethereum it may take some time to connect to network. If you see any delays with jsonrpc responses, or crashes contant us. We are probably aware of them, but it's good to know about any possible vulnerability* - -#### 4. json-rpc methods, that you might be intrested in: - -- [eth_sendTransaction](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sendtransaction) - used to send transaction / create contract -- [eth_newBlockFilter](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_newblockfilter) - be notified any time there is new block on the chain -- [eth_newFilter](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_newfilter) - create new custom filter and listen to blockchain events matching this filter -- [eth_compileSolidity](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_compilesolidity) - used to compile solidity code - - - - - - - - - - - - - - - - - - - diff --git a/pages/dapp-development/JSON-RPC.md b/pages/dapp-development/JSON-RPC.md deleted file mode 100644 index 33f9d64d1..000000000 --- a/pages/dapp-development/JSON-RPC.md +++ /dev/null @@ -1,2381 +0,0 @@ ---- -name: JSON RPC -category: ---- - -# JSON RPC API - -[JSON](http://json.org/) is a lightweight data-interchange format. It can represent numbers, strings, ordered sequences of values, and collections of name/value pairs. - -[JSON-RPC](http://www.jsonrpc.org/specification) is a stateless, light-weight remote procedure call (RPC) protocol. Primarily this specification defines several data structures and the rules around their processing. It is transport agnostic in that the concepts can be used within the same process, over sockets, over HTTP, or in many various message passing environments. It uses JSON ([RFC 4627](http://www.ietf.org/rfc/rfc4627.txt)) as data format. - -## JavaScript API - -To talk to an ethereum node from inside a JavaScript application use the [web3.js](https://github.com/ethereum/web3.js) library, which gives an convenient interface for the RPC methods. -See the [JavaScript API](https://github.com/ethereum/wiki/wiki/JavaScript-API) for more. - -## JSON-RPC Endpoint - -Default JSON-RPC endpoints: -``` -C++: http://localhost:8545 -Go: http://localhost:8545 -Py: http://localhost:4000 -``` - -### Go - -You can start the HTTP JSON-RPC with the `--rpc` flag -```bash -geth --rpc -``` - -change the default port (8545) and listing address (localhost) with: - -```bash -geth --rpc --rpcaddr --rpcport -``` - -If accessing the RPC from a browser, CORS will need to be enabled with the appropriate domain set. Otherwise, JavaScript calls are limit by the same-origin policy and requests will fail: - -```bash -geth --rpc --rpccorsdomain "http://localhost:3000" -``` - -The JSON RPC can also be started from the [geth console](https://github.com/ethereum/go-ethereum/wiki/JavaScript-Console) using the `admin.startRPC(addr, port)` command. - - -### C++ - -You can start it by running `eth` application with `-j` option: -```bash -./eth -j -``` - -You can also specify JSON-RPC port (default is 8545): -```bash -./eth -j --json-rpc-port 8079 -``` - -### Python -In python the JSONRPC server is currently started by default and listens on `127.0.0.1:4000` - -You can change the port and listen address by giving a config option. - -`pyethapp -c jsonrpc.listen_port=4002 -c jsonrpc.listen_host=127.0.0.2 run` - -## JSON-RPC support - -| | cpp-ethereum | go-ethereum | py-ethereum| -|-------|:------------:|:-----------:|:-----------:| -| JSON-RPC 1.0 | ✓ | | | -| JSON-RPC 2.0 | ✓ | ✓ | ✓ | -| Batch requests | ✓ | ✓ | ✓ | -| HTTP | ✓ | ✓ | ✓ | - -## Output HEX values - -At present there are two key datatypes that are passed over JSON: unformatted byte arrays and quantities. Both are passed with a hex encoding, however with different requirements to formatting: - -When encoding **QUANTITIES** (integers, numbers): encode as hex, prefix with "0x", the most compact representation (slight exception: zero should be represented as "0x0"). Examples: -- 0x41 (65 in decimal) -- 0x400 (1024 in decimal) -- WRONG: 0x (should always have at least one digit - zero is "0x0") -- WRONG: 0x0400 (no leading zeroes allowed) -- WRONG: ff (must be prefixed 0x) - -When encoding **UNFORMATTED DATA** (byte arrays, account addresses, hashes, bytecode arrays): encode as hex, prefix with "0x", two hex digits per byte. Examples: -- 0x41 (size 1, "A") -- 0x004200 (size 3, "\0B\0") -- 0x (size 0, "") -- WRONG: 0xf0f0f (must be even number of digits) -- WRONG: 004200 (must be prefixed 0x) - -Currently [cpp-ethereum](https://github.com/ethereum/cpp-ethereum) and [go-ethereum](https://github.com/ethereum/go-ethereum) provides JSON-RPC communication only over http. - -## The default block parameter - -The following methods have a extra default block parameter: - -- [eth_getBalance](#eth_getbalance) -- [eth_getCode](#eth_getcode) -- [eth_getTransactionCount](#eth_gettransactioncount) -- [eth_getStorageAt](#eth_getstorageat) -- [eth_call](#eth_call) - -When requests are made that act on the state of ethereum, the last default block parameter determines the height of the block. - -The following options are possible for the defaultBlock parameter: - -- `HEX String` - an integer block number -- `String "earliest"` for the earliest/genesis block -- `String "latest"` - for the latest mined block -- `String "pending"` - for the pending state/transactions - -## JSON-RPC methods - -* [web3_clientVersion](#web3_clientversion) -* [web3_sha3](#web3_sha3) -* [net_version](#net_version) -* [net_peerCount](#net_peercount) -* [net_listening](#net_listening) -* [eth_protocolVersion](#eth_protocolversion) -* [eth_syncing](#eth_syncing) -* [eth_coinbase](#eth_coinbase) -* [eth_mining](#eth_mining) -* [eth_hashrate](#eth_hashrate) -* [eth_gasPrice](#eth_gasprice) -* [eth_accounts](#eth_accounts) -* [eth_blockNumber](#eth_blocknumber) -* [eth_getBalance](#eth_getbalance) -* [eth_getStorageAt](#eth_getstorageat) -* [eth_getTransactionCount](#eth_gettransactioncount) -* [eth_getBlockTransactionCountByHash](#eth_getblocktransactioncountbyhash) -* [eth_getBlockTransactionCountByNumber](#eth_getblocktransactioncountbynumber) -* [eth_getUncleCountByBlockHash](#eth_getunclecountbyblockhash) -* [eth_getUncleCountByBlockNumber](#eth_getunclecountbyblocknumber) -* [eth_getCode](#eth_getcode) -* [eth_sign](#eth_sign) -* [eth_sendTransaction](#eth_sendtransaction) -* [eth_sendRawTransaction](#eth_sendrawtransaction) -* [eth_call](#eth_call) -* [eth_estimateGas](#eth_estimategas) -* [eth_getBlockByHash](#eth_getblockbyhash) -* [eth_getBlockByNumber](#eth_getblockbynumber) -* [eth_getTransactionByHash](#eth_gettransactionbyhash) -* [eth_getTransactionByBlockHashAndIndex](#eth_gettransactionbyblockhashandindex) -* [eth_getTransactionByBlockNumberAndIndex](#eth_gettransactionbyblocknumberandindex) -* [eth_getTransactionReceipt](#eth_gettransactionreceipt) -* [eth_getUncleByBlockHashAndIndex](#eth_getunclebyblockhashandindex) -* [eth_getUncleByBlockNumberAndIndex](#eth_getunclebyblocknumberandindex) -* [eth_getCompilers](#eth_getcompilers) -* [eth_compileLLL](#eth_compilelll) -* [eth_compileSolidity](#eth_compilesolidity) -* [eth_compileSerpent](#eth_compileserpent) -* [eth_newFilter](#eth_newfilter) -* [eth_newBlockFilter](#eth_newblockfilter) -* [eth_newPendingTransactionFilter](#eth_newpendingtransactionfilter) -* [eth_uninstallFilter](#eth_uninstallfilter) -* [eth_getFilterChanges](#eth_getfilterchanges) -* [eth_getFilterLogs](#eth_getfilterlogs) -* [eth_getLogs](#eth_getlogs) -* [eth_getWork](#eth_getwork) -* [eth_submitWork](#eth_submitwork) -* [eth_submitHashrate](#eth_submithashrate) -* [db_putString](#db_putstring) -* [db_getString](#db_getstring) -* [db_putHex](#db_puthex) -* [db_getHex](#db_gethex) -* [shh_post](#shh_post) -* [shh_version](#shh_version) -* [shh_newIdentity](#shh_newidentity) -* [shh_hasIdentity](#shh_hasidentity) -* [shh_newGroup](#shh_newgroup) -* [shh_addToGroup](#shh_addtogroup) -* [shh_newFilter](#shh_newfilter) -* [shh_uninstallFilter](#shh_uninstallfilter) -* [shh_getFilterChanges](#shh_getfilterchanges) -* [shh_getMessages](#shh_getmessages) - -## JSON RPC API Reference - -*** - -#### web3_clientVersion - -Returns the current client version. - -##### Parameters -none - -##### Returns - -`String` - The current client version - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":67}' - -// Result -{ - "id":67, - "jsonrpc":"2.0", - "result": "Mist/v0.9.3/darwin/go1.4.1" -} -``` - -*** - -#### web3_sha3 - -Returns Keccak-256 (*not* the standardized SHA3-256) of the given data. - -##### Parameters - -1. `String` - the data to convert into a SHA3 hash - -```js -params: [ - '0x68656c6c6f20776f726c64' -] -``` - -##### Returns - -`DATA` - The SHA3 result of the given string. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"web3_sha3","params":["0x68656c6c6f20776f726c64"],"id":64}' - -// Result -{ - "id":64, - "jsonrpc": "2.0", - "result": "0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad" -} -``` - -*** - -#### net_version - -Returns the current network protocol version. - -##### Parameters -none - -##### Returns - -`String` - The current network protocol version - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"net_version","params":[],"id":67}' - -// Result -{ - "id":67, - "jsonrpc": "2.0", - "result": "59" -} -``` - -*** - -#### net_listening - -Returns `true` if client is actively listening for network connections. - -##### Parameters -none - -##### Returns - -`Boolean` - `true` when listening, otherwise `false`. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"net_listening","params":[],"id":67}' - -// Result -{ - "id":67, - "jsonrpc":"2.0", - "result":true -} -``` - -*** - -#### net_peerCount - -Returns number of peers currenly connected to the client. - -##### Parameters -none - -##### Returns - -`QUANTITY` - integer of the number of connected peers. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"net_peerCount","params":[],"id":74}' - -// Result -{ - "id":74, - "jsonrpc": "2.0", - "result": "0x2" // 2 -} -``` - -*** - -#### eth_protocolVersion - -Returns the current ethereum protocol version. - -##### Parameters -none - -##### Returns - -`String` - The current ethereum protocol version - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_protocolVersion","params":[],"id":67}' - -// Result -{ - "id":67, - "jsonrpc": "2.0", - "result": "54" -} -``` - -*** - -#### eth_syncing - -Returns an object object with data about the sync status or FALSE. - - -##### Parameters -none - -##### Returns - -`Object|Boolean`, An object with sync status data or `FALSE`, when not syncing: - - `startingBlock`: `QUANTITY` - The block at which the import started (will only be reset, after the sync reached his head) - - `currentBlock`: `QUANTITY` - The current block, same as eth_blockNumber - - `highestBlock`: `QUANTITY` - The estimated highest block - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_isSyncing","params":[],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": { - startingBlock: '0x384', - currentBlock: '0x386', - highestBlock: '0x454' - } -} -// Or when not syncing -{ - "id":1, - "jsonrpc": "2.0", - "result": false -} -``` - -*** - -#### eth_coinbase - -Returns the client coinbase address. - - -##### Parameters -none - -##### Returns - -`DATA`, 20 bytes - the current coinbase address. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_coinbase","params":[],"id":64}' - -// Result -{ - "id":64, - "jsonrpc": "2.0", - "result": "0x407d73d8a49eeb85d32cf465507dd71d507100c1" -} -``` - -*** - -#### eth_mining - -Returns `true` if client is actively mining new blocks. - -##### Parameters -none - -##### Returns - -`Boolean` - returns `true` of the client is mining, otherwise `false`. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_mining","params":[],"id":71}' - -// Result -{ - "id":71, - "jsonrpc": "2.0", - "result": true -} - -``` - -*** - -#### eth_hashrate - -Returns the number of hashes per second that the node is mining with. - -##### Parameters -none - -##### Returns - -`QUANTITY` - number of hashes per second. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_hashrate","params":[],"id":71}' - -// Result -{ - "id":71, - "jsonrpc": "2.0", - "result": "0x38a" -} - -``` - -*** - -#### eth_gasPrice - -Returns the current price per gas in wei. - -##### Parameters -none - -##### Returns - -`QUANTITY` - integer of the current gas price in wei. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_gasPrice","params":[],"id":73}' - -// Result -{ - "id":73, - "jsonrpc": "2.0", - "result": "0x09184e72a000" // 10000000000000 -} -``` - -*** - -#### eth_accounts - -Returns a list of addresses owned by client. - - -##### Parameters -none - -##### Returns - -`Array of DATA`, 20 Bytes - addresses owned by the client. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_accounts","params":[],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": ["0x407d73d8a49eeb85d32cf465507dd71d507100c1"] -} -``` - -*** - -#### eth_blockNumber - -Returns the number of most recent block. - -##### Parameters -none - -##### Returns - -`QUANTITY` - integer of the current block number the client is on. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":83}' - -// Result -{ - "id":83, - "jsonrpc": "2.0", - "result": "0x4b7" // 1207 -} -``` - -*** - -#### eth_getBalance - -Returns the balance of the account of given address. - -##### Parameters - -1. `DATA`, 20 Bytes - address to check for balance. -2. `QUANTITY|TAG` - integer block number, or the string `"latest"`, `"earliest"` or `"pending"`, see the [default block parameter](#the-default-block-parameter) - -```js -params: [ - '0x407d73d8a49eeb85d32cf465507dd71d507100c1', - 'latest' -] -``` - -##### Returns - -`QUANTITY` - integer of the current balance in wei. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBalance","params":["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "latest"],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x0234c8a3397aab58" // 158972490234375000 -} -``` - -*** - -#### eth_getStorageAt - -Returns the value from a storage position at a given address. - - -##### Parameters - -1. `DATA`, 20 Bytes - address of the storage. -2. `QUANTITY` - integer of the position in the storage. -3. `QUANTITY|TAG` - integer block number, or the string `"latest"`, `"earliest"` or `"pending"`, see the [default block parameter](#the-default-block-parameter) - - -```js -params: [ - '0x407d73d8a49eeb85d32cf465507dd71d507100c1', - '0x0', // storage position at 0 - '0x2' // state at block number 2 -] -``` - -##### Returns - -`DATA` - the value at this storage position. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getStorageAt","params":["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "0x0", "0x2"],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x03" -} -``` - -*** - -#### eth_getTransactionCount - -Returns the number of transactions *sent* from an address. - - -##### Parameters - -1. `DATA`, 20 Bytes - address. -2. `QUANTITY|TAG` - integer block number, or the string `"latest"`, `"earliest"` or `"pending"`, see the [default block parameter](#the-default-block-parameter) - -```js -params: [ - '0x407d73d8a49eeb85d32cf465507dd71d507100c1', - 'latest' // state at the latest block -] -``` - -##### Returns - -`QUANTITY` - integer of the number of transactions send from this address. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionCount","params":["0x407d73d8a49eeb85d32cf465507dd71d507100c1","latest"],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x1" // 1 -} -``` - -*** - -#### eth_getBlockTransactionCountByHash - -Returns the number of transactions in a block from a block matching the given block hash. - - -##### Parameters - -1. `DATA`, 32 Bytes - hash of a block - -```js -params: [ - '0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238' -] -``` - -##### Returns - -`QUANTITY` - integer of the number of transactions in this block. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockTransactionCountByHash","params":["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0xb" // 11 -} -``` - -*** - -#### eth_getBlockTransactionCountByNumber - -Returns the number of transactions in a block from a block matching the given block number. - - -##### Parameters - -1. `QUANTITY|TAG` - integer of a block number, or the string `"earliest"`, `"latest"` or `"pending"`, as in the [default block parameter](#the-default-block-parameter). - -```js -params: [ - '0xe8', // 232 -] -``` - -##### Returns - -`QUANTITY` - integer of the number of transactions in this block. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockTransactionCountByNumber","params":["0xe8"],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0xa" // 10 -} -``` - -*** - -#### eth_getUncleCountByBlockHash - -Returns the number of uncles in a block from a block matching the given block hash. - - -##### Parameters - -1. `DATA`, 32 Bytes - hash of a block - -```js -params: [ - '0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238' -] -``` - -##### Returns - -`QUANTITY` - integer of the number of uncles in this block. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getUncleCountByBlockHash","params":["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"],"id"Block:1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x1" // 1 -} -``` - -*** - -#### eth_getUncleCountByBlockNumber - -Returns the number of uncles in a block from a block matching the given block number. - - -##### Parameters - -1. `QUANTITY` - integer of a block number, or the string "latest", "earliest" or "pending", see the [default block parameter](#the-default-block-parameter) - -```js -params: [ - '0xe8', // 232 -] -``` - -##### Returns - -`QUANTITY` - integer of the number of uncles in this block. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getUncleCountByBlockNumber","params":["0xe8"],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x1" // 1 -} -``` - -*** - -#### eth_getCode - -Returns code at a given address. - - -##### Parameters - -1. `DATA`, 20 Bytes - address -2. `QUANTITY|TAG` - integer block number, or the string `"latest"`, `"earliest"` or `"pending"`, see the [default block parameter](#the-default-block-parameter) - -```js -params: [ - '0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b', - '0x2' // 2 -] -``` - -##### Returns - -`DATA` - the code from the given address. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getCode","params":["0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0x2"],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x600160008035811a818181146012578301005b601b6001356025565b8060005260206000f25b600060078202905091905056" -} -``` - -*** - -#### eth_sign - -Signs data with a given address. - -**Note** the address to sign must be unlocked. - -##### Parameters - -1. `DATA`, 20 Bytes - address -2. `DATA`, Data to sign - -##### Returns - -`DATA`: Signed data - -##### Example - -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_sign","params":["0xd1ade25ccd3d550a7eb532ac759cac7be09c2719", "Schoolbus"],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x2ac19db245478a06032e69cdbd2b54e648b78431d0a47bd1fbab18f79f820ba407466e37adbe9e84541cab97ab7d290f4a64a5825c876d22109f3bf813254e8601" -} -``` - - - -*** - -#### eth_sendTransaction - -Creates new message call transaction or a contract creation, if the data field contains code. - -##### Parameters - -1. `Object` - The transaction object - - `from`: `DATA`, 20 Bytes - The address the transaction is send from. - - `to`: `DATA`, 20 Bytes - (optional when creating new contract) The address the transaction is directed to. - - `gas`: `QUANTITY` - (optional, default: 90000) Integer of the gas provided for the transaction execution. It will return unused gas. - - `gasPrice`: `QUANTITY` - (optional, default: To-Be-Determined) Integer of the gasPrice used for each paid gas - - `value`: `QUANTITY` - (optional) Integer of the value send with this transaction - - `data`: `DATA` - (optional) The compiled code of a contract - - `nonce`: `QUANTITY` - (optional) Integer of a nonce. This allows to overwrite your own pending transactions that use the same nonce. - -```js -params: [{ - "from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", - "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", - "gas": "0x76c0", // 30400, - "gasPrice": "0x9184e72a000", // 10000000000000 - "value": "0x9184e72a", // 2441406250 - "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" -}] -``` - -##### Returns - -`DATA`, 32 Bytes - the transaction hash, or the zero hash if the transaction is not yet available. - -Use [eth_getTransactionReceipt](#eth_gettransactionreceipt) to get the contract address, after the transaction was mined, when you created a contract. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_sendTransaction","params":[{see above}],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331" -} -``` - -*** - -#### eth_sendRawTransaction - -Creates new message call transaction or a contract creation for signed transactions. - -##### Parameters - -1. `Object` - The transaction object - - `data`: `DATA`, The signed transaction data. - -```js -params: [{ - "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" -}] -``` - -##### Returns - -`DATA`, 32 Bytes - the transaction hash, or the zero hash if the transaction is not yet available. - -Use [eth_getTransactionReceipt](#eth_gettransactionreceipt) to get the contract address, after the transaction was mined, when you created a contract. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_sendRawTransaction","params":[{see above}],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331" -} -``` - -*** - -#### eth_call - -Executes a new message call immediately without creating a transaction on the block chain. - - -##### Parameters - -1. `Object` - The transaction call object - - `from`: `DATA`, 20 Bytes - (optional) The address the transaction is send from. - - `to`: `DATA`, 20 Bytes - The address the transaction is directed to. - - `gas`: `QUANTITY` - (optional) Integer of the gas provided for the transaction execution. eth_call consumes zero gas, but this parameter may be needed by some executions. - - `gasPrice`: `QUANTITY` - (optional) Integer of the gasPrice used for each paid gas - - `value`: `QUANTITY` - (optional) Integer of the value send with this transaction - - `data`: `DATA` - (optional) The compiled code of a contract -2. `QUANTITY|TAG` - integer block number, or the string `"latest"`, `"earliest"` or `"pending"`, see the [default block parameter](#the-default-block-parameter) - -##### Returns - -`DATA` - the return value of executed contract. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_call","params":[{see above}],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x0" -} -``` - -*** - -#### eth_estimateGas - -Makes a call or transaction, which won't be added to the blockchain and returns the used gas, which can be used for estimating the used gas. - -##### Parameters - -See [eth_call](#eth_call) parameters, expect that all properties are optional. - -##### Returns - -`QUANTITY` - the amount of gas used. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_estimateGas","params":[{see above}],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x5208" // 21000 -} -``` - -*** - -#### eth_getBlockByHash - -Returns information about a block by hash. - - -##### Parameters - -1. `DATA`, 32 Bytes - Hash of a block. -2. `Boolean` - If `true` it returns the full transaction objects, if `false` only the hashes of the transactions. - -```js -params: [ - '0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331', - true -] -``` - -##### Returns - -`Object` - A block object, or `null` when no block was found: - - - `number`: `QUANTITY` - the block number. `null` when its pending block. - - `hash`: `DATA`, 32 Bytes - hash of the block. `null` when its pending block. - - `parentHash`: `DATA`, 32 Bytes - hash of the parent block. - - `nonce`: `DATA`, 8 Bytes - hash of the generated proof-of-work. `null` when its pending block. - - `sha3Uncles`: `DATA`, 32 Bytes - SHA3 of the uncles data in the block. - - `logsBloom`: `DATA`, 256 Bytes - the bloom filter for the logs of the block. `null` when its pending block. - - `transactionsRoot`: `DATA`, 32 Bytes - the root of the transaction trie of the block. - - `stateRoot`: `DATA`, 32 Bytes - the root of the final state trie of the block. - - `receiptsRoot`: `DATA`, 32 Bytes - the root of the receipts trie of the block. - - `miner`: `DATA`, 20 Bytes - the address of the beneficiary to whom the mining rewards were given. - - `difficulty`: `QUANTITY` - integer of the difficulty for this block. - - `totalDifficulty`: `QUANTITY` - integer of the total difficulty of the chain until this block. - - `extraData`: `DATA` - the "extra data" field of this block. - - `size`: `QUANTITY` - integer the size of this block in bytes. - - `gasLimit`: `QUANTITY` - the maximum gas allowed in this block. - - `gasUsed`: `QUANTITY` - the total used gas by all transactions in this block. - - `timestamp`: `QUANTITY` - the unix timestamp for when the block was collated. - - `transactions`: `Array` - Array of transaction objects, or 32 Bytes transaction hashes depending on the last given parameter. - - `uncles`: `Array` - Array of uncle hashes. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockByHash","params":["0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", true],"id":1}' - -// Result -{ -"id":1, -"jsonrpc":"2.0", -"result": { - "number": "0x1b4", // 436 - "hash": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", - "parentHash": "0x9646252be9520f6e71339a8df9c55e4d7619deeb018d2a3f2d21fc165dde5eb5", - "nonce": "0xe04d296d2460cfb8472af2c5fd05b5a214109c25688d3704aed5484f9a7792f2", - "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "logsBloom": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", - "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot": "0xd5855eb08b3387c0af375e9cdb6acfc05eb8f519e419b874b6ff2ffda7ed1dff", - "miner": "0x4e65fda2159562a496f9f3522f89122a3088497a", - "difficulty": "0x027f07", // 163591 - "totalDifficulty": "0x027f07", // 163591 - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000", - "size": "0x027f07", // 163591 - "gasLimit": "0x9f759", // 653145 - "minGasPrice": "0x9f759", // 653145 - "gasUsed": "0x9f759", // 653145 - "timestamp": "0x54e34e8e" // 1424182926 - "transactions": [{...},{ ... }] - "uncles": ["0x1606e5...", "0xd5145a9..."] - } -} -``` - -*** - -#### eth_getBlockByNumber - -Returns information about a block by block number. - -##### Parameters - -1. `QUANTITY|TAG` - integer of a block number, or the string `"earliest"`, `"latest"` or `"pending"`, as in the [default block parameter](#the-default-block-parameter). -2. `Boolean` - If `true` it returns the full transaction objects, if `false` only the hashes of the transactions. - -```js -params: [ - '0x1b4', // 436 - true -] -``` - -##### Returns - -See [eth_getBlockByHash](#eth_getblockbyhash) - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0x1b4", true],"id":1}' -``` - -Result see [eth_getBlockByHash](#eth_getblockbyhash) - -*** - -#### eth_getTransactionByHash - -Returns the information about a transaction requested by transaction hash. - - -##### Parameters - -1. `DATA`, 32 Bytes - hash of a transaction - -```js -params: [ - "0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238" -] -``` - -##### Returns - -`Object` - A transaction object, or `null` when no transaction was found: - - - `hash`: `DATA`, 32 Bytes - hash of the transaction. - - `nonce`: `QUANTITY` - the number of transactions made by the sender prior to this one. - - `blockHash`: `DATA`, 32 Bytes - hash of the block where this transaction was in. `null` when its pending. - - `blockNumber`: `QUANTITY` - block number where this transaction was in. `null` when its pending. - - `transactionIndex`: `QUANTITY` - integer of the transactions index position in the block. `null` when its pending. - - `from`: `DATA`, 20 Bytes - address of the sender. - - `to`: `DATA`, 20 Bytes - address of the receiver. `null` when its a contract creation transaction. - - `value`: `QUANTITY` - value transferred in Wei. - - `gasPrice`: `QUANTITY` - gas price provided by the sender in Wei. - - `gas`: `QUANTITY` - gas provided by the sender. - - `input`: `DATA` - the data send along with the transaction. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionByHash","params":["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"],"id":1}' - -// Result -{ -"id":1, -"jsonrpc":"2.0", -"result": { - "hash":"0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b", - "nonce":"0x", - "blockHash": "0xbeab0aa2411b7ab17f30a99d3cb9c6ef2fc5426d6ad6fd9e2a26a6aed1d1055b", - "blockNumber": "0x15df", // 5599 - "transactionIndex": "0x1", // 1 - "from":"0x407d73d8a49eeb85d32cf465507dd71d507100c1", - "to":"0x85h43d8a49eeb85d32cf465507dd71d507100c1", - "value":"0x7f110" // 520464 - "gas": "0x7f110" // 520464 - "gasPrice":"0x09184e72a000", - "input":"0x603880600c6000396000f300603880600c6000396000f3603880600c6000396000f360", - } -} -``` - -*** - -#### eth_getTransactionByBlockHashAndIndex - -Returns information about a transaction by block hash and transaction index position. - - -##### Parameters - -1. `DATA`, 32 Bytes - hash of a block. -2. `QUANTITY` - integer of the transaction index position. - -```js -params: [ - '0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331', - '0x0' // 0 -] -``` - -##### Returns - -See [eth_getBlockByHash](#eth_gettransactionbyhash) - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionByBlockHashAndIndex","params":[0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b, "0x0"],"id":1}' -``` - -Result see [eth_getTransactionByHash](#eth_gettransactionbyhash) - -*** - -#### eth_getTransactionByBlockNumberAndIndex - -Returns information about a transaction by block number and transaction index position. - - -##### Parameters - -1. `QUANTITY|TAG` - a block number, or the string `"earliest"`, `"latest"` or `"pending"`, as in the [default block parameter](#the-default-block-parameter). -2. `QUANTITY` - the transaction index position. - -```js -params: [ - '0x29c', // 668 - '0x0' // 0 -] -``` - -##### Returns - -See [eth_getBlockByHash](#eth_gettransactionbyhash) - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionByBlockNumberAndIndex","params":["0x29c", "0x0"],"id":1}' -``` - -Result see [eth_getTransactionByHash](#eth_gettransactionbyhash) - -*** - -#### eth_getTransactionReceipt - -Returns the receipt of a transaction by transaction hash. - -**Note** That the receipt is not available for pending transactions. - - -##### Parameters - -1. `DATA`, 32 Bytes - hash of a transaction - -```js -params: [ - '0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238' -] -``` - -##### Returns - -`Object` - A transaction receipt object, or `null` when no receipt was found: - - - `transactionHash `: `DATA`, 32 Bytes - hash of the transaction. - - `transactionIndex`: `QUANTITY` - integer of the transactions index position in the block. - - `blockHash`: `DATA`, 32 Bytes - hash of the block where this transaction was in. - - `blockNumber`: `QUANTITY` - block number where this transaction was in. - - `cumulativeGasUsed `: `QUANTITY ` - The total amount of gas used when this transaction was executed in the block. - - `gasUsed `: `QUANTITY ` - The amount of gas used by this specific transaction alone. - - `contractAddress `: `DATA`, 20 Bytes - The contract address created, if the transaction was a contract creation, otherwise `null`. - - `logs`: `Array` - Array of log objects, which this transaction generated. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionReceipt","params":["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"],"id":1}' - -// Result -{ -"id":1, -"jsonrpc":"2.0", -"result": { - transactionHash: '0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238', - transactionIndex: '0x1', // 1 - blockNumber: '0xb', // 11 - blockHash: '0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b', - cumulativeGasUsed: '0x33bc', // 13244 - gasUsed: '0x4dc', // 1244 - contractAddress: '0xb60e8dd61c5d32be8058bb8eb970870f07233155' // or null, if none was created - logs: [{ - // logs as returned by getFilterLogs, etc. - }, ...] - } -} -``` - -*** - -#### eth_getUncleByBlockHashAndIndex - -Returns information about a uncle of a block by hash and uncle index position. - - -##### Parameters - - -1. `DATA`, 32 Bytes - hash a block. -2. `QUANTITY` - the uncle's index position. - -```js -params: [ - '0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b', - '0x0' // 0 -] -``` - -##### Returns - -See [eth_getBlockByHash](#eth_getblockbyhash) - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getUncleByBlockHashAndIndex","params":["0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b", "0x0"],"id":1}' -``` - -Result see [eth_getBlockByHash](#eth_getblockbyhash) - -**Note**: An uncle doesn't contain individual transactions. - -*** - -#### eth_getUncleByBlockNumberAndIndex - -Returns information about a uncle of a block by number and uncle index position. - - -##### Parameters - -1. `QUANTITY|TAG` - a block number, or the string `"earliest"`, `"latest"` or `"pending"`, as in the [default block parameter](#the-default-block-parameter). -2. `QUANTITY` - the uncle's index position. - -```js -params: [ - '0x29c', // 668 - '0x0' // 0 -] -``` - -##### Returns - -See [eth_getBlockByHash](#eth_getblockbyhash) - -**Note**: An uncle doesn't contain individual transactions. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getUncleByBlockNumberAndIndex","params":["0x29c", "0x0"],"id":1}' -``` - -Result see [eth_getBlockByHash](#eth_getblockbyhash) - -*** - -#### eth_getCompilers - -Returns a list of available compilers in the client. - -##### Parameters -none - -##### Returns - -`Array` - Array of available compilers. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getCompilers","params":[],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": ["solidity", "lll", "serpent"] -} -``` - -*** - -#### eth_compileSolidity - -Returns compiled solidity code. - -##### Parameters - -1. `String` - The source code. - -```js -params: [ - "contract test { function multiply(uint a) returns(uint d) { return a * 7; } }", -] -``` - -##### Returns - -`DATA` - The compiled source code. - -##### Example -```js -// Request -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}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": { - "code": "0x605880600c6000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa114602e57005b603d6004803590602001506047565b8060005260206000f35b60006007820290506053565b91905056", - "info": { - "source": "contract test {\n function multiply(uint a) constant returns(uint d) {\n return a * 7;\n }\n}\n", - "language": "Solidity", - "languageVersion": "0", - "compilerVersion": "0.9.19", - "abiDefinition": [ - { - "constant": true, - "inputs": [ - { - "name": "a", - "type": "uint256" - } - ], - "name": "multiply", - "outputs": [ - { - "name": "d", - "type": "uint256" - } - ], - "type": "function" - } - ], - "userDoc": { - "methods": {} - }, - "developerDoc": { - "methods": {} - } - } - -} -``` - -*** - -#### eth_compileLLL - -Returns compiled LLL code. - -##### Parameters - -1. `String` - The source code. - -```js -params: [ - "(returnlll (suicide (caller)))", -] -``` - -##### Returns - -`DATA` - The compiled source code. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_compileSolidity","params":["(returnlll (suicide (caller)))"],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x603880600c6000396000f3006001600060e060020a600035048063c6888fa114601857005b6021600435602b565b8060005260206000f35b600081600702905091905056" // the compiled source code -} -``` - -*** - -#### eth_compileSerpent - -Returns compiled serpent code. - -##### Parameters - -1. `String` - The source code. - -```js -params: [ - "/* some serpent */", -] -``` - -##### Returns - -`DATA` - The compiled source code. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_compileSerpent","params":["/* some serpent */"],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x603880600c6000396000f3006001600060e060020a600035048063c6888fa114601857005b6021600435602b565b8060005260206000f35b600081600702905091905056" // the compiled source code -} -``` - -*** - -#### eth_newFilter - -Creates a filter object, based on filter options, to notify when the state changes (logs). -To check if the state has changed, call [eth_getFilterChanges](#eth_getfilterchanges). - -##### Parameters - -1. `Object` - The filter options: - - `fromBlock`: `QUANTITY|TAG` - (optional, default: `"latest"`) Integer block number, or `"latest"` for the last mined block or `"pending"`, `"earliest"` for not yet mined transactions. - - `toBlock`: `QUANTITY|TAG` - (optional, default: `"latest"`) Integer block number, or `"latest"` for the last mined block or `"pending"`, `"earliest"` for not yet mined transactions. - - `address`: `DATA|Array`, 20 Bytes - (optional) Contract address or a list of addresses from which logs should originate. - - `topics`: `Array of DATA`, - (optional) Array of 32 Bytes `DATA` topics. Each topic can also be an array of DATA with "or" options. - -```js -params: [{ - "fromBlock": "0x1", - "toBlock": "0x2", - "address": "0x8888f1f195afa192cfee860698584c030f4c9db1", - "topics": ["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b", null, [0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b, 0x000000000000000000000000aff3454fce5edbc8cca8697c15331677e6ebccc]] -}] -``` - -##### Returns - -`QUANTITY` - A filter id. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_newFilter","params":[{"topics":["0x12341234"]}],"id":73}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x1" // 1 -} -``` - -*** - -#### eth_newBlockFilter - -Creates a filter in the node, to notify when a new block arrives. -To check if the state has changed, call [eth_getFilterChanges](#eth_getfilterchanges). - -##### Parameters -None - -##### Returns - -`QUANTITY` - A filter id. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_newBlockFilter","params":[],"id":73}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x1" // 1 -} -``` - -*** - -#### eth_newPendingTransactionFilter - -Creates a filter in the node, to notify when new pending transactions arrive. -To check if the state has changed, call [eth_getFilterChanges](#eth_getfilterchanges). - -##### Parameters -None - -##### Returns - -`QUANTITY` - A filter id. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_newPendingTransactionFilter","params":[],"id":73}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x1" // 1 -} -``` - -*** - -#### eth_uninstallFilter - -Uninstalls a filter with given id. Should always be called when watch is no longer needed. -Additonally Filters timeout when they aren't requested with [eth_getFilterChanges](#eth_getfilterchanges) for a period of time. - - -##### Parameters - -1. `QUANTITY` - The filter id. - -```js -params: [ - "0xb" // 11 -] -``` - -##### Returns - -`Boolean` - `true` if the filter was successfully uninstalled, otherwise `false`. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_uninstallFilter","params":["0xb"],"id":73}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": true -} -``` - -*** - -#### eth_getFilterChanges - -Polling method for a filter, which returns an array of logs which occurred since last poll. - - -##### Parameters - -1. `QUANTITY` - the filter id. - -```js -params: [ - "0x16" // 22 -] -``` - -##### Returns - -`Array` - Array of log objects, or an empty array if nothing has changed since last poll. - -- For filters created with `eth_newBlockFilter` the return are block hashes (`DATA`, 32 Bytes), e.g. `["0x3454645634534..."]`. -- For filters created with `eth_newPendingTransactionFilter ` the return are transaction hashes (`DATA`, 32 Bytes), e.g. `["0x6345343454645..."]`. -- For filters created with `eth_newFilter` logs are objects with following params: - - - `type`: `TAG` - `pending` when the log is pending. `mined` if log is already mined. - - `logIndex`: `QUANTITY` - integer of the log index position in the block. `null` when its pending log. - - `transactionIndex`: `QUANTITY` - integer of the transactions index position log was created from. `null` when its pending log. - - `transactionHash`: `DATA`, 32 Bytes - hash of the transactions this log was created from. `null` when its pending log. - - `blockHash`: `DATA`, 32 Bytes - hash of the block where this log was in. `null` when its pending. `null` when its pending log. - - `blockNumber`: `QUANTITY` - the block number where this log was in. `null` when its pending. `null` when its pending log. - - `address`: `DATA`, 20 Bytes - address from which this log originated. - - `data`: `DATA` - contains one or more 32 Bytes non-indexed arguments of the log. - - `topics`: `Array of DATA` - Array of 0 to 4 32 Bytes `DATA` of indexed log arguments. (In *solidity*: The first topic is the *hash* of the signature of the event (e.g. `Deposit(address,bytes32,uint256)`), except you declared the event with the `anonymous` specifier.) - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getFilterChanges","params":["0x16"],"id":73}' - -// Result -{ - "id":1, - "jsonrpc":"2.0", - "result": [{ - "logIndex": "0x1", // 1 - "blockNumber":"0x1b4" // 436 - "blockHash": "0x8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcfdf829c5a142f1fccd7d", - "transactionHash": "0xdf829c5a142f1fccd7d8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcf", - "transactionIndex": "0x0", // 0 - "address": "0x16c5785ac562ff41e2dcfdf829c5a142f1fccd7d", - "data":"0x0000000000000000000000000000000000000000000000000000000000000000", - "topics": ["0x59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a5"] - },{ - ... - }] -} -``` - -*** - -#### eth_getFilterLogs - -Returns an array of all logs matching filter with given id. - - -##### Parameters - -1. `QUANTITY` - The filter id. - -```js -params: [ - "0x16" // 22 -] -``` - -##### Returns - -See [eth_getFilterChanges](#eth_getfilterchanges) - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getFilterLogs","params":["0x16"],"id":74}' -``` - -Result see [eth_getFilterChanges](#eth_getfilterchanges) - -*** - -#### eth_getLogs - -Returns an array of all logs matching a given filter object. - -##### Parameters - -1. `Object` - the filter object, see [eth_newFilter parameters](#eth_newfilter). - -```js -params: [{ - "topics": ["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b"] -}] -``` - -##### Returns - -See [eth_getFilterChanges](#eth_getfilterchanges) - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getLogs","params":[{"topics":["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b"]}],"id":74}' -``` - -Result see [eth_getFilterChanges](#eth_getfilterchanges) - -*** - -#### eth_getWork - -Returns the hash of the current block, the seedHash, and the boundary condition to be met ("target"). - -##### Parameters -none - -##### Returns - -`Array` - Array with the following properties: - 1. `DATA`, 32 Bytes - current block header pow-hash - 2. `DATA`, 32 Bytes - the seed hash used for the DAG. - 3. `DATA`, 32 Bytes - the boundary condition ("target"), 2^256 / difficulty. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getWork","params":[],"id":73}' - -// Result -{ - "id":1, - "jsonrpc":"2.0", - "result": [ - "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", - "0x5EED00000000000000000000000000005EED0000000000000000000000000000", - "0xd1ff1c01710000000000000000000000d1ff1c01710000000000000000000000" - ] -} -``` - -*** - -#### eth_submitWork - -Used for submitting a proof-of-work solution. - - -##### Parameters - -1. `DATA`, 8 Bytes - The nonce found (64 bits) -2. `DATA`, 32 Bytes - The header's pow-hash (256 bits) -3. `DATA`, 32 Bytes - The mix digest (256 bits) - -```js -params: [ - "0x0000000000000001", - "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", - "0xD1FE5700000000000000000000000000D1FE5700000000000000000000000000" -] -``` - -##### Returns - -`Boolean` - returns `true` if the provided solution is valid, otherwise `false`. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0", "method":"eth_submitWork", "params":["0x0000000000000001", "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", "0xD1GE5700000000000000000000000000D1GE5700000000000000000000000000"],"id":73}' - -// Result -{ - "id":1, - "jsonrpc":"2.0", - "result": true -} -``` - -*** - -#### eth_submitHashrate - -Used for submitting mining hashrate. - - -##### Parameters - -1. `Hashrate`, a hexadecimal string representation (32 bytes) of the hash rate -2. `ID`, String - A random hexadecimal(32 bytes) ID identifying the client - -```js -params: [ - "0x0000000000000000000000000000000000000000000000000000000000500000", - "0x59daa26581d0acd1fce254fb7e85952f4c09d0915afd33d3886cd914bc7d283c" -] -``` - -##### Returns - -`Boolean` - returns `true` if submitting went through succesfully and `false` otherwise. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0", "method":"eth_submitHashrate", "params":["0x0000000000000000000000000000000000000000000000000000000000500000", "0x59daa26581d0acd1fce254fb7e85952f4c09d0915afd33d3886cd914bc7d283c"],"id":73}' - -// Result -{ - "id":73, - "jsonrpc":"2.0", - "result": true -} -``` - -*** - -#### db_putString - -Stores a string in the local database. - -**Note** this function is deprecated and will be removed in the future. - -##### Parameters - -1. `String` - Database name. -2. `String` - Key name. -3. `String` - String to store. - -```js -params: [ - "testDB", - "myKey", - "myString" -] -``` - -##### Returns - -`Boolean` - returns `true` if the value was stored, otherwise `false`. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"db_putString","params":["testDB","myKey","myString"],"id":73}' - -// Result -{ - "id":1, - "jsonrpc":"2.0", - "result": true -} -``` - -*** - -#### db_getString - -Returns string from the local database. - -**Note** this function is deprecated and will be removed in the future. - -##### Parameters - -1. `String` - Database name. -2. `String` - Key name. - -```js -params: [ - "testDB", - "myKey", -] -``` - -##### Returns - -`String` - The previously stored string. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"db_getString","params":["testDB","myKey"],"id":73}' - -// Result -{ - "id":1, - "jsonrpc":"2.0", - "result": "myString" -} -``` - -*** - -#### db_putHex - -Stores binary data in the local database. - -**Note** this function is deprecated and will be removed in the future. - - -##### Parameters - -1. `String` - Database name. -2. `String` - Key name. -3. `DATA` - The data to store. - -```js -params: [ - "testDB", - "myKey", - "0x68656c6c6f20776f726c64" -] -``` - -##### Returns - -`Boolean` - returns `true` if the value was stored, otherwise `false`. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"db_putHex","params":["testDB","myKey","0x68656c6c6f20776f726c64"],"id":73}' - -// Result -{ - "id":1, - "jsonrpc":"2.0", - "result": true -} -``` - -*** - -#### db_getHex - -Returns binary data from the local database. - -**Note** this function is deprecated and will be removed in the future. - - -##### Parameters - -1. `String` - Database name. -2. `String` - Key name. - -```js -params: [ - "testDB", - "myKey", -] -``` - -##### Returns - -`DATA` - The previously stored data. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"db_getHex","params":["testDB","myKey"],"id":73}' - -// Result -{ - "id":1, - "jsonrpc":"2.0", - "result": "0x68656c6c6f20776f726c64" -} -``` - -*** - -#### shh_version - -Returns the current whisper protocol version. - -##### Parameters -none - -##### Returns - -`String` - The current whisper protocol version - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"shh_version","params":[],"id":67}' - -// Result -{ - "id":67, - "jsonrpc": "2.0", - "result": "2" -} -``` - -*** - -#### shh_post - -Sends a whisper message. - -##### Parameters - -1. `Object` - The whisper post object: - - `from`: `DATA`, 60 Bytes - (optional) The identity of the sender. - - `to`: `DATA`, 60 Bytes - (optional) The identity of the receiver. When present whisper will encrypt the message so that only the receiver can decrypt it. - - `topics`: `Array of DATA` - Array of `DATA` topics, for the receiver to identify messages. - - `payload`: `DATA` - The payload of the message. - - `priority`: `QUANTITY` - The integer of the priority in a rang from ... (?). - - `ttl`: `QUANTITY` - integer of the time to live in seconds. - -```js -params: [{ - from: "0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1", - to: "0x3e245533f97284d442460f2998cd41858798ddf04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a0d4d661997d3940272b717b1", - topics: ["0x776869737065722d636861742d636c69656e74", "0x4d5a695276454c39425154466b61693532"], - payload: "0x7b2274797065223a226d6", - priority: "0x64", - ttl: "0x64", -}] -``` - -##### Returns - -`Boolean` - returns `true` if the message was send, otherwise `false`. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"shh_post","params":[{"from":"0xc931d93e97ab07fe42d923478ba2465f2..","topics": ["0x68656c6c6f20776f726c64"],"payload":"0x68656c6c6f20776f726c64","ttl":"0x64","priority":"0x64"}],"id":73}' - -// Result -{ - "id":1, - "jsonrpc":"2.0", - "result": true -} -``` - -*** - -#### shh_newIdentity - -Creates new whisper identity in the client. - -##### Parameters -none - -##### Returns - -`DATA`, 60 Bytes - the address of the new identiy. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"shh_newIdentity","params":[],"id":73}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0xc931d93e97ab07fe42d923478ba2465f283f440fd6cabea4dd7a2c807108f651b7135d1d6ca9007d5b68aa497e4619ac10aa3b27726e1863c1fd9b570d99bbaf" -} -``` - -*** - -#### shh_hasIdentity - -Checks if the client hold the private keys for a given identity. - - -##### Parameters - -1. `DATA`, 60 Bytes - The identity address to check. - -```js -params: [ - "0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1" -] -``` - -##### Returns - -`Boolean` - returns `true` if the client holds the privatekey for that identity, otherwise `false`. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"shh_hasIdentity","params":["0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1"],"id":73}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": true -} -``` - -*** - -#### shh_newGroup - -(?) - -##### Parameters -none - -##### Returns - -`DATA`, 60 Bytes - the address of the new group. (?) - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"shh_newGroup","params":[],"id":73}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0xc65f283f440fd6cabea4dd7a2c807108f651b7135d1d6ca90931d93e97ab07fe42d923478ba2407d5b68aa497e4619ac10aa3b27726e1863c1fd9b570d99bbaf" -} -``` - -*** - -#### shh_addToGroup - -(?) - -##### Parameters - -1. `DATA`, 60 Bytes - The identity address to add to a group (?). - -```js -params: [ - "0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1" -] -``` - -##### Returns - -`Boolean` - returns `true` if the identity was successfully added to the group, otherwise `false` (?). - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"shh_addToGroup","params":["0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1"],"id":73}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": true -} -``` - -*** - -#### shh_newFilter - -Creates filter to notify, when client receives whisper message matching the filter options. - - -##### Parameters - -1. `Object` - The filter options: - - `to`: `DATA`, 60 Bytes - (optional) Identity of the receiver. *When present it will try to decrypt any incoming message if the client holds the private key to this identity.* - - `topics`: `Array of DATA` - Array of `DATA` topics which the incoming message's topics should match. You can use the following combinations: - - `[A, B] = A && B` - - `[A, [B, C]] = A && (B || C)` - - `[null, A, B] = ANYTHING && A && B` `null` works as a wildcard - -```js -params: [{ - "topics": ['0x12341234bf4b564f'], - "to": "0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1" -}] -``` - -##### Returns - -`QUANTITY` - The newly created filter. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"shh_newFilter","params":[{"topics": ['0x12341234bf4b564f'],"to": "0x2341234bf4b2341234bf4b564f..."}],"id":73}' - -// Result -{ - "id":1, - "jsonrpc":"2.0", - "result": "0x7" // 7 -} -``` - -*** - -#### shh_uninstallFilter - -Uninstalls a filter with given id. Should always be called when watch is no longer needed. -Additonally Filters timeout when they aren't requested with [shh_getFilterChanges](#shh_getfilterchanges) for a period of time. - - -##### Parameters - -1. `QUANTITY` - The filter id. - -```js -params: [ - "0x7" // 7 -] -``` - -##### Returns - -`Boolean` - `true` if the filter was successfully uninstalled, otherwise `false`. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"shh_uninstallFilter","params":["0x7"],"id":73}' - -// Result -{ - "id":1, - "jsonrpc":"2.0", - "result": true -} -``` - -*** - -#### shh_getFilterChanges - -Polling method for whisper filters. Returns new messages since the last call of this method. - -**Note** calling the [shh_getMessages](#shh_getmessages) method, will reset the buffer for this method, so that you won't receive duplicate messages. - - -##### Parameters - -1. `QUANTITY` - The filter id. - -```js -params: [ - "0x7" // 7 -] -``` - -##### Returns - -`Array` - Array of messages received since last poll: - - - `hash`: `DATA`, 32 Bytes (?) - The hash of the message. - - `from`: `DATA`, 60 Bytes - The sender of the message, if a sender was specified. - - `to`: `DATA`, 60 Bytes - The receiver of the message, if a receiver was specified. - - `expiry`: `QUANTITY` - Integer of the time in seconds when this message should expire (?). - - `ttl`: `QUANTITY` - Integer of the time the message should float in the system in seconds (?). - - `sent`: `QUANTITY` - Integer of the unix timestamp when the message was sent. - - `topics`: `Array of DATA` - Array of `DATA` topics the message contained. - - `payload`: `DATA` - The payload of the message. - - `workProved`: `QUANTITY` - Integer of the work this message required before it was send (?). - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"shh_getFilterChanges","params":["0x7"],"id":73}' - -// Result -{ - "id":1, - "jsonrpc":"2.0", - "result": [{ - "hash": "0x33eb2da77bf3527e28f8bf493650b1879b08c4f2a362beae4ba2f71bafcd91f9", - "from": "0x3ec052fc33..", - "to": "0x87gdf76g8d7fgdfg...", - "expiry": "0x54caa50a", // 1422566666 - "sent": "0x54ca9ea2", // 1422565026 - "ttl": "0x64" // 100 - "topics": ["0x6578616d"], - "payload": "0x7b2274797065223a226d657373616765222c2263686...", - "workProved": "0x0" - }] -} -``` - -*** - -#### shh_getMessages - -Get all messages matching a filter, which are still existing in the node's buffer. - -**Note** calling this method, will also reset the buffer for the [shh_getFilterChanges](#shh_getfilterchanges) method, so that you won't receive duplicate messages. - -##### Parameters - -1. `QUANTITY` - The filter id. - -```js -params: [ - "0x7" // 7 -] -``` - -##### Returns - -See [shh_getFilterChanges](#shh_getfilterchanges) - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"shh_getMessages","params":["0x7"],"id":73}' -``` - -Result see [shh_getFilterChanges](#shh_getfilterchanges) diff --git a/pages/dapp-development/JavaScript-API.md b/pages/dapp-development/JavaScript-API.md deleted file mode 100644 index 213269b39..000000000 --- a/pages/dapp-development/JavaScript-API.md +++ /dev/null @@ -1,2416 +0,0 @@ ---- -name: Javascript API -category: ---- - -# Web3 JavaScript Ðapp API - -To make your Ðapp work on Ethereum, you can use the `web3` object provided by the [web3.js library](https://github.com/ethereum/web3.js). Under the hood it communicates to a local node through [RPC calls](https://github.com/ethereum/wiki/wiki/JSON-RPC). web3.js works with any Ethereum node, which exposes an RPC layer. - -`web3` contains the `eth` object - `web3.eth` (for specifically Ethereum blockchain interactions) and the `shh` object - `web3.shh` (for Whisper interaction). Over time we'll introduce other objects for each of the other web3 protocols. Working [examples can be found here](https://github.com/ethereum/web3.js/tree/master/example). - -If you want to look at some more sophisticated examples using web3.js check out these [useful Ðapp patterns](https://github.com/ethereum/wiki/wiki/Useful-Ðapp-Patterns). - -## Using callbacks - -As this API is designed to work with a local RPC node and all its functions are by default use synchronous HTTP requests.con - -If you want to make an asynchronous request, you can pass an optional callback as the last parameter to most functions. -All callbacks are using an [error first callback](http://fredkschott.com/post/2014/03/understanding-error-first-callbacks-in-node-js/) style: - -```js -web3.eth.getBlock(48, function(error, result){ - if(!error) - console.log(result) - else - console.error(error); -}) -``` - -## Batch requests - -Batch requests allow queuing up requests and processing them at once. - -```js -var batch = web3.createBatch(); -batch.add(web3.eth.getBalance.request('0x0000000000000000000000000000000000000000', 'latest', callback)); -batch.add(web3.eth.contract(abi).at(address).balance.request(address, callback2)); -batch.execute(); -``` - -## A note on big numbers in web3.js - -You will always get a BigNumber object for balance values as JavaScript is not able to handle big numbers correctly. -Look at the following examples: - -```js -"101010100324325345346456456456456456456" -// "101010100324325345346456456456456456456" -101010100324325345346456456456456456456 -// 1.0101010032432535e+38 -``` - -web3.js depends on the [BigNumber Library](https://github.com/MikeMcl/bignumber.js/) and adds it automatically. - -```js -var balance = new BigNumber('131242344353464564564574574567456'); -// or var balance = web3.eth.getBalance(someAddress); - -balance.plus(21).toString(10); // toString(10) converts it to a number string -// "131242344353464564564574574567477" -``` - -The next example wouldn't work as we have more than 20 floating points, therefore it is recommended that you always keep your balance in *wei* and only transform it to other units when presenting to the user: -```js -var balance = new BigNumber('13124.234435346456466666457455567456'); - -balance.plus(21).toString(10); // toString(10) converts it to a number string, but can only show max 20 floating points -// "13145.23443534645646666646" // you number would be cut after the 20 floating point -``` - -## Web3 Javascript Ðapp API Reference - -* [web3](#web3) - * [version](#web3versionapi) - * [api](#web3versionapi) - * [node](#web3versionnode) - * [network](#web3versionnetwork) - * [ethereum](#web3versionethereum) - * [whisper](#web3versionwhisper) - * [isConnected()](#web3isconnected) - * [setProvider(provider)](#web3setprovider) - * [currentProvider](#web3currentprovider) - * [reset()](#web3reset) - * [sha3(string)](#web3sha3) - * [toHex(stringOrNumber)](#web3tohex) - * [toAscii(hexString)](#web3toascii) - * [fromAscii(textString, [padding])](#web3fromascii) - * [toDecimal(hexString)](#web3todecimal) - * [toChecksumAddress(string)](#web3tochecksumaddress) - * [fromDecimal(number)](#web3fromdecimal) - * [fromWei(numberStringOrBigNumber, unit)](#web3fromwei) - * [toWei(numberStringOrBigNumber, unit)](#web3towei) - * [toBigNumber(numberOrHexString)](#web3tobignumber) - * [isAddress(hexString)](#web3isAddress) - * [net](#web3net) - * [listening/getListening](#web3netlistening) - * [peerCount/getPeerCount](#web3ethpeercount) - * [eth](#web3eth) - * [defaultAccount](#web3ethdefaultaccount) - * [defaultBlock](#web3ethdefaultblock) - * [syncing/getSyncing](#web3ethsyncing) - * [isSyncing](#web3ethissyncing) - * [coinbase/getCoinbase](#web3ethcoinbase) - * [hashrate/getHashrate](#web3ethhashrate) - * [gasPrice/getGasPrice](#web3ethgasprice) - * [accounts/getAccounts](#web3ethaccounts) - * [mining/getMining](#web3ethmining) - * [blockNumber/getBlockNumber](#web3ethblocknumber) - * [register(hexString)](#web3ethregister) (Not implemented yet) - * [unRegister(hexString)](#web3ethunregister) (Not implemented yet) - * [getBalance(address)](#web3ethgetbalance) - * [getStorageAt(address, position)](#web3ethgetstorageat) - * [getCode(address)](#web3ethgetcode) - * [getBlock(hash/number)](#web3ethgetblock) - * [getBlockTransactionCount(hash/number)](#web3ethgetblocktransactioncount) - * [getUncle(hash/number)](#web3ethgetuncle) - * [getBlockUncleCount(hash/number)](#web3ethgetblockunclecount) - * [getTransaction(hash)](#web3ethgettransaction) - * [getTransactionFromBlock(hashOrNumber, indexNumber)](#web3ethgettransactionfromblock) - * [getTransactionReceipt(hash)](#web3ethgettransactionreceipt) - * [getTransactionCount(address)](#web3ethgettransactioncount) - * [sendTransaction(object)](#web3ethsendtransaction) - * [call(object)](#web3ethcall) - * [estimateGas(object)](#web3ethestimategas) - * [filter(array (, options) )](#web3ethfilter) - - [watch(callback)](#web3ethfilter) - - [stopWatching(callback)](#web3ethfilter) - - [get()](#web3ethfilter) - * [contract(abiArray)](#web3ethcontract) - * [contract.myMethod()](#contract-methods) - * [contract.myEvent()](#contract-events) - * [contract.allEvents()](#contract-allevents) - * [getCompilers()](#web3ethgetcompilers) - * [compile.lll(string)](#web3ethcompilelll) - * [compile.solidity(string)](#web3ethcompilesolidity) - * [compile.serpent(string)](#web3ethcompileserpent) - * [namereg](#web3ethnamereg) - * [sendIBANTransaction](#web3ethsendibantransaction) - * [iban](#web3ethiban) - * [fromAddress](#web3ethibanfromaddress) - * [fromBban](#web3ethibanfrombban) - * [createIndirect](#web3ethibancreateindirect) - * [isValid](#web3ethibanisvalid) - * [isDirect](#web3ethibanisdirect) - * [isIndirect](#web3ethibanisindirect) - * [checksum](#web3ethibanchecksum) - * [institution](#web3ethibaninstitution) - * [client](#web3ethibanclient) - * [address](#web3ethibanaddress) - * [toString](#web3ethibantostring) - * [db](#web3db) - * [putString(name, key, value)](#web3dbputstring) - * [getString(name, key)](#web3dbgetstring) - * [putHex(name, key, value)](#web3dbputhex) - * [getHex(name, key)](#web3dbgethex) - * [shh](#web3shh) - * [post(postObject)](#web3shhpost) - * [newIdentity()](#web3shhnewidentity) - * [hasIdentity(hexString)](#web3shhhaveidentity) - * [newGroup(_id, _who)](#web3shhnewgroup) - * [addToGroup(_id, _who)](#web3shhaddtogroup) - * [filter(object/string)](#web3shhfilter) - * [watch(callback)](#web3shhfilter) - * [stopWatching(callback)](#web3shhfilter) - * [get(callback)](#web3shhfilter) - -### Usage - -#### web3 -The `web3` object provides all methods. - -##### Example - -```js -var Web3 = require('web3'); -// create an instance of web3 using the HTTP provider. -// NOTE in mist web3 is already available, so check first if it's available before instantiating -var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); -``` - -*** - -#### web3.version.api - -```js -web3.version.api -// or async -web3.version.getApi(callback(error, result){ ... }) -``` - -##### Returns - -`String` - The ethereum js api version. - -##### Example - -```js -var version = web3.version.api; -console.log(version); // "0.2.0" -``` - -*** - -#### web3.version.node - - web3.version.node - // or async - web3.version.getClient(callback(error, result){ ... }) - - -##### Returns - -`String` - The client/node version. - -##### Example - -```js -var version = web3.version.node; -console.log(version); // "Mist/v0.9.3/darwin/go1.4.1" -``` - -*** - -#### web3.version.network - - web3.version.network - // or async - web3.version.getNetwork(callback(error, result){ ... }) - - -##### Returns - -`String` - The network protocol version. - -##### Example - -```js -var version = web3.version.network; -console.log(version); // 54 -``` - -*** - -#### web3.version.ethereum - - web3.version.ethereum - // or async - web3.version.getEthereum(callback(error, result){ ... }) - - -##### Returns - -`String` - The ethereum protocol version. - -##### Example - -```js -var version = web3.version.ethereum; -console.log(version); // 60 -``` - -*** - -#### web3.version.whisper - - web3.version.whisper - // or async - web3.version.getWhisper(callback(error, result){ ... }) - - -##### Returns - -`String` - The whisper protocol version. - -##### Example - -```js -var version = web3.version.whisper; -console.log(version); // 20 -``` - -*** -#### web3.isConnected - - web3.isConnected() - -Should be called to check if a connection to a node exists - -##### Parameters -none - -##### Returns - -`Boolean` - -##### Example - -```js -if(!web3.isConnected()) { - - // show some dialog to ask the user to start a node - -} else { - - // start web3 filters, calls, etc - -} -``` - -*** - -#### web3.setProvider - - web3.setProvider(provider) - -Should be called to set provider. - -##### Parameters -none - -##### Returns - -`undefined` - -##### Example - -```js -web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545')); // 8080 for cpp/AZ, 8545 for go/mist -``` - -*** - -#### web3.currentProvider - - web3.currentProvider - -Will contain the current provider, if one is set. This can be used to check if mist etc. set already a provider. - - -##### Returns - -`Object` - The provider set or `null`; - -##### Example - -```js -// Check if mist etc. already set a provider -if(!web3.currentProvider) - web3.setProvider(new web3.providers.HttpProvider("http://localhost:8545")); - -``` - -*** - -#### web3.reset - - web3.reset(keepIsSyncing) - -Should be called to reset state of web3. Resets everything except manager. Uninstalls all filters. Stops polling. - -##### Parameters - -1. `Boolean` - If `true` it will uninstall all filters, but will keep the [web3.eth.isSyncing()](#web3ethissyncing) polls - -##### Returns - -`undefined` - -##### Example - -```js -web3.reset(); -``` - -*** - -#### web3.sha3 - - web3.sha3(string [, callback]) - -##### Parameters - -1. `String` - The string to hash using the SHA3 algorithm -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -`String` - The SHA3 of the given data. - -##### Example - -```js -var str = web3.sha3("Some ASCII string to be hashed"); -console.log(str); // "0x536f6d6520415343494920737472696e6720746f20626520686173686564" - -var hash = web3.sha3(str); -console.log(hash); // "0xb21dbc7a5eb6042d91f8f584af266f1a512ac89520f43562c6c1e37eab6eb0c4" -``` - -*** - -#### web3.toHex - - web3.toHex(mixed); - -Converts any value into HEX. - -##### Parameters - -1. `String|Number|Object|Array|BigNumber` - The value to parse to HEX. If its an object or array it will be `JSON.stringify` first. If its a BigNumber it will make it the HEX value of a number. - -##### Returns - -`String` - The hex string of `mixed`. - -##### Example - -```js -var str = web3.toHex({test: 'test'}); -console.log(str); // '0x7b2274657374223a2274657374227d' -``` - -*** - -#### web3.toAscii - - web3.toAscii(hexString); - -Converts a HEX string into a ASCII string. - -##### Parameters - -1. `String` - A HEX string to be converted to ascii. - -##### Returns - -`String` - An ASCII string made from the given `hexString`. - -##### Example - -```js -var str = web3.toAscii("0x657468657265756d000000000000000000000000000000000000000000000000"); -console.log(str); // "ethereum" -``` - -*** - -#### web3.fromAscii - - web3.fromAscii(string [, padding]); - -Converts any ASCII string to a HEX string. - -##### Parameters - -1. `String` - An ASCII string to be converted to HEX. -2. `Number` - The number of bytes the returned HEX string should have. - -##### Returns - -`String` - The converted HEX string. - -##### Example - -```js -var str = web3.fromAscii('ethereum'); -console.log(str); // "0x657468657265756d" - -var str2 = web3.fromAscii('ethereum', 32); -console.log(str2); // "0x657468657265756d000000000000000000000000000000000000000000000000" -``` - -*** - -#### web3.toChecksumAddress - - web3.toChecksumAddress(hexString); - -Converts a string to the checksummed address equivalent. - -##### Parameters - -1. `String` - A string to be converted to a checksummed address. - - -##### Returns - -`String` - A string containing the checksummed address. - -##### Example - -```js -var myAddress = web3.toChecksumAddress('0xa0c876ec9f2d817c4304a727536f36363840c02c'); -console.log(myAddress); // '0xA0C876eC9F2d817c4304A727536f36363840c02c' -``` - -*** - -#### web3.toDecimal - - web3.toDecimal(hexString); - -Converts a HEX string to its number representation. - -##### Parameters - -1. `String` - An HEX string to be converted to a number. - - -##### Returns - -`Number` - The number representing the data `hexString`. - -##### Example - -```js -var number = web3.toDecimal('0x15'); -console.log(number); // 21 -``` - -*** - -#### web3.fromDecimal - - web3.fromDecimal(number); - -Converts a number or number string to its HEX representation. - -##### Parameters - -1. `Number|String` - A number to be converted to a HEX string. - -##### Returns - -`String` - The HEX string representing of the given `number`. - -##### Example - -```js -var value = web3.fromDecimal('21'); -console.log(value); // "0x15" -``` - -*** - -#### web3.fromWei - - web3.fromWei(number, unit) - -Converts a number of wei into the following ethereum units: - -- `kwei`/`ada` -- `mwei`/`babbage` -- `gwei`/`shannon` -- `szabo` -- `finney` -- `ether` -- `kether`/`grand`/`einstein` -- `mether` -- `gether` -- `tether` - -##### Parameters - -1. `Number|String|BigNumber` - A number or BigNumber instance. -2. `String` - One of the above ether units. - - -##### Returns - -`String|BigNumber` - Either a number string, or a BigNumber instance, depending on the given `number` parameter. - -##### Example - -```js -var value = web3.fromWei('21000000000000', 'finney'); -console.log(value); // "0.021" -``` - -*** - -#### web3.toWei - - web3.toWei(number, unit) - -Converts an ethereum unit into wei. Possible units are: - -- `kwei`/`ada` -- `mwei`/`babbage` -- `gwei`/`shannon` -- `szabo` -- `finney` -- `ether` -- `kether`/`grand`/`einstein` -- `mether` -- `gether` -- `tether` - -##### Parameters - -1. `Number|String|BigNumber` - A number or BigNumber instance. -2. `String` - One of the above ether units. - -##### Returns - -`String|BigNumber` - Either a number string, or a BigNumber instance, depending on the given `number` parameter. - -##### Example - -```js -var value = web3.toWei('1', 'ether'); -console.log(value); // "1000000000000000000" -``` - -*** - -#### web3.toBigNumber - - web3.toBigNumber(numberOrHexString); - -Converts a given number into a BigNumber instance. - -See the [note on BigNumber](#a-note-on-big-numbers-in-javascript). - -##### Parameters - -1. `Number|String` - A number, number string or HEX string of a number. - - -##### Returns - -`BigNumber` - A BigNumber instance representing the given value. - - -##### Example - -```js -var value = web3.toBigNumber('200000000000000000000001'); -console.log(value); // instanceOf BigNumber -console.log(value.toNumber()); // 2.0000000000000002e+23 -console.log(value.toString(10)); // '200000000000000000000001' -``` - -*** - -### web3.net - -#### web3.net.listening - - web3.net.listening - // or async - web3.net.getListening(callback(error, result){ ... }) - -This property is read only and says whether the node is actively listening for network connections or not. - -##### Returns - -`Boolean` - `true` if the client is actively listening for network connections, otherwise `false`. - -##### Example - -```js -var listening = web3.net.listening; -console.log(listening); // true of false -``` - -*** - -#### web3.net.peerCount - - web3.net.peerCount - // or async - web3.net.getPeerCount(callback(error, result){ ... }) - -This property is read only and returns the number of connected peers. - -##### Returns - -`Number` - The number of peers currently connected to the client. - -##### Example - -```js -var peerCount = web3.net.peerCount; -console.log(peerCount); // 4 -``` - -*** - -### web3.eth - -Contains the ethereum blockchain related methods. - -##### Example - -```js -var eth = web3.eth; -``` - -*** - -#### web3.eth.defaultAccount - - web3.eth.defaultAccount - -This default address is used for the following methods (optionally you can overwrite it by specifying the `from` property): - -- [web3.eth.sendTransaction()](#web3ethsendtransaction) -- [web3.eth.call()](#web3ethcall) - -##### Values - -`String`, 20 Bytes - Any address you own, or where you have the private key for. - -*Default is* `undefined`. - -##### Returns - -`String`, 20 Bytes - The currently set default address. - -##### Example - -```js -var defaultAccount = web3.eth.defaultAccount; -console.log(defaultAccount); // '' - -// set the default block -web3.eth.defaultAccount = '0x8888f1f195afa192cfee860698584c030f4c9db1'; -``` - -*** - -#### web3.eth.defaultBlock - - web3.eth.defaultBlock - -This default block is used for the following methods (optionally you can overwrite the defaultBlock by passing it as the last parameter): - -- [web3.eth.getBalance()](#web3ethgetbalance) -- [web3.eth.getCode()](#web3ethgetcode) -- [web3.eth.getTransactionCount()](#web3ethgettransactioncount) -- [web3.eth.getStorageAt()](#web3ethgetstorageat) -- [web3.eth.call()](#web3ethcall) - -##### Values - -Default block parameters can be one of the following: - -- `Number` - a block number -- `String` - `"earliest"`, the genisis block -- `String` - `"latest"`, the latest block (current head of the blockchain) -- `String` - `"pending"`, the currently mined block (including pending transactions) - -*Default is* `latest` - -##### Returns - -`Number|String` - The default block number to use when querying a state. - -##### Example - -```js -var defaultBlock = web3.eth.defaultBlock; -console.log(defaultBlock); // 'latest' - -// set the default block -web3.eth.defaultBlock = 231; -``` - -*** - -#### web3.eth.syncing - - web3.eth.syncing - // or async - web3.eth.getSyncing(callback(error, result){ ... }) - -This property is read only and returns the either a sync object, when the node is syncing or `false`. - -##### Returns - -`Object|Boolean` - A sync object as follows, when the node is currently syncing or `false`: - - `startingBlock`: `Number` - The block number where the sync started. - - `currentBlock`: `Number` - The block number where at which block the node currently synced to already. - - `highestBlock`: `Number` - The estimated block number to sync to. - -##### Example - -```js -var sync = web3.eth.syncing; -console.log(sync); -/* -{ - startingBlock: 300, - currentBlock: 312, - highestBlock: 512 -} -*/ -``` - -*** - -#### web3.eth.isSyncing - - web3.eth.isSyncing(callback); - -This convenience function calls the `callback` everytime a sync starts, updates and stops. - -##### Returns - -`Object` - a isSyncing object with the following methods: - - * `syncing.addCallback()`: Adds another callback, which will be called when the node starts or stops syncing. - * `syncing.stopWatching()`: Stops the syncing callbacks. - -##### Callback return value - -- `Boolean` - The callback will be fired with `true` when the syncing starts and with `false` when it stopped. -- `Object` - While syncing it will return the syncing object: - - `startingBlock`: `Number` - The block number where the sync started. - - `currentBlock`: `Number` - The block number where at which block the node currently synced to already. - - `highestBlock`: `Number` - The estimated block number to sync to. - - -##### Example - -```js -web3.eth.isSyncing(function(error, sync){ - if(!error) { - // stop all app activity - if(sync === true) { - // we use `true`, so it stops all filters, but not the web3.eth.syncing polling - web3.reset(true); - - // show sync info - } else if(sync) { - console.log(sync.currentBlock); - - // re-gain app operation - } else { - // run your app init function... - } - } -}); -``` - -*** - -#### web3.eth.coinbase - - web3.eth.coinbase - // or async - web3.eth.getCoinbase(callback(error, result){ ... }) - -This property is read only and returns the coinbase address were the mining rewards go to. - -##### Returns - -`String` - The coinbase address of the client. - -##### Example - -```js -var coinbase = web3.eth.coinbase; -console.log(coinbase); // "0x407d73d8a49eeb85d32cf465507dd71d507100c1" -``` - -*** - -#### web3.eth.mining - - web3.eth.mining - // or async - web3.eth.getMining(callback(error, result){ ... }) - - -This property is read only and says whether the node is mining or not. - - -##### Returns - -`Boolean` - `true` if the client is mining, otherwise `false`. - -##### Example - -```js -var mining = web3.eth.mining; -console.log(mining); // true or false -``` - -*** - -#### web3.eth.hashrate - - web3.eth.hashrate - // or async - web3.eth.getHashrate(callback(error, result){ ... }) - -This property is read only and returns the number of hashes per second that the node is mining with. - - -##### Returns - -`Number` - number of hashes per second. - -##### Example - -```js -var hashrate = web3.eth.hashrate; -console.log(hashrate); // 493736 -``` - -*** - -#### web3.eth.gasPrice - - web3.eth.gasPrice - // or async - web3.eth.getGasPrice(callback(error, result){ ... }) - - -This property is read only and returns the current gas price. -The gas price is determined by the x latest blocks median gas price. - -##### Returns - -`BigNumber` - A BigNumber instance of the current gas price in wei. - -See the [note on BigNumber](#a-note-on-big-numbers-in-javascript). - -##### Example - -```js -var gasPrice = web3.eth.gasPrice; -console.log(gasPrice.toString(10)); // "10000000000000" -``` - -*** - -#### web3.eth.accounts - - web3.eth.accounts - // or async - web3.eth.getAccounts(callback(error, result){ ... }) - -This property is read only and returns a list of accounts the node controls. - -##### Returns - -`Array` - An array of addresses controlled by client. - -##### Example - -```js -var accounts = web3.eth.accounts; -console.log(accounts); // ["0x407d73d8a49eeb85d32cf465507dd71d507100c1"] -``` - -*** - -#### web3.eth.blockNumber - - web3.eth.blockNumber - // or async - web3.eth.getBlockNumber(callback(error, result){ ... }) - -This property is read only and returns the current block number. - -##### Returns - -`Number` - The number of the most recent block. - -##### Example - -```js -var number = web3.eth.blockNumber; -console.log(number); // 2744 -``` - -*** - -#### web3.eth.register - - web3.eth.register(addressHexString [, callback]) - -(Not Implemented yet) -Registers the given address to be included in `web3.eth.accounts`. This allows non-private-key owned accounts to be associated as an owned account (e.g., contract wallets). - -##### Parameters - -1. `String` - The address to register -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -? - - -##### Example - -```js -web3.eth.register("0x407d73d8a49eeb85d32cf465507dd71d507100ca") -``` - -*** - -#### web3.eth.unRegister - - web3.eth.unRegister(addressHexString [, callback]) - - -(Not Implemented yet) -Unregisters a given address. - -##### Parameters - -1. `String` - The address to unregister. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -? - - -##### Example - -```js -web3.eth.unregister("0x407d73d8a49eeb85d32cf465507dd71d507100ca") -``` - -*** - -#### web3.eth.getBalance - - web3.eth.getBalance(addressHexString [, defaultBlock] [, callback]) - -Get the balance of an address at a given block. - -##### Parameters - -1. `String` - The address to get the balance of. -2. `Number|String` - (optional) If you pass this parameter it will not use the default block set with [web3.eth.defaultBlock](#web3ethdefaultblock). -3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - A BigNumber instance of the current balance for the given address in wei. - -See the [note on BigNumber](#a-note-on-big-numbers-in-javascript). - -##### Example - -```js -var balance = web3.eth.getBalance("0x407d73d8a49eeb85d32cf465507dd71d507100c1"); -console.log(balance); // instanceof BigNumber -console.log(balance.toString(10)); // '1000000000000' -console.log(balance.toNumber()); // 1000000000000 -``` - -*** - -#### web3.eth.getStorageAt - - web3.eth.getStorageAt(addressHexString, position [, defaultBlock] [, callback]) - -Get the storage at a specific position of an address. - -##### Parameters - -1. `String` - The address to get the storage from. -2. `Number` - The index position of the storage. -3. `Number|String` - (optional) If you pass this parameter it will not use the default block set with [web3.eth.defaultBlock](#web3ethdefaultblock). -4. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -`String` - The value in storage at the given position. - -##### Example - -```js -var state = web3.eth.getStorageAt("0x407d73d8a49eeb85d32cf465507dd71d507100c1", 0); -console.log(state); // "0x03" -``` - -*** - -#### web3.eth.getCode - - web3.eth.getCode(addressHexString [, defaultBlock] [, callback]) - -Get the code at a specific address. - -##### Parameters - -1. `String` - The address to get the code from. -2. `Number|String` - (optional) If you pass this parameter it will not use the default block set with [web3.eth.defaultBlock](#web3ethdefaultblock). -3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - The data at given address `addressHexString`. - -##### Example - -```js -var code = web3.eth.getCode("0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8"); -console.log(code); // "0x600160008035811a818181146012578301005b601b6001356025565b8060005260206000f25b600060078202905091905056" -``` - -*** - -#### web3.eth.getBlock - - web3.eth.getBlock(blockHashOrBlockNumber [, returnTransactionObjects] [, callback]) - -Returns a block matching the block number or block hash. - -##### Parameters - -1. `String|Number` - The block number or hash. Or the string `"earliest"`, `"latest"` or `"pending"` as in the [default block parameter](#web3ethdefaultblock). -2. `Boolean` - (optional, default `false`) If `true`, the returned block will contain all transactions as objects, if `false` it will only contains the transaction hashes. -3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Object` - The block object: - - - `number`: `Number` - the block number. `null` when its pending block. - - `hash`: `String`, 32 Bytes - hash of the block. `null` when its pending block. - - `parentHash`: `String`, 32 Bytes - hash of the parent block. - - `nonce`: `String`, 8 Bytes - hash of the generated proof-of-work. `null` when its pending block. - - `sha3Uncles`: `String`, 32 Bytes - SHA3 of the uncles data in the block. - - `logsBloom`: `String`, 256 Bytes - the bloom filter for the logs of the block. `null` when its pending block. - - `transactionsRoot`: `String`, 32 Bytes - the root of the transaction trie of the block - - `stateRoot`: `String`, 32 Bytes - the root of the final state trie of the block. - - `miner`: `String`, 20 Bytes - the address of the beneficiary to whom the mining rewards were given. - - `difficulty`: `BigNumber` - integer of the difficulty for this block. - - `totalDifficulty`: `BigNumber` - integer of the total difficulty of the chain until this block. - - `extraData`: `String` - the "extra data" field of this block. - - `size`: `Number` - integer the size of this block in bytes. - - `gasLimit`: `Number` - the maximum gas allowed in this block. - - `gasUsed`: `Number` - the total used gas by all transactions in this block. - - `timestamp`: `Number` - the unix timestamp for when the block was collated. - - `transactions`: `Array` - Array of transaction objects, or 32 Bytes transaction hashes depending on the last given parameter. - - `uncles`: `Array` - Array of uncle hashes. - -##### Example - -```js -var info = web3.eth.block(3150); -console.log(info); -/* -{ - "number": 3, - "hash": "0xef95f2f1ed3ca60b048b4bf67cde2195961e0bba6f70bcbea9a2c4e133e34b46", - "parentHash": "0x2302e1c0b972d00932deb5dab9eb2982f570597d9d42504c05d9c2147eaf9c88", - "nonce": "0xfb6e1a62d119228b", - "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "transactionsRoot": "0x3a1b03875115b79539e5bd33fb00d8f7b7cd61929d5a3c574f507b8acf415bee", - "stateRoot": "0xf1133199d44695dfa8fd1bcfe424d82854b5cebef75bddd7e40ea94cda515bcb", - "miner": "0x8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty": BigNumber, - "totalDifficulty": BigNumber, - "size": 616, - "extraData": "0x", - "gasLimit": 3141592, - "gasUsed": 21662, - "timestamp": 1429287689, - "transactions": [ - "0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b" - ], - "uncles": [] -} -*/ -``` - -*** - -#### web3.eth.getBlockTransactionCount - - web3.eth.getBlockTransactionCount(hashStringOrBlockNumber [, callback]) - -Returns the number of transaction in a given block. - -##### Parameters - -1. `String|Number` - The block number or hash. Or the string `"earliest"`, `"latest"` or `"pending"` as in the [default block parameter](#web3ethdefaultblock). -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Number` - The number of transactions in the given block. - -##### Example - -```js -var number = web3.eth.getBlockTransactionCount("0x407d73d8a49eeb85d32cf465507dd71d507100c1"); -console.log(number); // 1 -``` - -*** - -#### web3.eth.getUncle - - web3.eth.getUncle(blockHashStringOrNumber, uncleNumber [, returnTransactionObjects] [, callback]) - -Returns a blocks uncle by a given uncle index position. - -##### Parameters - -1. `String|Number` - The block number or hash. Or the string `"earliest"`, `"latest"` or `"pending"` as in the [default block parameter](#web3ethdefaultblock). -2. `Number` - The index position of the uncle. -3. `Boolean` - (optional, default `false`) If `true`, the returned block will contain all transactions as objects, if `false` it will only contains the transaction hashes. -4. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -`Object` - the returned uncle. For a return value see [web3.eth.getBlock()](#web3ethgetblock). - -**Note**: An uncle doesn't contain individual transactions. - -##### Example - -```js -var uncle = web3.eth.getUncle(500, 0); -console.log(uncle); // see web3.eth.getBlock - -``` - -*** - -##### web3.eth.getTransaction - - web3.eth.getTransaction(transactionHash [, callback]) - -Returns a transaction matching the given transaction hash. - -##### Parameters - -1. `String` - The transaction hash. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -`Object` - A transaction object its hash `transactionHash`: - - - `hash`: `String`, 32 Bytes - hash of the transaction. - - `nonce`: `Number` - the number of transactions made by the sender prior to this one. - - `blockHash`: `String`, 32 Bytes - hash of the block where this transaction was in. `null` when its pending. - - `blockNumber`: `Number` - block number where this transaction was in. `null` when its pending. - - `transactionIndex`: `Number` - integer of the transactions index position in the block. `null` when its pending. - - `from`: `String`, 20 Bytes - address of the sender. - - `to`: `String`, 20 Bytes - address of the receiver. `null` when its a contract creation transaction. - - `value`: `BigNumber` - value transferred in Wei. - - `gasPrice`: `BigNumber` - gas price provided by the sender in Wei. - - `gas`: `Number` - gas provided by the sender. - - `input`: `String` - the data sent along with the transaction. - - -##### Example - -```js -var blockNumber = 668; -var indexOfTransaction = 0 - -var transaction = web3.eth.getTransaction(blockNumber, indexOfTransaction); -console.log(transaction); -/* -{ - "hash": "0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b", - "nonce": 2, - "blockHash": "0xef95f2f1ed3ca60b048b4bf67cde2195961e0bba6f70bcbea9a2c4e133e34b46", - "blockNumber": 3, - "transactionIndex": 0, - "from": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "to": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f", - "value": BigNumber, - "gas": 314159, - "gasPrice": BigNumber, - "input": "0x57cb2fc4" -} -*/ - -``` - -*** - -#### web3.eth.getTransactionFromBlock - - getTransactionFromBlock(hashStringOrNumber, indexNumber [, callback]) - -Returns a transaction based on a block hash or number and the transactions index position. - -##### Parameters - -1. `String` - A block number or hash. Or the string `"earliest"`, `"latest"` or `"pending"` as in the [default block parameter](#web3ethdefaultblock). -2. `Number` - The transactions index position. -3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Object` - A transaction object, see [web3.eth.getTransaction](#web3ethgettransaction): - - -##### Example - -```js -var transaction = web3.eth.getTransactionFromBlock('0x4534534534', 2); -console.log(transaction); // see web3.eth.getTransaction - -``` - -*** - -#### web3.eth.getTransactionReceipt - - web3.eth.getTransactionReceipt(hashString [, callback]) - -Returns the receipt of a transaction by transaction hash. - -**Note** That the receipt is not available for pending transactions. - - -##### Parameters - -1. `String` - The transaction hash. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Object` - A transaction receipt object, or `null` when no receipt was found: - - - `blockHash`: `String`, 32 Bytes - hash of the block where this transaction was in. - - `blockNumber`: `Number` - block number where this transaction was in. - - `transactionHash`: `String`, 32 Bytes - hash of the transaction. - - `transactionIndex`: `Number` - integer of the transactions index position in the block. - - `from`: `String`, 20 Bytes - address of the sender. - - `to`: `String`, 20 Bytes - address of the receiver. `null` when its a contract creation transaction. - - `cumulativeGasUsed `: `Number ` - The total amount of gas used when this transaction was executed in the block. - - `gasUsed `: `Number ` - The amount of gas used by this specific transaction alone. - - `contractAddress `: `String` - 20 Bytes - The contract address created, if the transaction was a contract creation, otherwise `null`. - - `logs `: `Array` - Array of log objects, which this transaction generated. - -##### Example -```js -var receipt = web3.eth.getTransactionReceipt('0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b'); -console.log(receipt); -{ - "transactionHash": "0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b", - "transactionIndex": 0, - "blockHash": "0xef95f2f1ed3ca60b048b4bf67cde2195961e0bba6f70bcbea9a2c4e133e34b46", - "blockNumber": 3, - "contractAddress": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "cumulativeGasUsed": 314159, - "gasUsed": 30234, - "logs": [{ - // logs as returned by getFilterLogs, etc. - }, ...] -} -``` - -*** - -#### web3.eth.getTransactionCount - - web3.eth.getTransactionCount(addressHexString [, defaultBlock] [, callback]) - -Get the numbers of transactions sent from this address. - -##### Parameters - -1. `String` - The address to get the numbers of transactions from. -2. `Number|String` - (optional) If you pass this parameter it will not use the default block set with [web3.eth.defaultBlock](#web3ethdefaultblock). -3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Number` - The number of transactions sent from the given address. - -##### Example - -```js -var number = web3.eth.getTransactionCount("0x407d73d8a49eeb85d32cf465507dd71d507100c1"); -console.log(number); // 1 -``` - -*** - -#### web3.eth.sendTransaction - - web3.eth.sendTransaction(transactionObject [, callback]) - -Sends a transaction to the network. - -##### Parameters - -1. `Object` - The transaction object to send: - - `from`: `String` - The address for the sending account. Uses the [web3.eth.defaultAccount](#web3ethdefaultaccount) property, if not specified. - - `to`: `String` - (optional) The destination address of the message, left undefined for a contract-creation transaction. - - `value`: `Number|String|BigNumber` - (optional) The value transferred for the transaction in Wei, also the endowment if it's a contract-creation transaction. - - `gas`: `Number|String|BigNumber` - (optional, default: To-Be-Determined) The amount of gas to use for the transaction (unused gas is refunded). - - `gasPrice`: `Number|String|BigNumber` - (optional, default: To-Be-Determined) The price of gas for this transaction in wei, defaults to the mean network gas price. - - `data`: `String` - (optional) Either a [byte string](https://github.com/ethereum/wiki/wiki/Solidity,-Docs-and-ABI) containing the associated data of the message, or in the case of a contract-creation transaction, the initialisation code. - - `nonce`: `Number` - (optional) Integer of a nonce. This allows to overwrite your own pending transactions that use the same nonce. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - The 32 Bytes transaction hash as HEX string. - -If the transaction was a contract creation use [web3.eth.getTransactionReceipt()](#web3gettransactionreceipt) to get the contract address, after the transaction was mined. - -##### Example - -```js - -// compiled solidity source code using https://chriseth.github.io/cpp-ethereum/ -var code = "603d80600c6000396000f3007c01000000000000000000000000000000000000000000000000000000006000350463c6888fa18114602d57005b600760043502 -8060005260206000f3"; - -web3.eth.sendTransaction({data: code}, function(err, address) { - if (!err) - console.log(address); // "0x7f9fade1c0d57a7af66ab4ead7c2eb7b11a91385" -}); -``` - -*** - -#### web3.eth.call - - web3.eth.call(callObject [, defaultBlock] [, callback]) - -Executes a message call transaction, which is directly executed in the VM of the node, but never mined into the blockchain. - -##### Parameters - -1. `Object` - A transaction object see [web3.eth.sendTransaction](#web3ethsendtransaction), with the difference that for calls the `from` property is optional as well. -2. `Number|String` - (optional) If you pass this parameter it will not use the default block set with [web3.eth.defaultBlock](#web3ethdefaultblock). -3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - The returned data of the call, e.g. a codes functions return value. - -##### Example - -```js -var result = web3.eth.call({ - to: "0xc4abd0339eb8d57087278718986382264244252f", - data: "0xc6888fa10000000000000000000000000000000000000000000000000000000000000003" -}); -console.log(result); // "0x0000000000000000000000000000000000000000000000000000000000000015" -``` - -*** - -#### web3.eth.estimateGas - - web3.eth.estimateGas(callObject [, defaultBlock] [, callback]) - -Executes a message call or transaction, which is directly executed in the VM of the node, but never mined into the blockchain and returns the amount of the gas used. - -##### Parameters - -See [web3.eth.sendTransaction](#web3ethsendtransaction), expect that all properties are optional. - -##### Returns - -`Number` - the used gas for the simulated call/transaction. - -##### Example - -```js -var result = web3.eth.estimateGas({ - to: "0xc4abd0339eb8d57087278718986382264244252f", - data: "0xc6888fa10000000000000000000000000000000000000000000000000000000000000003" -}); -console.log(result); // "0x0000000000000000000000000000000000000000000000000000000000000015" -``` - -*** - -#### web3.eth.filter - -```js -// can be 'latest' or 'pending' -var filter = web3.eth.filter(filterString); -// OR object are log filter options -var filter = web3.eth.filter(options); - -// watch for changes -filter.watch(function(error, result){ - if (!error) - console.log(result); -}); - -// Additionally you can start watching right away, by passing a callback: -web3.eth.filter(options, function(error, result){ - if (!error) - console.log(result); -}); -``` - -##### Parameters - -1. `String|Object` - The string `"latest"` or `"pending"` to watch for changes in the latest block or pending transactions respectively. Or a filter options object as follows: - * `fromBlock`: `Number|String` - The number of the earliest block (`latest` may be given to mean the most recent and `pending` currently mining, block). By default `latest`. - * `toBlock`: `Number|String` - The number of the latest block (`latest` may be given to mean the most recent and `pending` currently mining, block). By default `latest`. - * `address`: `String` - An address or a list of addresses to only get logs from particular account(s). - * `topics`: `Array of Strings` - An array of values which must each appear in the log entries. The order is important, if you want to leave topics out use `null`, e.g. `[null, '0x00...']`. You can also pass another array for each topic with options for that topic e.g. `[null, ['option1', 'option2']]` - -##### Returns - -`Object` - A filter object with the following methods: - - * `filter.get(callback)`: Returns all of the log entries that fit the filter. - * `filter.watch(callback)`: Watches for state changes that fit the filter and calls the callback. See [this note](#using-callbacks) for details. - * `filter.stopWatching()`: Stops the watch and uninstalls the filter in the node. Should always be called once it is done. - -##### Watch callback return value - -- `String` - When using the `"latest"` parameter, it returns the block hash of the last incoming block. -- `String` - When using the `"pending"` parameter, it returns a transaction hash of the last add pending transaction. -- `Object` - When using manual filter options, it returns a log object as follows: - - `logIndex`: `Number` - integer of the log index position in the block. `null` when its pending log. - - `transactionIndex`: `Number` - integer of the transactions index position log was created from. `null` when its pending log. - - `transactionHash`: `String`, 32 Bytes - hash of the transactions this log was created from. `null` when its pending log. - - `blockHash`: `String`, 32 Bytes - hash of the block where this log was in. `null` when its pending. `null` when its pending log. - - `blockNumber`: `Number` - the block number where this log was in. `null` when its pending. `null` when its pending log. - - `address`: `String`, 32 Bytes - address from which this log originated. - - `data`: `String` - contains one or more 32 Bytes non-indexed arguments of the log. - - `topics`: `Array of Strings` - Array of 0 to 4 32 Bytes `DATA` of indexed log arguments. (In *solidity*: The first topic is the *hash* of the signature of the event (e.g. `Deposit(address,bytes32,uint256)`), except you declared the event with the `anonymous` specifier.) - -**Note** For event filter return values see [Contract Events](#contract-events) - -##### Example - -```js -var filter = web3.eth.filter('pending'); - -filter.watch(function (error, log) { - console.log(log); // {"address":"0x0000000000000000000000000000000000000000", "data":"0x0000000000000000000000000000000000000000000000000000000000000000", ...} -}); - -// get all past logs again. -var myResults = filter.get(function(error, logs){ ... }); - -... - -// stops and uninstalls the filter -filter.stopWatching(); - -``` - -*** - -#### web3.eth.contract - - web3.eth.contract(abiArray) - -Creates a contract object for a solidity contract, which can be used to initiate contracts on an address. -You can read more about events [here](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI#example-javascript-usage). - -##### Parameters - -1. `Array` - ABI array with descriptions of functions and events of the contract. - -##### Returns - -`Object` - A contract object, which can be initiated as follows: - -```js -var MyContract = web3.eth.contract(abiArray); - -// instantiate by address -var contractInstance = MyContract.at([address]); - -// deploy new contract -var contractInstance = MyContract.new([contructorParam1] [, contructorParam2], {data: '0x12345...', from: myAccount, gas: 1000000}); - -// Get the data to deploy the contract manually -var contractData = MyContract.new.getData([contructorParam1] [, contructorParam2], {data: '0x12345...'}); -// contractData = '0x12345643213456000000000023434234' -``` - -And then you can either initiate an existing contract on an address, -or deploy the contract using the compiled byte code: - -```js -// Instantiate from an existing address: -var myContractInstance = MyContract.at(myContractAddress); - - -// Or deploy a new contract: - -// Deploy the contract asyncronous: -var myContractReturned = MyContract.new(param1, param2, { - data: myContractCode, - gas: 300000, - from: mySenderAddress}, function(err, myContract){ - if(!err) { - // NOTE: The callback will fire twice! - // Once the contract has the transactionHash property set and once its deployed on an address. - - // e.g. check tx hash on the first call (transaction send) - if(!myContract.address) { - console.log(myContract.transactionHash) // The hash of the transaction, which deploys the contract - - // check address on the second call (contract deployed) - } else { - console.log(myContract.address) // the contract address - } - - // Note that the returned "myContractReturned" === "myContract", - // so the returned "myContractReturned" object will also get the address set. - } - }); - -// Deploy contract syncronous: The address will be added as soon as the contract is mined. -// Additionally you can watch the transaction by using the "transactionHash" property -var myContractInstance = MyContract.new(param1, param2, {data: myContractCode, gas: 300000, from: mySenderAddress}); -myContractInstance.transactionHash // The hash of the transaction, which created the contract -myContractInstance.address // undefined at start, but will be auto-filled later -``` - -**Note** When you deploy a new contract, you should check for the next 12 blocks or so if the contract code is still at the address (using [web3.eth.getCode()](#web3ethgetcode)), to make sure a fork didn't change that. - -##### Example - -```js -// contract abi -var abi = [{ - name: 'myConstantMethod', - type: 'function', - constant: true, - inputs: [{ name: 'a', type: 'string' }], - outputs: [{name: 'd', type: 'string' }] -}, { - name: 'myStateChangingMethod', - type: 'function', - constant: false, - inputs: [{ name: 'a', type: 'string' }, { name: 'b', type: 'int' }], - outputs: [] -}, { - name: 'myEvent', - type: 'event', - inputs: [{name: 'a', type: 'int', indexed: true},{name: 'b', type: 'bool', indexed: false] -}]; - -// creation of contract object -var MyContract = web3.eth.contract(abi); - -// initiate contract for an address -var myContractInstance = MyContract.at('0xc4abd0339eb8d57087278718986382264244252f'); - -// call constant function -var result = myContractInstance.myConstantMethod('myParam'); -console.log(result) // '0x25434534534' - -// send a transaction to a function -myContractInstance.myStateChangingMethod('someParam1', 23, {value: 200, gas: 2000}); - -// short hand style -web3.eth.contract(abi).at(address).myAwesomeMethod(...); - -// create filter -var filter = myContractInstance.myEvent({a: 5}, function (error, result) { - if (!error) - console.log(result); - /* - { - address: '0x8718986382264244252fc4abd0339eb8d5708727', - topics: "0x12345678901234567890123456789012", "0x0000000000000000000000000000000000000000000000000000000000000005", - data: "0x0000000000000000000000000000000000000000000000000000000000000001", - ... - } - */ -}); -``` - -*** - -#### Contract Methods - -```js -// Automatically determines the use of call or sendTransaction based on the method type -myContractInstance.myMethod(param1 [, param2, ...] [, transactionObject] [, callback]); - -// Explicitly calling this method -myContractInstance.myMethod.call(param1 [, param2, ...] [, transactionObject] [, callback]); - -// Explicitly sending a transaction to this method -myContractInstance.myMethod.sendTransaction(param1 [, param2, ...] [, transactionObject] [, callback]); - -// Explicitly sending a transaction to this method -myContractInstance.myMethod.sendTransaction(param1 [, param2, ...] [, transactionObject] [, callback]); - -// Get the call data, so you can call the contract through some other means -var myCallData = myContractInstance.myMethod.getData(param1 [, param2, ...]); -// myCallData = '0x45ff3ff6000000000004545345345345..' -``` - -The contract object exposes the contracts methods, which can be called using parameters and a transaction object. - -##### Parameters - -- `String|Number` - (optional) Zero or more parameters of the function. -- `Object` - (optional) The (previous) last parameter can be a transaction object, see [web3.eth.sendTransaction](#web3ethsendtransaction) parameter 1 for more. -- `Function` - (optional) If you pass a callback as the last parameter the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - If its a call the result data, if its a send transaction a created contract address, or the transaction hash, see [web3.eth.sendTransaction](#web3ethsendtransaction) for details. - - -##### Example - -```js -// creation of contract object -var MyContract = web3.eth.contract(abi); - -// initiate contract for an address -var myContractInstance = MyContract.at('0x78e97bcc5b5dd9ed228fed7a4887c0d7287344a9'); - -var result = myContractInstance.myConstantMethod('myParam'); -console.log(result) // '0x25434534534' - -myContractInstance.myStateChangingMethod('someParam1', 23, {value: 200, gas: 2000}, function(err, result){ ... }); -``` - -*** - - -#### Contract Events - -```js -var event = myContractInstance.MyEvent({valueA: 23} [, additionalFilterObject]) - -// watch for changes -event.watch(function(error, result){ - if (!error) - console.log(result); -}); - -// Or pass a callback to start watching immediately -var event = myContractInstance.MyEvent([{valueA: 23}] [, additionalFilterObject] , function(error, result){ - if (!error) - console.log(result); -}); - -``` - -You can use events like [filters](#web3ethfilter) and they have the same methods, but you pass different objects to create the event filter. - -##### Parameters - -1. `Object` - Indexed return values you want to filter the logs by, e.g. `{'valueA': 1, 'valueB': [myFirstAddress, mySecondAddress]}`. By default all filter values are set to `null`. It means, that they will match any event of given type sent from this contract. -2. `Object` - Additional filter options, see [filters](#web3ethfilter) parameter 1 for more. By default filterObject has field 'address' set to address of the contract. Also first topic is the signature of event. -3. `Function` - (optional) If you pass a callback as the last parameter it will immediately start watching and you don't need to call `myEvent.watch(function(){})`. See [this note](#using-callbacks) for details. - -##### Callback return - - -`Object` - An event object as follows: - -- `args`: `Object` - The arguments coming from the event. -- `event`: `String` - The event name. -- `logIndex`: `Number` - integer of the log index position in the block. -- `transactionIndex`: `Number` - integer of the transactions index position log was created from. -- `transactionHash`: `String`, 32 Bytes - hash of the transactions this log was created from. -- `address`: `String`, 32 Bytes - address from which this log originated. -- `blockHash`: `String`, 32 Bytes - hash of the block where this log was in. `null` when its pending. -- `blockNumber`: `Number` - the block number where this log was in. `null` when its pending. - - -##### Example - -```js -var MyContract = web3.eth.contract(abi); -var myContractInstance = MyContract.at('0x78e97bcc5b5dd9ed228fed7a4887c0d7287344a9'); - -// watch for an event with {some: 'args'} -var myEvent = myContractInstance.MyEvent({some: 'args'}, {fromBlock: 0, toBlock: 'latest'}); -myEvent.watch(function(error, result){ - ... -}); - -// would get all past logs again. -var myResults = myEvent.get(function(error, logs){ ... }); - -... - -// would stop and uninstall the filter -myEvent.stopWatching(); -``` - -*** - -#### Contract allEvents - -```js -var events = myContractInstance.allEvents([additionalFilterObject]); - -// watch for changes -events.watch(function(error, event){ - if (!error) - console.log(event); -}); - -// Or pass a callback to start watching immediately -var events = myContractInstance.allEvents([additionalFilterObject,] function(error, log){ - if (!error) - console.log(log); -}); - -``` - -Will call the callback for all events which are created by this contract. - -##### Parameters - -1. `Object` - Additional filter options, see [filters](#web3ethfilter) parameter 1 for more. By default filterObject has field 'address' set to address of the contract. Also first topic is the signature of event. -2. `Function` - (optional) If you pass a callback as the last parameter it will immediately start watching and you don't need to call `myEvent.watch(function(){})`. See [this note](#using-callbacks) for details. - -##### Callback return - - -`Object` - See [Contract Events](#contract-events) for more. - -##### Example - -```js -var MyContract = web3.eth.contract(abi); -var myContractInstance = MyContract.at('0x78e97bcc5b5dd9ed228fed7a4887c0d7287344a9'); - -// watch for an event with {some: 'args'} -var events = myContractInstance.allEvents({fromBlock: 0, toBlock: 'latest'}); -events.watch(function(error, result){ - ... -}); - -// would get all past logs again. -events.get(function(error, logs){ ... }); - -... - -// would stop and uninstall the filter -myEvent.stopWatching(); -``` - -**** - -#### web3.eth.getCompilers - - web3.eth.getCompilers([callback]) - -Gets a list of available compilers. - -##### Parameters - -1. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Array` - An array of strings of available compilers. - -##### Example - -```js -var number = web3.eth.getCompilers(); -console.log(number); // ["lll", "solidity", "serpent"] -``` - -*** - -#### web3.eth.compile.solidity - - web3.eth.compile.solidity(sourceString [, callback]) - -Compiles solidity source code. - -##### Parameters - -1. `String` - The solidity source code. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Object` - Contract and compiler info. - - -##### Example - -```js -var source = "" + - "contract test {\n" + - " function multiply(uint a) returns(uint d) {\n" + - " return a * 7;\n" + - " }\n" + - "}\n"; -var compiled = web3.eth.compile.solidity(source); -console.log(compiled); -// { - "test": { - "code": "0x605280600c6000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa114602e57005b60376004356041565b8060005260206000f35b6000600782029050604d565b91905056", - "info": { - "source": "contract test {\n\tfunction multiply(uint a) returns(uint d) {\n\t\treturn a * 7;\n\t}\n}\n", - "language": "Solidity", - "languageVersion": "0", - "compilerVersion": "0.8.2", - "abiDefinition": [ - { - "constant": false, - "inputs": [ - { - "name": "a", - "type": "uint256" - } - ], - "name": "multiply", - "outputs": [ - { - "name": "d", - "type": "uint256" - } - ], - "type": "function" - } - ], - "userDoc": { - "methods": {} - }, - "developerDoc": { - "methods": {} - } - } - } -} -``` - -*** - -#### web3.eth.compile.lll - - web3. eth.compile.lll(sourceString [, callback]) - -Compiles LLL source code. - -##### Parameters - -1. `String` - The LLL source code. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - The compiled LLL code as HEX string. - - -##### Example - -```js -var source = "..."; - -var code = web3.eth.compile.lll(source); -console.log(code); // "0x603880600c6000396000f3006001600060e060020a600035048063c6888fa114601857005b6021600435602b565b8060005260206000f35b600081600702905091905056" -``` - -*** - -#### web3.eth.compile.serpent - - web3.eth.compile.serpent(sourceString [, callback]) - -Compiles serpent source code. - -##### Parameters - -1. `String` - The serpent source code. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - The compiled serpent code as HEX string. - - -```js -var source = "..."; - -var code = web3.eth.compile.serpent(source); -console.log(code); // "0x603880600c6000396000f3006001600060e060020a600035048063c6888fa114601857005b6021600435602b565b8060005260206000f35b600081600702905091905056" -``` - -*** - -#### web3.eth.namereg - - web3.eth.namereg - -Returns GlobalRegistrar object. - -##### Usage - -see [namereg](https://github.com/ethereum/web3.js/blob/master/example/namereg.html) example - -*** - -### web3.db - -#### web3.db.putString - - web3.db.putString(db, key, value) - -This method should be called, when we want to store a string in the local leveldb database. - -##### Parameters - -1. `String` - The database to store to. -2. `String` - The name of the store. -3. `String` - The string value to store. - -##### Returns - -`Boolean` - `true` if successfull, otherwise `false`. - -##### Example - - param is db name, second is the key, and third is the string value. -```js -web3.db.putString('testDB', 'key', 'myString') // true -``` - -*** - -#### web3.db.getString - - web3.db.getString(db, key) - -This method should be called, when we want to get string from the local leveldb database. - -##### Parameters - -1. `String` - The database string name to retrieve from. -2. `String` - The name of the store. - -##### Returns - -`String` - The stored value. - -##### Example - param is db name and second is the key of string value. -```js -var value = web3.db.getString('testDB', 'key'); -console.log(value); // "myString" -``` - -*** - -#### web3.db.putHex - - web3.db.putHex(db, key, value) - -This method should be called, when we want to store binary data in HEX form in the local leveldb database. - -##### Parameters - -1. `String` - The database to store to. -2. `String` - The name of the store. -3. `String` - The HEX string to store. - -##### Returns - -`Boolean` - `true` if successfull, otherwise `false`. - -##### Example -```js -web3.db.putHex('testDB', 'key', '0x4f554b443'); // true - -``` - -*** - -#### web3.db.getHex - - web3.db.getHex(db, key) - -This method should be called, when we want to get a binary data in HEX form from the local leveldb database. - -##### Parameters - -1. `String` - The database to store to. -2. `String` - The name of the store. - -##### Returns - -`String` - The stored HEX value. - - -##### Example - param is db name and second is the key of value. -```js -var value = web3.db.getHex('testDB', 'key'); -console.log(value); // "0x4f554b443" -``` - -*** - -### web3.shh - -[Whisper Overview](https://github.com/ethereum/wiki/wiki/Whisper-Overview) - -##### Example - -```js -var shh = web3.shh; -``` - -*** - -#### web3.shh.post - - web3.shh.post(object [, callback]) - -This method should be called, when we want to post whisper message to the network. - -##### Parameters - -1. `Object` - The post object: - - `from`: `String`, 60 Bytes HEX - (optional) The identity of the sender. - - `to`: `String`, 60 Bytes HEX - (optional) The identity of the receiver. When present whisper will encrypt the message so that only the receiver can decrypt it. - - `topics`: `Array of Strings` - Array of topics `Strings`, for the receiver to identify messages. - - `payload`: `String|Number|Object` - The payload of the message. Will be autoconverted to a HEX string before. - - `priority`: `Number` - The integer of the priority in a rang from ... (?). - - `ttl`: `Number` - integer of the time to live in seconds. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Boolean` - returns `true` if the message was send, otherwise `false`. - - -##### Example - -```js -var identity = web3.shh.newIdentity(); -var topic = 'example'; -var payload = 'hello whisper world!'; - -var message = { - from: identity, - topics: [topic], - payload: payload, - ttl: 100, - workToProve: 100 // or priority TODO -}; - -web3.shh.post(message); -``` - -*** - -#### web3.shh.newIdentity - - web3.shh.newIdentity([callback]) - -Should be called to create new identity. - -##### Parameters - -1. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -`String` - A new identity HEX string. - - -##### Example - -```js -var identity = web3.shh.newIdentity(); -console.log(identity); // "0xc931d93e97ab07fe42d923478ba2465f283f440fd6cabea4dd7a2c807108f651b7135d1d6ca9007d5b68aa497e4619ac10aa3b27726e1863c1fd9b570d99bbaf" -``` - -*** - -#### web3.shh.hasIdentity - - web3.shh.hasIdentity(identity, [callback]) - -Should be called, if we want to check if user has given identity. - -##### Parameters - -1. `String` - The identity to check. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Boolean` - returns `true` if the identity exists, otherwise `false`. - - -##### Example - -```js -var identity = web3.shh.newIdentity(); -var result = web3.shh.hasIdentity(identity); -console.log(result); // true - -var result2 = web3.shh.hasIdentity(identity + "0"); -console.log(result2); // false -``` - -*** - -#### web3.shh.newGroup - -##### Example -```js -// TODO: not implemented yet -``` - -*** - -#### web3.shh.addToGroup - -##### Example -```js -// TODO: not implemented yet -``` - -*** - -#### web3.shh.filter - -```js -var filter = web3.shh.filter(options) - -// watch for changes -filter.watch(function(error, result){ - if (!error) - console.log(result); -}); -``` - -Watch for incoming whisper messages. - -##### Parameters - -1. `Object` - The filter options: - * `topics`: `Array of Strings` - Filters messages by this topic(s). You can use the following combinations: - - `['topic1', 'topic2'] == 'topic1' && 'topic2'` - - `['topic1', ['topic2', 'topic3']] == 'topic1' && ('topic2' || 'topic3')` - - `[null, 'topic1', 'topic2'] == ANYTHING && 'topic1' && 'topic2'` -> `null` works as a wildcard - * `to`: Filter by identity of receiver of the message. If provided and the node has this identity, it will decrypt incoming encrypted messages. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Callback return - -`Object` - The incoming message: - - - `from`: `String`, 60 Bytes - The sender of the message, if a sender was specified. - - `to`: `String`, 60 Bytes - The receiver of the message, if a receiver was specified. - - `expiry`: `Number` - Integer of the time in seconds when this message should expire (?). - - `ttl`: `Number` - Integer of the time the message should float in the system in seconds (?). - - `sent`: `Number` - Integer of the unix timestamp when the message was sent. - - `topics`: `Array of String` - Array of `String` topics the message contained. - - `payload`: `String` - The payload of the message. - - `workProved`: `Number` - Integer of the work this message required before it was send (?). - -*** - -#### web3.eth.sendIBANTransaction - -```js -var txHash = web3.eth.sendIBANTransaction('0x00c5496aee77c1ba1f0854206a26dda82a81d6d8', 'XE81ETHXREGGAVOFYORK', 0x100); -``` - -Sends IBAN transaction from user account to destination IBAN address. - -##### Parameters - -- `string` - address from which we want to send transaction -- `string` - IBAN address to which we want to send transaction -- `value` - value that we want to send in IBAN transaction - -*** - -#### web3.eth.iban - -```js -var i = new web3.eth.iban("XE81ETHXREGGAVOFYORK"); -``` - -*** - -#### web3.eth.iban.fromAddress - -```js -var i = web3.eth.iban.fromAddress('0x00c5496aee77c1ba1f0854206a26dda82a81d6d8'); -console.log(i.toString()); // 'XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS -``` - -*** - -#### web3.eth.iban.fromBban - -```js -var i = web3.eth.iban.fromBban('ETHXREGGAVOFYORK'); -console.log(i.toString()); // "XE81ETHXREGGAVOFYORK" -``` - -*** - -#### web3.eth.iban.createIndirect - -```js -var i = web3.eth.iban.createIndirect({ - institution: "XREG", - identifier: "GAVOFYORK" -}); -console.log(i.toString()); // "XE81ETHXREGGAVOFYORK" -``` - -*** - -#### web3.eth.iban.isValid - -```js -var valid = web3.eth.iban.isValid("XE81ETHXREGGAVOFYORK"); -console.log(valid); // true - -var valid2 = web3.eth.iban.isValid("XE82ETHXREGGAVOFYORK"); -console.log(valid2); // false, cause checksum is incorrect - -var i = new web3.eth.iban("XE81ETHXREGGAVOFYORK"); -var valid3 = i.isValid(); -console.log(valid3); // true - -``` - -*** - -#### web3.eth.iban.isDirect - -```js -var i = new web3.eth.iban("XE81ETHXREGGAVOFYORK"); -var direct = i.isDirect(); -console.log(direct); // false -``` - -*** - -#### web3.eth.iban.isIndirect - -```js -var i = new web3.eth.iban("XE81ETHXREGGAVOFYORK"); -var indirect = i.isIndirect(); -console.log(indirect); // true -``` - -*** - -#### web3.eth.iban.checksum - -```js -var i = new web3.eth.iban("XE81ETHXREGGAVOFYORK"); -var checksum = i.checksum(); -console.log(checksum); // "81" -``` - -*** - -#### web3.eth.iban.institution - -```js -var i = new web3.eth.iban("XE81ETHXREGGAVOFYORK"); -var institution = i.institution(); -console.log(institution); // 'XREG' -``` - -*** - -#### web3.eth.iban.client - -```js -var i = new web3.eth.iban("XE81ETHXREGGAVOFYORK"); -var client = i.client(); -console.log(client); // 'GAVOFYORK' -``` - -*** - -#### web3.eth.iban.address - -```js -var i = new web3.eth.iban('XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS'); -var address = i.address(); -console.log(address); // '00c5496aee77c1ba1f0854206a26dda82a81d6d8' -``` - -*** - -#### web3.eth.iban.toString - -```js -var i = new web3.eth.iban('XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS'); -console.log(i.toString()); // 'XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS' -``` diff --git a/pages/dapp-development/Javascript-Development-Deficiencies.md b/pages/dapp-development/Javascript-Development-Deficiencies.md deleted file mode 100644 index 0bc7d934c..000000000 --- a/pages/dapp-development/Javascript-Development-Deficiencies.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Javascript Development Deficiencies -category: ---- - -The medium-term vision for the Ethereum javascript development tools is simple: to make developing a dapp as easy as developing a web page. However, we are not quite there yet; this page provides a partial list of the problems that dapp developers have to deal with that web developers do not. - -### Transaction Asynchrony and Uncertainty - -When sending an ajax request to a server, that request (i) processes immediately, (ii) is either answered by the server or fails immediately, and (iii) has an effect that we know is final. When sending a transaction, we lose many of these benefits: - -1. When you send a transaction, it takes ~0-30 seconds for the transaction to get included in a block. -2. When a transaction does get included in a block, it could get un-included later due to blockchain reorgs, and could then get double-spent. -3. The transaction gas a gas limit and a gas price, and either of these could lead to failures: in the first case an OOG exception, and in the second case a failure to get the transaction to get included for even longer (possibly forever). It is not possible to tell for sure when this has happened. - -We also lack good ways of dealing with the output of non-constant transactions; for example, a common workflow is creating a transaction that registers a new record in a contract and then getting back the ID of that record or a success or failure confirmation, and there currently is no convenient coding pattern for getting that output back. - -### Failure and retrying - -If a transaction fails for some reason (eg. gas price too low, out of gas), it may be prudent to automatically retry with a higher gas price or gas limit. \ No newline at end of file diff --git a/pages/dapp-development/Mix-Features.md b/pages/dapp-development/Mix-Features.md deleted file mode 100644 index 66d6b62e4..000000000 --- a/pages/dapp-development/Mix-Features.md +++ /dev/null @@ -1,183 +0,0 @@ ---- -name: Mix Features -category: ---- - -# Block Mining - -Hit `File`->`New Project`. - -Type contract: - -```javascript -contract Test { -} -``` - -Hit `File`->`Save`. - -Hit `Deploy`->`Deploy 'Default'` to deploy contract. - -Then for index.html: - -```html - - - - - - number: - - - -``` - -Hit `File`->`Save`. - -In the HTML view, you'll see: - -``` -number: 1 -``` - -Hit `Deploy`->`Mine`. - -The HTML view will update to: - -``` -number: 2 -``` - -# Parameters in Contract Constructor - -Write a Contract containing parameters in the constructor: - -```javascript -contract Test { - uint mem; - Test(uint _a, uint _b) { mem = _a; } - get() returns (uint) - { - return mem; - } -} -``` - -Press `F7` => `Edit State` -The transaction named 'Constructor' should appear in the transaction lists. - -Press `Edit` (on `Constructor`) -This modal dialog should allow users to fill in input parameters (_a and _b). - -Press `+` to add a new transaction. Select the function `get` and save. - -Press `F5` (or run the current editing state if this is not the default state). - -Verify that the return value of `get` is displayed and is this is the good one => in the transaction log (column `returned`). - -# Deploy to Network - -This feature allows users to deploy the current project as a Dapp in the main blockchain. -This will deploy contracts and register front end resources. - -The deployment process includes two steps: - - **The Deployment of contracts**: -This step will deploy contracts in the main blockchain and package front end resources of the current project. After this operation the package (package.dapp) will be available inside the deployment directory. - - - **The Registration of front end resources**: -To render the Dapp, the Ethereum browser (Mist or AlethZero) needs to access this package. This step will register the URL where the resources are stored. - -To Deploy your Dapp, Please follow these instructions: - -Click on `Deploy`, `Deploy to Network`. -This modal dialog displays two parts, We will focus on the first part (Deployment) for now: - - **The Deployment of contracts** - - 4 Buttons: `Help` to access to the WikiPage, `Open Package Folder` to open the deployment directory (this button is only enable is the package is built), `Copy Base64 conversion to ClipBoard` to copy the Base64 value of the built package (this button is only enable is the package is built), `Exit` to close this modal dialog. - - `Root Registrar address` is the address of the root registrar contract (used to link the Dapp with resources. - - `Account used to deploy` allows users to select the Ethereum account to use to deploy. - - `Amount of gas to use..` is the amount of gas that the deployment process will use to deploy contracts. - - `Ethereum Application URL` is the address that users should use in Mist (or AlethZero) to access to the Dapp. in italic, you can check the formatted Dapp URL (which will be used by the Ethereum browser) -(ex: eth/user1/app1). - - `Web Application Resources URL` is the URL where the front resources (html/js/...) will be stored. - - 1 button to start the deployment process (The checkbox `Deploy Contract(s)` is disabled and checked if this is the first time the contract is deployed. If not you can choose to repackage the resources without redeploying the contract by unchecking this option). - -Click on `Deploy contract(s) and Package resources files` (last button) and the deployment is executed. -Then many options/actions will be enabled: - - `Open Package Folder`, `Copy Base64 conversion to ClipBoard`, `Deploy Contract(s)` - - All inputs associated with the second step. - -**Host your web application** - -There are many places where to host front end resources, you just need to find a web server. One other way (and very easy way) could be to use the pastebin.com service: - - Follow the first deployment step to deploy contract(s). - - The `Copy Base64 conversion to ClipBoard` icon will be enable (on top of the modal dialog), click on this icon to copy the Base64 content into the clipboard. - - Go to pastebin.com and paste the content into the `New Paste` input. Then click on `Submit'. - - Go through the Captcha. - - Copy the address targeted by the link `Raw` (on the top of the page). - - Use this address in the `Web Application Resources URL` field. - -**Registration of front end resources** - - `URL Hint contract address` is the address of the contract which is used to store the URL where the resources are. - - `Web Application Resources URL` is the URL from where the Ethereum browser will retrieve resources. - -Click on `Register hosted Web Application` and Mix will register the front end resources on the Ethereum network. - -Users can now use Mist or AlethZero to access to the Dapp, using the Ethereum URL (ex: eth/user1/app1). - -# Account Management - -When a new state is created, it is possible to add new accounts which can be used to send transaction. -It is not possible to delete an account if this one is used by a transaction. - -By default, one account is created, this account will be used to deploy standards contract like `Config` and `NameReg` but can also be used in other transactions. - -For each created account users have to specify a balance. When users start to debugging, the state will -be initialized with all the configured accounts/balances. - -When a transaction is edited, users can select which account to set as the sender. - -# Logs Window - -Clicking on the header status pane will open a pane which displays all logs generated by Mix. -There are 3 log levels: info, warning, error. -Those logs comes from different part of Mix: - - `JavaScript` displays logs coming from the Web preview, it shows error messages generated by the JavaScript engine and messages generated by the command `console.log('...')`. - - `Run` displays logs coming from the execution of transactions. - - `State` displays logs coming from directly from the state (State alteration, New block added). - - `Compilation` displays logs generated by an error when Mix is trying to compile contracts. - -On the header are several actions: - - Clear the content of this window. - - Copy the content to the Clipboard. - - Select which log type to display (4 buttons). - - Use the text input to filter displayed logs. - -# Auto-completion for solidity source - -Auto-completion in Mix is based on the code mirror plugins show-hint.js and anyword-hint.js (Not semantic) -It displays: - - Solidity token (currency, keywords, stdContract, Time, Types). - - Contract Name. - - Functions Name. - - Words that are in the nearby code. - -# Error messages - -When running a bunch of transactions, several error might happen. -One of the common error is that the current account does not have enough ether to execute a transaction. -Users should be aware of that and the status panel should display the amount of gas needed, and the current amount of ether that the user has given for this transaction. -Other important error messages will be displayed here. - -# Highlight secondary error locations - -If the current compilation error has secondary errors locations Mix shows those secondary errors. -In each secondary errors Mix shows where (document) the primary error is. \ No newline at end of file diff --git a/pages/dapp-development/Mix:-The-DApp-IDE.md b/pages/dapp-development/Mix:-The-DApp-IDE.md deleted file mode 100644 index 26afb6857..000000000 --- a/pages/dapp-development/Mix:-The-DApp-IDE.md +++ /dev/null @@ -1,181 +0,0 @@ ---- -name: Mix The DAPP IDE -category: ---- - -# Welcome to Mix IDE! - -This guide provides a very simple and quick introduction to the Mix IDE workflow by walking you through the creation of a simple ÐApp. Once you are done with this tutorial, you will have a general knowledge of how to create and run applications in the IDE. - -Note that the software is in still in proof-of-concept state. Things are changing rapidly and this tutorial might not be up to date. If that is the case [please open an issue](https://github.com/ethereum/cpp-ethereum/issues) or [edit the wiki](https://github.com/ethereum/wiki/wiki/Mix%3A-The-DApp-IDE/_edit). - -## Getting started. - -This tutorial assumes you have [C++ Ethereum installed](https://github.com/ethereum/cpp-ethereum/wiki). - -## Creating a new project - -Let's create a simple ÐApp that will allow user to store and query personal movie ratings. - -In the IDE, choose `File > New Project`. Enter the project name "MovieRatings" and a path for the project file. To the left there is a project items list with two items added by default: Contract and index.html. Contract contains [Solidity](https://github.com/ethereum/wiki/wiki/Solidity-Tutorial) contract code, and index.html is for the front-end. You can add new contract files to the project using file menu. All files will be copied to the project directory. - -Select Contract and enter the text for the rating contract: - -```js - contract Rating { - function setRating(bytes32 _key, uint256 _value) { - ratings[_key] = _value; - } - mapping (bytes32 => uint256) public ratings; - } -``` - -Check [Solidity tutorial](https://github.com/ethereum/wiki/wiki/Solidity-Tutorial) for solidity reference. - -Now select `index.html` and enter the following html code: -```html - - - - - - -

Ratings

-
- Store: - - - -
-
- Query: - -
-
- - -``` -Note that Mix exposes the following objects into the global window context: -* [`web3`](https://github.com/ethereum/wiki/wiki/JavaScript-API#web3) - Ethereum JavaScript API - -* `contracts` - A collection of contract objects. A key to the collection is the contract name. A value is an object with the following properties: - * `contract` - Contract object instance (created as in `web3.eth.contract`) - * `address` - Contract address from the last deployed state (see below) - * `interface` - Contract ABI - -Check the [JavaScript API Reference](https://github.com/ethereum/wiki/wiki/JavaScript-API) for further information. - -Select `File > Save` to save project files. You should see the web preview in the web preview pane. - -## Setting up state - -Now we need to configure a state for debugging. Mix has its own blockchain that is reset on each debugging session. States are used to get the blockchain to a point where it is possible to make transactions and calls to a contract. A state is defined by a sequence of transactions that create DApp and all dependencies on the blockchain and set up DApp initial storage. - -If the debugger pane on the right side is not open, open it by pressing `F7` or selecting `Windows > Show right view` from the menu. At the top of the right pane you can see a state selector and a transaction log. The Default state is already created. Add a transaction by clicking the `Add Tx` button. Make sure the function called `Rating` is selected from the Contract dropdown. This is the contract constructor, running this transaction will effectively deploy the contract on a blockchain. Close the windows by pressing `OK`. - -Add another transaction with `Add Tx` button. This time select a `Transact with Contract` transaction and enter parameter values, e.g. `Titanic` for _key and `4` for _value. This will add a single rating key-value pair to the state. Close the state editor with `OK`. Now once you press `Add Block...` the blockchain will be cleared and a state will be re-deployed. You can see the Pending transactions move to Block 1 in the transaction log. - -## Transaction log - -Now let's test out contract. Type "Titanic" in the web preview query input and you should see the result returned. Enter a name and a rating in store fields and click `Save` to add a new rating. Note that all transactions and calls made to the contract during state deployment and debugging session are recorded into Transaction log to the right. Double click on any entry to load the execution into the debugger. There is also a mine button `Add Block...` to instantly mine a new block on the chain and put all pending transactions there. - -## Debugging - -Mix currently supports assembly level contract code debugging. Source level debugging is a work in progress. - -### Assembly level debugging - -Double-click a `setRating` transaction in the transaction log to debug it. The VM assembly code is loaded into the assembly view and the execution slider is reset to a first position. You can navigate the execution using the slider and/or step buttons. At any execution point the following information is available: - -* VM stack. -* Call stack - Grows when contract is calling into another contract. Double click a stack frame to view the machine state in that frame -* Storage - Storage data associated with the contract -* Memory - Machine memory allocated up to this execution point -* Call data - Transaction or call parameters - -See the [Ethereum Yellow Paper](http://gavwood.com/Paper.pdf) for VM instruction description. - -## Deployment to network - -This feature allows users to deploy the current project as a Dapp in the main blockchain. -This will deploy contracts and register frontend resources. - -The deployment process includes three steps: - - - **Deploy contract**: -This step will deploy contracts in the main blockchain. - - - **Package dapp**: -This step is used to package and upload frontend resources. - - - **Register**: -To render the Dapp, the Ethereum browser (Mist or AlethZero) needs to access this package. This step will register the URL where the resources are stored. - -To Deploy your Dapp, Please follow these instructions: - -Click on `Deploy`, `Deploy to Network`. -This modal dialog displays three parts (see above): - - - **Deploy contract** - - - *Select Scenario* - -"Ethereum node URL" is the location where a node is running, there must be a node running in order to initiate deployment. - -"Pick Scenario to deploy" is a mandatory step. Mix will execute transactions that are in the selected scenario (all transactions except transactions that are not related to contract creation or contract call). Mix will display all the transactions in the panel below with all associated input parameters. - -"Gas Used": depending on the selected scenario, Mix will display the total gas used. - - - *Deploy Scenario* - -"Deployment account" allow selecting the account that Mix will use to execute transactions. - -"Gas Price" shows the default gas price of the network. You can also specify a different value. - -"Deployment cost": depending on the value of the gas price that you want to use and the selected scenario. this will display the amount ether that the deployment need. - -"Deployed Contract": before any deployment this part is empty. This will be filled once the deployment is finished by all contract addresses that have been created. - -"Verifications". This will shows the number of verifications (number of blocks generated on top of the last block which contains the last deployed transactions). Mix keep track of all the transactions. If one is missing (unvalidated) it will be displayed in this panel. - -- **Package dapp** - -- *Generate local package* - -The action "Generate Package" will create the package.dapp in the specified folder - -"Local package Url" the content of this field can be pasted directly in AlethZero in order to use the dapp before uploading it. - -- *Upload and share package* - -This step has to be done outside of Mix. package.dapp file has to be hosted by a server in order to be available by all users. - -"Copy Base64" will copy the base64 value of the package to the clipboard. - -"Host in pastebin.com" will open pastebin.com in a browser (you can then host your package as base64). - -- **Package dapp** - -"Root Registrar address" is the account address of the root registrar contract - -"Http URL" is the url where resources are hosted (pastebin.com or similar) - -"Ethereum URL" is the url that users will use in AlethZero or Mist to access your dapp. - -"Formatted Ethereum URL" is the url that users will use in AlethZero or Mist to access your dapp. - -"Gas Price" shows the default gas price of the network. You can also specify a different value. - -"Registration Cost" will display the amount of ether you need to register your dapp url. diff --git a/pages/dapp-development/RPC-Testing.md b/pages/dapp-development/RPC-Testing.md deleted file mode 100644 index 7032858d8..000000000 --- a/pages/dapp-development/RPC-Testing.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -name: RPC Testing -category: ---- - -``` -{ - blockchain: [ - { - difficulty: 1024, - transactions: [ - ... - ] - }, - ] -} -``` \ No newline at end of file diff --git a/pages/dapp-development/Standardized_Contract_APIs.md b/pages/dapp-development/Standardized_Contract_APIs.md deleted file mode 100644 index 68ccb0a68..000000000 --- a/pages/dapp-development/Standardized_Contract_APIs.md +++ /dev/null @@ -1,295 +0,0 @@ ---- -name: Standardized Contract APIs -category: ---- - -Ethereum allows you to standardize common use cases that allow users and applications to more easily interact with each other. This includes currency units, registering names, making offers on exchanges, and other similar functions. A standard typically consists of function signatures for methods, eg. `send`, `register`, `delete`, providing the set of arguments and their formats in the [Ethereum contract ABI](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI) language. - -The standards described below have sample implementations available [here](https://github.com/ethereum/dapp-bin/tree/master/standardized_contract_apis). - -All function names are in lower camelCase (eg. `sendCoin`), and all event names are in upper CamelCase (eg. `CoinTransfer`). - -Input variables are in underscore-prefixed lower camelCase (eg. `_offerId`). - -Output variables are `_r` for pure getter (ie. constant) functions - `_success` (always boolean) when denoting success or failur, and other values (eg. `_maxValue`) for methods that perform an action but need to return a value as an identifier. -Addresses are referred to using `_address` when generic, and otherwise if a more specific description exists (eg. `_from`, `_to`). - -# Transferable Fungibles - -Also known as tokens, coins and sub-currencies. - -## Token - -### Methods - -#### transfer - -```js -transfer(address _to, uint256 _value) returns (bool success) -``` -Send `_value` amount of coins to address `_to` - -#### transferFrom - -```js -transferFrom(address _from, address _to, uint256 _value) returns (bool success) -``` -Send `_value` amount of coins from address `_from` to address `_to` - -#### balanceOf - -```js -balanceOf(address _address) constant returns (uint256 balance) -``` -Get the account balance of another account with address `_address` - ---- -The `transferFrom` method is used for a "direct debit" workflow, allowing contracts to send coins on your behalf, for example to "deposit" to a contract address and/or to charge fees in sub-currencies. The command should fail unless the `_from` account has deliberately authorized the sender of the message via some mechanism. We propose these standardized APIs for approval: - -#### approve - -```js -approve(address _address) returns (bool _success) -``` -Allow `_address ` to direct debit from your account with full custody. Only implement if absolutely required and use carefully. See `approveOnce` below for a more limited method. - -#### unapproved - -```js -unapprove(address _address) returns (bool _success) -``` -Unapprove address `_address ` to direct debit from your account if it was previously approved. Must reset both one-time and full custody approvals. - -#### isApprovedFor - -```js -isApprovedFor(address _target, address _proxy) constant returns (bool _r) -``` -Returns 1 if `_proxy` is allowed to direct debit from `_target` - -#### approveOnce - -```js -approveOnce(address _address, uint256 _maxValue) returns (bool _success) -``` -Makes a one-time approval for `_address ` to send a maximum amount of currency equal to `_maxValue` - -#### isApprovedOnceFor - -```js -isApprovedOnceFor(address _target, address _proxy) returns (uint256 _maxValue) -``` -Returns `_maxValue` if `_proxy` is allowed to direct debit the returned `_maxValue` from address `_target` only once. The approval must be reset on any transfer by `_proxy` of `_maxValue` or less. - -### Events -#### Transfer - -```js -Transfer(address indexed from, address indexed to, uint256 value) -``` -Triggered when tokens are transferred. - -#### AddressApproval - -```js -AddressApproval(address indexed address, address indexed proxy, bool result) -``` -Triggered when an `address` approves `proxy` to direct debit from their account. - -#### AddressApprovalOnce - -```js -AddressApprovalOnce(address indexed address, address indexed proxy, uint256 value) -``` -Triggered when an `address` approves `proxy` to direct debit from their account only once for a maximum of `value` - -## TF Registries - -Token registries contain information about tokens. There is at least one global registry (though other may create more like the global Registry) to which you can add your token. Adding your token to it would increase the experience of the user that the GUI Client can use or not. - -#### symbol - -```js -setSymbol(string _s) -symbol(address _token) constant returns (string) -``` - -Sets or returns a short sequence of letters that are used to represent the unit of the coin. When setting, it assumes the `msg.sender` is the token. Solidity string is on UTF-8 format so this should support any character supported by UTF-8. Symbols are chosen by the contract and it's up to the client to decide how to handle different currencies with similar or identical symbols. - -Examples or symbols: `USDX`, `BOB$`, `Ƀ`, `% of shares`. - -#### name - -```js -setName(string _s) -name(address _token) constant returns (string) -``` - -Sets or returns the name of a token. Solidity string is on UTF-8 format so this should support any character supported by UTF-8. Names are chosen by the contract and it's up to the client to decide how to handle different currencies with similar or identical names. - -Examples of names: `e-Dollar`, `BobToken`, `Bitcoin-Eth`. - -#### baseUnit - -```js -setBaseUnit(uint _s) -baseUnit(address _token) constant returns (uint256) -``` - -Sets or returns the base unit of a token. Although most tokens are displayed to the final user as containing decimal points, token values are unsigned integers counting in the smallest possible unit. The client should always display the total units divided by `baseUnit`. Base units can be any integer but we suggest only using powers of 10. At the moment there is no support for multiple sub-units. - -Example: Bob has a balance of 100000 BobTokens whose base unit is 100. His balance will be displayed on the client as **BOB$100.00** - -## Registries - -Registries (eg. domain name systems) have the following API: - -### Methods -#### reserve - -```js -reserve(string _name) returns (bool _success) -``` -Reserves a name and sets its owner to you if it is not yet reserved. - -#### owner - -```js -owner(string _name) constant returns (address _r) -``` -Get the owner of a particular name. - -#### transfer - -```js -transfer(string _name, address _newOwner) -``` -Transfer ownership of a name. - -#### setAddr - -```js -setAddr(string _name, address _address) -``` - -Set the primary address associated with a name (similar to an A record in traditional DNS.) - -#### addr - -```js -addr(string _name) constant returns (address _r) -``` -Get the primary address associated with a name. - -#### setContent - -```js -setContent(string _name, bytes32 _content) -``` - -If you are the owner of a name, sets its associated content. - -#### content - -```js -content(string _name) constant returns (bytes32 _r) -``` - -Get the content associated with a name. - -#### setSubRegistrar - -```js -setSubRegistrar(string _name, address _subRegistrar) -``` - -Records the name as referring to a sub-registrar at the given address. - -#### subRegistrar - -```js -subRegistrar(string _name) constant returns (address _r) -``` -Gets the sub-registrar associated with the given name. - -#### disown - -```js -disown(string _name) -``` - -Relinquishes control over a name that you currently control. - -### Events - -#### Changed - -```js -event Changed(string name, bytes32 indexed __hash_name) -```` - -Triggered when changed to a domain happen. - - -## Data feeds - -The data feed standard is a _templated standard_, ie. in the below descriptions one should be free to replace `` with any desired data type, eg. `uint256`, `bytes32`, `address`, `real192x64`. - -### Methods -#### get - -```js -get(bytes32 _key) returns ( _r) -``` - -Get the value associated with a key. - -#### set - -```js -set(bytes32 _key, _value) -``` - -Set the value associated with a key if you are the owner. - -#### setFee - -```js -setFee(uint256 _fee) -``` - -Sets the fee. - -#### setFeeCurrency - -```js -setFeeCurrency(address _feeCurrency) -``` - -Sets the currency that the fee is paid in - -The latter two methods are optional. Also, note that the fee may be charged either in ether or subcurrency. If the contract charges in ether then the `setFeeCurrency` method is unnecessary. - - -## Forwarding contracts (eg. multisig) - -Forwarding contracts will likely work very differently depending on what the authorization policy of each one is. However, there are some standard workflows that should be used as much as possible: - -### Methods -#### execute - -```js -execute(address _to, uint _value, bytes _data) returns (bytes32 _id) -``` - -Create a message with the desired recipient, value and data. Returns a "pending ID" for the transaction. - -#### confirm - -```js -confirm(bytes32 _id) returns (bool _success) -``` - -Confirm a pending message with a particular ID using your account; returns success or failure. If enough confirmations are made, sends the message along. - -Access policies can be of any form, eg. multisig, an arbitrary CNF boolean formula, a scheme that depends on the _value_ or _contents_ of a transaction, etc. diff --git "a/pages/dapp-development/Useful-\303\220app-Patterns.md" "b/pages/dapp-development/Useful-\303\220app-Patterns.md" deleted file mode 100644 index e40841400..000000000 --- "a/pages/dapp-development/Useful-\303\220app-Patterns.md" +++ /dev/null @@ -1,17 +0,0 @@ ---- -name: Useful DAPP Patterns -category: ---- - -The following page is a collection of useful patterns, Ðapps can use, such as talking to the blockchain reliably. - -The example patterns can possibly change, so don't rely fully on them as of yet. - -## Examples - -- Contract deployment by code: -(Outdated, use `web3.contract(abiArray).new({}, function(e, res){...})`) -https://gist.github.com/frozeman/655a9325a93ac198416e - -- Test a contract transaction with a `call` before actually sending: -https://gist.github.com/ethers/2d8dfaaf7f7a2a9e4eaa diff --git a/pages/dapp-development/serpent/Serpent-1.0-(old).md b/pages/dapp-development/serpent/Serpent-1.0-(old).md deleted file mode 100644 index a221b99e8..000000000 --- a/pages/dapp-development/serpent/Serpent-1.0-(old).md +++ /dev/null @@ -1,281 +0,0 @@ ---- -name: Serpent 1.0 -category: ---- - -Serpent is one of the high-level programming languages used to write Ethereum contracts. The language, as suggested by its name, is designed to be very similar to Python; later versions may even eventually come to target the entire [RPython spec](http://pypy.readthedocs.org/en/latest/coding-guide.html#rpython-definition). The language is designed to be maximally clean and simple, combining many of the efficiency benefits of a low-level language with ease-of-use in programming style. The latest version of the Serpent compiler, available [on github](http://github.com/ethereum/serpent), is written in C++, allowing it to be easily included in any client, and works by compiling the code first to LLL then to EVM; thus, if you like LLL, a possible intermediate option is to write Serpent, compile it to LLL, and then hand-tweak the LLL at the end. - -This tutorial assumes basic knowledge of how Ethereum works, including the concept of blocks, transactions, contracts and messages and the fact that contracts take a byte array as input and provide a byte array as output. If you do not, then go [here](https://github.com/ethereum/wiki/wiki/Ethereum-Development-Tutorial) for a basic tutorial. - -### Differences Between Serpent and Python - -The important differences between Serpent and Python are: - -* Python numbers have potentially unlimited size, Serpent numbers wrap around 2256. For example, in Serpent the expression `3^(2^254)` suprisingly evaluates to 1, even though in reality the actual integer is too large to be recorded in its entirety within the universe. -* Serpent has no decimals. -* There is no way to take a Serpent array and access its length; this sometimes leads to inconveniences like needing to type `return([a,b,c], 3)` instead of Python's `return [a,b,c]`. Future versions may change this specifically in the case of array literals. -* Serpent has no concept of strings (at this point); if you make an expression like `x = "george"`, the compiler converts that into a number using ASCII encoding, so you get 103 * 2565 + 101 * 2564 + 111 * 2563 + 114 * 2562 + 103 * 256 + 101 = 113685359126373. These numbers can be converted back into strings, so you can still represent strings, but they are limited to 32 characters in length. Future versions may change this to turn strings into char arrays, which would be accessible via `getch(str, i) -> byte` and `setch(str, i, byte)` -* Serpent has no list comprehensions (expressions like `[x**2 for x in my_list]`), dictionaries or most other advanced features -* Serpent has no function definitions or classes. Future versions may add function definitions - -### Installation - -In order to install the Serpent python library and executable do: - - pip install ethereum-serpent - -[Install the cpp-ethereum cli tools](https://github.com/ethereum/cpp-ethereum/wiki) to run the sc commands in the tutorial - -If you want a library you can directly call from C++, instead do: - - git clone http://github.com/ethereum/serpent - cd serpent - make - sudo make install - -### Tutorial - -Now, let's write our first contract. Paste the following into a file called "mul2.se": - - return(msg.data[0] * 2) - -This contract is a simple one line of code. The first thing to point out is that Serpent sees message data, memory and output in 32-byte chunks; `msg.data[0]` returns bytes 0-31 of the input, `msg.data[5]` returns bytes 160-191, etc, and `return(202020)` returns the value 202020 encoded in binary form padded to 32 bytes. From now on, these mechanics will be assumed; "the zeroth data field" will be synonymous with "bytes 0-31 of the input" and "returns three values a,b,c" will be synonymous with "returns 96 bytes consisting of the values a, b and c, each padded to 32 bytes". - -Note that the Serpent compiler (included in the [cpp-ethereum toolkit](https://github.com/ethereum/cpp-ethereum)) includes some tools to make this conversion convenient; `sc encode_datalist "1 2 3"` gives: - - 000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003 - -And `sc decode_datalist 000..003` gives: - - 1 2 3 - -Additionally, the Pyethereum testing environment that we will be using simply assumes that data input and output are in this format. - -Now, let's try actually compiling the code. Type: - - > sc compile mul2.se - 600e51600c6000396000f20060026000350260405460206040f2 - -And there we go, that's the hexadecimal form of the code that you can put into transactions. Or, if you want to see opcodes: - - > sc pretty_compile mul2.se - PUSH1 14 DUP PUSH1 12 PUSH1 0 CODECOPY PUSH1 0 RETURN STOP PUSH1 2 PUSH1 0 CALLDATALOAD MUL PUSH1 64 MSTORE PUSH1 32 PUSH1 64 RETURN - -Alternatively, you can compile to LLL (the compiler compiles through LLL anyway, so this is just stopping at an intermediate step instead of at the end): - - > sc compile_to_lll mul2.se - (return 0 - (lll - (seq - (set '_temp4_1 (mul (calldataload 0) 2)) - (return (ref '_temp4_1) 32) - ) - 0 - ) - ) - -This shows you the machinery that is going on inside. As with most contracts, the outermost layer of code exists only to copy the data of the inner code during initialization and return it, since the code returned during initialization is the code that will be executed every time the contract is called; in the EVM you can see this with the `CODECOPY` opcode, and in LLL this corresponds to the `lll` meta-operation. In the innermost layer, we take bytes 0-31 from the input, multiply that value by two, and save it in a temp variable called `_temp4_1`. We then supply the memory address of that variable, and the length 32, to the `RETURN` opcode. Note that, when dealing with message and memory data, LLL deals not with 32-byte chunks but with bytes directly, so the conversion needs to introduce these more low-level mechanics. `msg.data[1]`, for examples, is translated into `(calldataload 32)`, and `msg.data[3]` into `(calldataload 96)`. - -Now, what if you want to actually run the contract? That is where [pyethereum](https://github.com/ethereum/pyethereum) comes in. Open up a Python console in the same directory, and run: - - > from pyethereum import tester as t - > s = t.state() - > c = s.contract('mul2.se') - > s.send(t.k0, c, 0, [42]) - [84] - > s.send(t.k0, c, 0, [303030]) - [606060] - -The second line initializes a new state (ie. a genesis block). The third line creates a new contract, and sets `c` to its address. The fourth line sends a transaction from private key zero (the `tester` submodule includes ten pre-made key/address pairs at `k0`, `a0`, `k1`, `a1`, etc) to the address of the contract with 0 wei and with data input 42, and we see 84 predictably come out. - -And there you go. - -### Lesson 2: Name Registry - -Having a multiply-by-two function on the blockchain is kind of boring. So let's do something marginally more interesting: a name registry. Our name registry will be fairly simple; it will take in two data items (ie. 64 bytes), treating the first item as the key and the second as the value. If the key is not yet registered, then it registers the key/value pair and returns 1; otherwise, it returns 0. Let's try it out: - - key = msg.data[0] - value = msg.data[1] - # Key not yet claimed - if not contract.storage[key]: - contract.storage[key] = value - return(1) - else: - return([0], 1) # Key already claimed - -Here, we see a few parts in action. First, we have the `msg.data` pseudo-array, which can be used to access message input data items. Then, we have `key` and `value`, which are variables that we set. The third line is a comment; it does not get compiled and only serves to remind you what the code does. Then, we have a standard if/else clause, which checks if `contract.storage[key]` is zero (ie. unclaimed), and if it is then it sets `contract.storage[key] = value` and returns 1. Otherwise, it returns zero (which we expressed as a literal array just to exhibit this other style of returning; it's more cumbersome but lets you do return multiple values). `contract.storage` is also a pseudo-array, acting like an array but without any particular memory location. - -Now, paste the code into "namecoin.se", if you wish try compiling it to LLL, opcodes or EVM, and let's try it out in the pyethereum tester environment: - - > from pyethereum import tester as t - > s = t.state() - > c = s.contract('namecoin.se') - > s.send(t.k0, c, 0, ["george", 45]) - [1] - > s.send(t.k1, c, 0, ["george", 20]) - [0] - > s.send(t.k2, c, 0, ["harry", 65]) - [1] - -### Including files - -Once your projects become larger, you will not want to put everything into the same file; things become particularly inconvenient when one piece of code needs to create a contract. Fortunately, the process for splitting code into multiple files is quite simple. Make the following two files: - -mul2.se: - - return(msg.data[0] * 2) - -returnten.se: - - MUL2 = create('mul2.se') - return(call(MUL2, 5)) - -And open Python: - - > from pyethereum import tester as t - > s = t.state() - > c = s.contract('returnten.se') - > s.send(t.k0, c, 0, []) - [10] - -Another, similar, operation is `(inset 'filename')`, which simply puts code into a particular place without adding a separate contract. - -### Miscellaneous - -Additional Serpent coding examples can be found here: https://github.com/ethereum/serpent/tree/master/examples - -The three other useful features in the tester environment are: - -* Block access - you can dig around `s.block` to see block data (eg. `s.block.number`, `s.block.get_balance(addr)`, `s.block.get_storage_data(addr, index)`) -* Snapshots - you can do `x = s.snapshot()` and `s.revert(x)` -* Advancing blocks - you can do `s.mine(100)` and 100 blocks magically pass by with a 60-second interval between blocks. `s.mine(100, addr)` mines into a particular address. -* Full block data dump - type `s.to_dict()` - -## Complete language spec - -### Expressions - -An expression is defined as anything that fits on one line. An expression is recursively defined as follows: - -* A number is an expression (eg. `125`) -* A number in hex is an expression (eg. `0xdeadbeef`), and evaluates to the corresponding decimal value (in this case, `3735928559`). Uppercase does not work. -* A string is an expression (eg. `"george"`), and evaluates to the corresponding hex (in this case, `0x67656f726765`, ie. `113685359126373`). Note that due to wraparound all but the last 32 characters of a 33+ char string are truncated off. -* A variable is an expression (eg. `a`) -* An arithmetic expression built out of arithmetic operations and expressions is an expression (eg. `2 + 3`, `(4 + 5) ^ 7`, `"george" ^ 2 / (0xdeadbeef - 4848) ^ "harry"`). Supported operations are: - * `+` (`ADD`) - * `-` (`SUB`); note that right now `-5` is converted into `(sub 0 5)` - * `*` (`MUL`) - * `/` (`SDIV`, ie. signed division, where negative values of `x` are stored as `x + 2^256`, eg. -3 is `0xfffffff....ffd`) - * `%` (`SMOD`) - * `@/` (`DIV`, ie. unsigned division) - * `@%` (`MOD`) - * `^` (`EXP`) - * `**` (`EXP`) - * `<` (`SLT`, ie. signed comparison) - * `@<` (`LT`, ie unsigned comparison) - * `>` (`SGT`) - * `@>` (`GT`) - * `==` (`EQ`) - * `|` (`OR`, ie. bitwise or) - * `xor` (`XOR`) - * `or`: `a or b` returns `a` if `a` is nonzero, otherwise `b`; `a` is never evaluated twice, and if `a != 0` then `b` is never evaluated at all - * `and`: `a and b` returns `b` if `a` is nonzero, otherwise `0`; if `a = 0` then `b` is never evaluated at all -* An array literal consisting of expressions is an expression (eg. `[1,2,3]`, `[3 + 5, [8, 12, [24]], 9 ^ 6 / "cow"]`) -* An array access where the accessed array and the index are expressions is an expressoin (eg. `x[4]`, `y[z + 5][c + 2]`) -* A function call where the arguments are expressions is an expression (eg. `return(call(addrs[7], x ^ 3 + 5))`). Supported functions are: - * `array(n)`: returns an empty array of size `n` (in 32-byte chunks) - * `bytes(n)`: returns a byte array of size `n` (in bytes) - * `getch(arr, i)`: returns the `i`th character of the given bytearray - * `setch(arr, i, c)`: sets the `i`th character of the given bytearray to `c` - * `msg(gas, to, value, dataval)`: sends a message with the specified recipient, quantity of ether (in wei) and amount of gas, with `dataval` as a 32-byte input, and returns the first 32 bytes of the output as a value on the stack - * `msg(gas, to, value, datarray, insize)`: sends a message with the specified recipient, quantity of ether (in wei) and amount of gas, taking `insize` values from the specified array as input, and returns the first 32 bytes of the output as a value on the stack - * `msg(gas, to, value, datarray, insize, outsize)`: sends a message with the specified recipient, quantity of ether (in wei) and amount of gas, taking `insize` values from the specified array as input, and returns an `outsize`-sized data array as the output - * `call(addr, dat)` - equivalent to `msg(tx.gas - 25, addr, 0, dat)` where `tx.gas` is the remaining gas - * `call(addr, datarray, insize)` - equivalent to `msg(tx.gas - 25, addr, 0, datarray, insize)` - * `call(addr, datarray, insize, outsize)` - equivalent to `msg(tx.gas - 25, addr, 0, datarray, insize, outsize)` - * `send(gas, addr, value)` - sends the desired amount of value to the desired address with the desired gas limit - * `send(addr, value)` - equivalent to `send(tx.gas - 25, addr, value)` - * `create('filename')` - creates a contract out of code from the desired filename and returns the address - * `sha3(value)` - returns the SHA3 of the given value (as 32 bytes, zero-padded if necessary) - * `sha3(str, bytes)` - returns the SHA3 of the given byte array with the given number of bytes - * `return(value)` - exits message execution, returning the given value (as 32 bytes, zero-padded if necessary) (ie. if you run `x = send(C)` and the contract at address `C` reaches a point where there is the code `return(7)`, then in the outer execution `x` will equal 7) - * `return(array, size)` - exits message execution, returning the given array with the given number of 32-byte chunks - * `stop` - exits message execution, reporting nothing - * `suicide(addr)` - destroys the contract, sending all ether to the given address - * `debug(num)` - does nothing (in the pyethereum implementation with the `DUP POP POP` sequence of opcodes). However, implementations may wish to show the number in some kind of debug output. - -### Code blocks - -A code block constitutes a complete program in Ethereum. A code block is defined as follows: - -(1) An expression is a code block. - -(2) A statement of the form: - - a - b - -is a code block, where `a` and `b` are code blocks. Note that this can be expanded to basically mean that any number of code blocks with the same indenting level put together is a code block. - -(3) A statement of the form: - - if a: - b - -is a code block, where `a` is an expression and `b` is a code block. - -(4) A statement of the form: - - if a: - b - else: - c - -is a code block, where `a` is an expression and `b` and `c` are code blocks. - -(5) A statement of the form: - - if a: - b - elif c: - d - else: - e - -is a code block, and an unlimited number of other elif clauses can be added in the middle. - -(6) A statement of the form: - - while a: - b - -is a code block, where `a` is an expression and `b` is a code block. - -(7) A statement of the form: - - init: - a - code: - b - -is a code block. This block should only be used at the top level; the `init` sub-block is called during initialization and the `code` sub-block is called during future executions. - -(8) A statement of the form: - - shared: - a - init: - b - code: - c - -is a code block, and is synonymous with: - - init: - a - b - code: - a - c - -(9) `inset('filename')` is a code block, and is substituted at compile time with the text of the file. \ No newline at end of file diff --git a/pages/dapp-development/serpent/Serpent.md b/pages/dapp-development/serpent/Serpent.md deleted file mode 100644 index 4ee0944a0..000000000 --- a/pages/dapp-development/serpent/Serpent.md +++ /dev/null @@ -1,494 +0,0 @@ ---- -name: Serpent -category: ---- - -See https://github.com/ethereum/wiki/wiki/Serpent-1.0-(old) for Serpent 1.0. - -Serpent is one of the high-level programming languages used to write Ethereum contracts. The language, as suggested by its name, is designed to be very similar to Python; it is intended to be maximally clean and simple, combining many of the efficiency benefits of a low-level language with ease-of-use in programming style, and at the same time adding special domain-specific features for contract programming. The latest version of the Serpent compiler, available [on github](http://github.com/ethereum/serpent), is written in C++, allowing it to be easily included in any client. - -This tutorial assumes basic knowledge of how Ethereum works, including the concept of blocks, transactions, contracts and messages and the fact that contracts take a byte array as input and provide a byte array as output. If you do not, then go [here](https://github.com/ethereum/wiki/wiki/Ethereum-Development-Tutorial) for a basic tutorial. - -### Differences Between Serpent and Python - -The important differences between Serpent and Python are: - -* Python numbers have potentially unlimited size, Serpent numbers wrap around 2256. For example, in Serpent the expression `3^(2^254)` suprisingly evaluates to 1, even though in reality the actual integer is too large to be recorded in its entirety within the universe. -* Serpent has no decimals. -* Serpent has no list comprehensions (expressions like `[x**2 for x in my_list]`), dictionaries or most other advanced features -* Serpent has no concept of first-class functions. Contracts do have functions, and can call their own functions, but variables (except storage) do not persist across calls. -* Serpent has a concept of persistent storage variables (see below) -* Serpent has an `extern` statement used to call functions from other contracts (see below) - -### Installation - -In order to install the Serpent python library and executable do: - - $ sudo pip install ethereum-serpent - -If you want a library you can directly call from C++, instead do: - - $ git clone http://github.com/ethereum/serpent - $ cd serpent - $ make - $ sudo make install - -### Tutorial - -Now, let's write our first contract. Paste the following into a file called `mul2.se`: - - def double(x): - return(x * 2) - -This contract is a simple two lines of code, and defines a function. Functions can be called either by transactions or by other contracts, and are the way that Serpent contracts provide an "interface" to other contracts and to transactions; for example, a contract defining a currency might have functions `send(to, value)` and `check_balance(address)`. - -Additionally, the Pyethereum testing environment that we will be using simply assumes that data input and output are in this format. - -Now, let's try actually compiling the code. Type: - -``` -$ serpent compile mul2.se -604380600b600039604e567c01000000000000000000000000000000000000000000000000000000006000350463eee9720681141560415760043560405260026040510260605260206060f35b505b6000f3 -``` - -And there we go, that's the hexadecimal form of the code that you can put into transactions. Or, if you want to see opcodes: - - $ serpent pretty_compile mul2.se - [PUSH1, 67, DUP1, PUSH1, 11, PUSH1, 0, CODECOPY, PUSH1, 78, JUMP, PUSH29, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, PUSH1, 0, CALLDATALOAD, DIV, PUSH4, 238, 233, 114, 6, DUP2, EQ, ISZERO, PUSH1, 65, JUMPI, PUSH1, 4, CALLDATALOAD, PUSH1, 64, MSTORE, PUSH1, 2, PUSH1, 64, MLOAD, MUL, PUSH1, 96, MSTORE, PUSH1, 32, PUSH1, 96, RETURN, JUMPDEST, POP, JUMPDEST, PUSH1, 0, RETURN] - -Alternatively, you can compile to LLL to get an intermediate representation: - -``` -$ serpent compile_to_lll mul2.se -(return 0 - (lll - (with '__funid - (div (calldataload 0) - 26959946667150639794667015087019630673637144422540572481103610249216 - ) - (unless (iszero (eq (get '__funid) 4008276486)) - (seq - (set 'x (calldataload 4)) - (seq - (set '_temp_521 (mul (get 'x) 2)) - (return (ref '_temp_521) 32) - ) - ) - ) - ) - 0 - ) -) -``` - -This shows you the machinery that is going on inside. As with most contracts, the outermost layer of code exists only to copy the data of the inner code during initialization and return it, since the code returned during initialization is the code that will be executed every time the contract is called; in the EVM you can see this with the `CODECOPY` opcode, and in LLL this corresponds to the `lll` meta-operation. Inside of the LLL, we have a wrapper whose purpose it is to grab the first four bytes of the contract data, (that's the `(div (calldataload 0) 26959946667150639794667015087019630673637144422540572481103610249216)`; we grab four bytes by grabbing the first 32 bytes and dividing it by 2^224) to get the function ID that is being called, and then inside of that we have a series of functions (in this case only one function) that checks the function ID provided against all function IDs supported by the contract. If the function ID is 4008276486, then it sets a variable `'x` to the message data bytes 4-35 (that's `(calldataload 4)`), sets a temporary variable to equal to `2 * x`, and returns the 32 byte memory slice that contains that variable. - -The function ID is calculated by computing a hash based on the function name and arguments and taking the first four bytes. In this case we have a function named `double` with a single integer as an argument; on the command line we can do: - - $ serpent get_prefix double i - 4008276486 - -Note that you can have multiple functions with the same name, if they take different combinations of inputs. For instance, a hypothetical function double that takes three integers as input (and, say, returns an array consisting of 2x each one) would have a different prefix: - - $ serpent get_prefix double iii - 1142360101 - -The letter `i` is meant for integers, and for fixed-length (up to 32 byte) strings (which are treated the same as integers in Serpent and EVM). Use the letter `s` for variable-length string arguments, and `a` for arrays; more on these later. - -Now, what if you want to actually run the contract? That is where [pyethereum](https://github.com/ethereum/pyethereum) comes in. Open up a Python console in the same directory, and run: - - >>> from ethereum import tester as t - >>> s = t.state() - >>> c = s.abi_contract('mul2.se') - >>> c.double(42) - [84] - -The second line initializes a new state (ie. a genesis block). The third line creates a new contract, and creates an object in Python which represents it. You can use `c.address` to access this contract's address. The fourth line calls the contract with argument 42, and we see 84 predictably come out. - -Note that if you want to send a transaction to such a contract in the testnet or livenet, you will need to package up the transaction data for "call function double with an integer as an input with data 42". The command line instruction for this is *deprecated*: - - $ serpent encode_abi double i 42 - eee97206000000000000000000000000000000000000000000000000000000000000002a - -### Example: Name Registry - -Having a multiply-by-two function on the blockchain is kind of boring. So let's do something marginally more interesting: a name registry. The main function will be a `register(key, value)` operation which checks if a given key was already taken, and if is unoccupied then register it with the desired value and return 1; if the key is already occupied return 0. We will also add a second function to check the value associated with a particular key. Let's try it out: - - def register(key, value): - # Key not yet claimed - if not self.storage[key]: - self.storage[key] = value - return(1) - else: - return(0) # Key already claimed - - def ask(key): - return(self.storage[key]) - -Here, we see a few parts in action. First, we have the `key` and `value` variables that the function takes as arguments. The second line is a comment; it does not get compiled and only serves to remind you what the code does. Then, we have a standard if/else clause, which checks if `self.storage[key]` is zero (ie. unclaimed), and if it is then it sets `self.storage[key] = value` and returns 1. Otherwise, it returns zero. `self.storage` is also a pseudo-array, acting like an array but without any particular memory location. - -Now, paste the code into `namecoin.se`, if you wish try compiling it to LLL, opcodes or EVM, and let's try it out in the pyethereum tester environment: - - >>> from ethereum import tester as t - >>> s = t.state() - >>> c = s.abi_contract('namecoin.se') - >>> c.register(0x67656f726765, 45) - [1] - >>> c.register(0x67656f726765, 20) - [0] - >>> c.register(0x6861727279, 65) - [1] - >>> c.ask(0x6861727279) - [65] - -If we wanted to encode the transaction data for that first call, we would do: - - - $ serpent encode_abi register ii 0x67656f726765 45 - d66d6c10000000000000000000000000000000000000000000000000000067656f726765000000000000000000000000000000000000000000000000000000000000002d - -### Including files, and calling other contracts - -Once your projects become larger, you will not want to put everything into the same file; things become particularly inconvenient when one piece of code needs to create a contract. Fortunately, the process for splitting code into multiple files is quite simple. Make the following two files: - -mul2.se: - - def double(x): - return(x * 2) - -returnten.se: - - extern mul2.se: [double:i:i] - - MUL2 = create('mul2.se') - def returnten(): - return(MUL2.double(5)) - -And open Python: - - >>> from ethereum import tester as t - >>> s = t.state() - >>> c = s.abi_contract('returnten.se') - >>> c.returnten() - [10] - -Note that here we introduced several new features. Particularly: - -* The `create` command to create a contract using code from another file -* The `extern` keyword to declare a class of contract for which we know the names of the functions -* The interface for calling other contracts - -`create` is self-explanatory; it creates a contract and returns the address to the contract. - -The way `extern` works is that you declare a class of contract, in this case `mul2`, and then list in an array the names of the functions, in this case just `double`. To generate `extern mul2.se: [double:i:i]` use - - $ serpent mk_signature mul2.se - -From there, given any variable containing an address, you can do `x.double(arg1)` to call the address stored by that variable. The arguments are the values provided to the function. If you provide too few arguments, the rest are filled to zero, and if you provide too many the extra ones are ignored. Function calling also has some other optional arguments: - -* `gas=12414` - call the function with 12414 gas instead of the default (all gas) -* `value=10^19` - send 10^19 wei (10 ether) along with the message -* `data=x`, `datasz=5` - call the function with 5 values from the array `x`; note that this replaces other function arguments. `data` without `datasz` is illegal -* `outsz=7` - by default, Serpent processes the output of a function by taking the first 32 bytes and returning it as a value. However, if `outsz` is used as here, the function will instead return an array containing 7 values; if you type `y = x.fun(arg1, outsz=7)` then you will be able to access the output via `y[0]`, `y[1]`, etc. - -Another similar operation to `create` is `inset('filename')`, which simply puts code into a particular place without adding a separate contract. - -returnten.se - - inset('mul2.se') - - def returnten(): - return(self.double(5)) - -### Storage data structures - -In more complicated contracts, you will often want to store data structures in storage to represent certain objects. For example, you might have a decentralized exchange contract that stores the balances of users in multiple currencies, as well as open bid and ask orders where each order has a price and a quantity. For this, Serpent has a built-in mechanism for defining your own structures. For example, in such a decentralized exchange contract you might see: - - data user_balances[][] - data orders[](buys[](user, price, quantity), sells[](user, price, quantity)) - -Then, you might do something like: - - def fill_buy_order(currency, order_id): - # Available amount buyer is willing to buy - q = self.orders[currency].buys[order_id].quantity - # My balance in the currency - bal = self.user_balances[msg.sender][currency] - # The buyer - buyer = self.orders[currency].buys[order_id].user - if q > 0: - # The amount we can actually trade - amount = min(q, bal) - # Trade the currency against the base currency - self.user_balances[msg.sender][currency] -= amount - self.user_balances[buyer][currency] += amount - self.user_balances[msg.sender][0] += amount * self.orders[currency].buys[order_id].price - self.user_balances[buyer][0] -= amount * self.orders[currency].buys[order_id].price - # Reduce the remaining quantity on the order - self.orders[currency].buys[order_id].quantity -= amount - -Notice how we define the data structures at the top, and then use them throughout the contract. These data structure gets and sets are converted into storage accesses in the background, so the data structures are persistent. - -The language for doing data structures is simple. First, we can do simple variables: - - data blah - - x = self.blah - self.blah = x + 1 - -Then, we can do arrays, both finite and infinite: - - data blah[1243] - data blaz[] - - x = self.blah[505] - y = self.blaz[3**160] - self.blah[125] = x + y - -Note that finite arrays are always preferred, because it will cost less gas to calculate the storage index associated with a finite array index lookup. And we can do tuples, where each element of the tuple is itself a valid data structure: - - data body(head(eyes[2], nose, mouth), arms[2], legs[2]) - - x = self.body.head.nose - y = self.body.arms[1] - -And we can do arrays of tuples: - - data bodies[100](head(eyes[2], nose, mouth), arms[2](fingers[5], elbow), legs[2]) - - x = self.bodies[45].head.eyes[1] - y = self.bodies[x].arms[1].fingers[3] - -Note that the following is unfortunately not legal: - - data body(head(eyes[2], nose, mouth), arms[2], legs[2]) - - x = self.body.head - y = x.eyes[0] - -Accesses have to descend fully in a single statement. To see how this could be used in a simpler example, let's go back to our name registry, and upgrade it so that when a user registers a key they become the owner of that key, and the owner of a key has the ability to (1) transfer ownership, and (2) change the value. We'll remove the return values here for simplicity. - - data registry[](owner, value) - - def register(key): - # Key not yet claimed - if not self.registry[key].owner: - self.registry[key].owner = msg.sender - - def transfer_ownership(key, new_owner): - if self.registry[key].owner == msg.sender: - self.registry[key].owner = new_owner - - def set_value(key, new_value): - if self.registry[key].owner == msg.sender: - self.registry[key].value = new_value - - def ask(key): - return([self.registry[key].owner, self.registry[key].value], items=2) - -Note that in the last ask command, the function returns an array of 2 values. If you wanted to call the registry, you would have needed to do something like `o = registry.ask(key, outsz=2)` and you could have then used `o[0]` and `o[1]` to recover the owner and value. - -### Simple arrays in memory - -The syntax for arrays in memory are different: they can only be finite and cannot have tuples or more complicated structures. - -Example: - - def bitwise_or(x, y): - blah = array(1243) - blah[567] = x - blah[568] = y - blah[569] = blah[567] | blah[568] - return(blah[569]) - -There are also two functions for dealing with arrays: - - len(x) - -Returns the length of array x. - - slice(x, items=start, items=end) - -Takes a slice of x starting with position start and ending with position end (note that we require `end >= start`; otherwise the result will almost certainly result in an error) - -### Arrays and Functions - -Functions can also take arrays as arguments, and return arrays. - - def compose(inputs:arr): - return(inputs[0] + inputs[1] * 10 + inputs[2] * 100) - - def decompose(x): - return([x % 10, (x % 100) / 10, x / 100]:arr) - -Putting the `:arr` after a function argument means it is an array, and putting it inside a return statement returns the value as an array (just doing `return([x,y,z])` would return the integer which is the memory location of the array). - -If a contract calls one of its functions, then it will autodetect which arguments should be arrays and parse them accordingly, so this works fine: - - def compose(inputs:arr, radix): - return(inputs[0] + inputs[1] * radix + inputs[1] * radix ** 2) - - def main(): - return self.compose([1,2,3,4,5], 100) - -However, if a contract wants to call another contract that takes arrays as arguments, then you will need to put a "signature" into the extern declaration: - - extern composer: [compose:ai, main] - -Here, `ai` means "an array followed by an integer". You can do things like `iiaa`, meaning 2 integers followed by 2 arrays or `iss` meaning an integer followed by 2 strings. If a colon is not provided, as in `main` in this example, that means that the function takes no arguments. If you want to determine the signature to use from a given file, you can do: - - > serpent mk_signature compose_test.se - extern compose_test: [compose:ai, main] - -### Strings - -There are two types of strings in Serpent: short strings, eg. `"george"`, and long strings, eg. `text("afjqwhruqwhurhqkwrhguqwhrkuqwrkqwhwhrugquwrguwegtwetwet")`. Short strings, given simply in quotes as above, are treated as numbers; long strings, surrounded by the `text` keyword as above, are treated as array-like objects; you can do `getch(str, index)` and `setch(str, index)` to manipulate characters in strings (doing `str[0]` will treat the string as an array and try to fetch the first 32 characters as a number). - -To use strings as function arguments or outputs, use the `str` tag, much like you would use `arr` for arrays. `len(s)` gives you the length of a string, and `slice` works for strings the same way as for arrays too. - -Here is an example of returning/retrieving a string: -``` -data str - -def t2(): - self.str = text("01") - log(data=self.str) - return(self.str, chars=2) - -def runThis(): - s = self.t2(outsz=2) - log(data=s) -``` - -### Macros - -**WARNING: Relatively new/untested feature, here be ~~dragons~~ serpents** - -Macros allow you to create rewrite rules which provide additional expressivity to the language. For example, suppose that you wanted to create a command that would compute the median of three values. You could simply do: - - macro median($a, $b, $c): - min(min(max($a, $b), max($a, $c)), max($b, $c)) - -Then, if you wanted to use it somewhere in your code, you just do: - - x = median(5, 9, 7) - -Or to take the max of an array: - - macro maxarray($a:$asz): - $m = 0 - $i = 0 - while i < $asz: - $m = max($m, $a[i]) - $i += 1 - $m - - x = maxarray([1, 9, 5, 6, 2, 4]:6) - -For a highly contrived example of just how powerful macros can be, see https://github.com/ethereum/serpent/blob/poc7/examples/peano.se - -Note that macros are not functions; they are copied into code every time they are used. Hence, if you have a long macro, you may instead want to make the macro call an actual function. Additionally, note that the dollar signs on variables are important; if you omit a dollar sign in the pattern $a then the macro will only match a variable actually called a. You can also create dollar sign variables that are in the substitution pattern, but not the search pattern; this will generate a variable with a random prefix each instance of the macro. You can also create new variables without a dollar sign inside a substitution pattern, but then the same variable will be shared across all instances of the pattern and with uses of that variable outside the pattern. - -### Types - -**WARNING: Relatively new/untested feature, here be ~~dragons~~ serpents** - -An excellent compliment to macros is Serpent's ghetto type system, which can be combined with macros to produce quite interesting results. Let us simply show this with an example: - - type float: [a, b, c] - - macro float($x) + float($y): - float($x + $y) - - macro float($x) - float($y): - float($x - $y) - - macro float($x) * float($y): - float($x * $y / 2^32) - - macro float($x) / float($y): - float($x * 2^32 / $y) - - macro unfloat($x): - $x / 2^32 - - macro floatfy($x): - float($x * 2^32) - - macro float($x) = float($y): - $x = $y - - macro with(float($x), float($y), $z): - with($x, $y, $z) - - a = floatfy(25) - b = a / floatfy(2) - c = b * b - return(unfloat(c)) - -This returns 156, the integer portion of 12.5^2. A purely integer-based version of this code would have simply returned 144. An interesting use case would be rewriting the [elliptic curve signature pubkey recovery code](https://github.com/ethereum/serpent/blob/df0aa0e1285d7667d4a0cc81b1e11e0abb31fff3/examples/ecc/jacobian_add.se) using types in order to make the code neater by making all additions and multiplications implicitly modulo P, or using [long integer types](https://github.com/ethereum/serpent/blob/poc7/examples/long_integer_macros.se) to do RSA and other large-value-based cryptography in EVM code. - -### Miscellaneous - -Additional Serpent coding examples can be found here: https://github.com/ethereum/serpent/tree/master/examples - -The three other useful features in the tester environment are: - -* Block access - you can dig around `s.block` to see block data (eg. `s.block.number`, `s.block.get_balance(addr)`, `s.block.get_storage_data(addr, index)`) -* Snapshots - you can do `x = s.snapshot()` and `s.revert(x)` -* Advancing blocks - you can do `s.mine(100)` and 100 blocks magically pass by with a 60-second interval between blocks. `s.mine(100, addr)` mines into a particular address. -* Full block data dump - type `s.block.to_dict()` - -Serpent also gives you access to many "special variables"; the full list is: - -* `tx.origin` - the sender of the transaction -* `tx.gasprice` - gas price of the transaction -* `msg.gas` - gas remaining -* `msg.sender` - the sender of the message -* `msg.value` - the number of wei (smallest units of ether) sent with the message -* `self` - the contract's own address -* `self.balance` - the contract's balance -* `x.balance` (for any x) - that account's balance -* `block.coinbase` - current block miner's address -* `block.timestamp` - current block timestamp -* `block.prevhash` - previous block hash -* `block.difficulty` - current block difficulty -* `block.number` - current block number -* `block.gaslimit` - current block gaslimit - -Serpent recognises the following "special functions": - -* `def init():` - executed upon contract creation, accepts no parameters -* `def shared():` - executed before running `init` and user functions -* `def code():` - executed before any user functions - -There are also special commands for a few crypto operations; particularly: - -* `addr = ecrecover(h, v, r, s)` - determines the address that produced the elliptic curve signature `v, r, s` of the hash `h` -* `x = sha256(a, items=4)` - returns the sha256 hash of the 128 bytes consisting of the 4-item array starting from `a` -* `x = ripemd160(a, items=4)` - same as above but for ripemd160 -* To hash an arbitrary number of bytes, use chars syntax. Example: `x = sha256([0xf1fc122bc7f5d74df2b9441a42a1469500000000000000000000000000000000], chars=16)` - returns the sha256 of the first 16 bytes. Note: padding with trailing zeroes, otherwise the first 16 bytes will be zeroes, and the sha256 of it will be computed instead of the desired. -* you can also use sha3 instead of sha256, e.g. `sha3(a, items=4)` -### Tips - -* If a function is not returning the result you expect, double-check that all variables are correct: there is no error/warning when using an undeclared variable. - -* `Invalid argument count or LLL function` usually means you just called foo() instead of `self.foo()`. - -* Sometimes you may be intending to use unsigned operators. eg div() and lt() instead of '/' and '<'. - -* To upgrade Serpent, you may need to do `pip uninstall ethereum-serpent` and `python setup.py install`. (Avoid `pip install ethereum-serpent` since it will get from PyPI which is probably old.) - -* When calling abi_contract(), if you get this type of error `Exception: Error (file "main", line 1, char 5): Invalid object member (ie. a foo.bar not mapped to anything)` make sure you are specifying correct path to the file you are compiling. - -* If you get a core dump when calling `abi_contract()`, check that you do not have functions with the same name. - -* Use macro for constants, example: -``` -macro CONSTANT: 99 -``` - -* Be careful that if your flow requires going through a number of contracts, that someone can't just directly short-circuit and call one of your latter contracts with data they've manipulated elsewhere. Example: If you have contract C which gives someone ether, but relies on computation from Contract A->B->C, that someone can't just call B or C to give themselves ether. - -### Other -http://mc2-umd.github.io/ethereumlab/docs/serpent_tutorial.pdf - some outdated but can generally be helpful \ No newline at end of file diff --git a/pages/dapp-development/serpent/Serpent_3.0.md b/pages/dapp-development/serpent/Serpent_3.0.md deleted file mode 100644 index 2c8f8c7b6..000000000 --- a/pages/dapp-development/serpent/Serpent_3.0.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -name: Serpent 3.0 -category: ---- - -The following is a suggested spec for Serpent 3.0. - - -1. Everything is strongly typed, but types are inferred, so there is no need to specify types explicitly. - -For example, consider the code: - - data bar[6] - - def foo(): - x = 5 - y = [1,2,3,4,5,6] - z = "123123124" - w1 = y[1] - w2 = z[2] - self.bar = y - return(x) - -A script would run through the code and assign types: - - x: int - y: arr[int] - z: string - w1: int - w2: int - self.bar: arr[int] :: storage - -When checking the type for w1, the script would see the line `w1 = y[1]`, note that `y` is already known as an `arr[int]` so `y[1]` will be recognized as `int`. Meanwhile, `z` will be known as `string`, and so `z[1]` will be recognized as a character, ie. `int`. Note that this means that `y[1]` will be compiled as `(mload (add y 32))` whereas `z[2]` will be compiled as `(byte (mload (add z 2)) 0)`. `self.bar = y` will be processed recursively so as to copy the entire contents of `y` into `self.bar`. \ No newline at end of file diff --git a/pages/dapp-development/solidity/Solidity,-Docs-and-ABI.md b/pages/dapp-development/solidity/Solidity,-Docs-and-ABI.md deleted file mode 100644 index e9b609379..000000000 --- a/pages/dapp-development/solidity/Solidity,-Docs-and-ABI.md +++ /dev/null @@ -1,231 +0,0 @@ ---- -name: Solidity Docs and ABI -category: ---- - -*NOTE: This is intended largely as a vague overview and a historical reference. For specific details and the latest specification, see [Ethereum Contract ABI](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI), [Ethereum Natural Specification Format](https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format) and [Solidity Tutorial](https://github.com/ethereum/wiki/wiki/Solidity-Tutorial).* - -An ABI is intended to serve as the de facto method for encoding & decoding data into & out of transactions. - -For this ABI, contracts are treated as objects. They export a particular interface, not dissimilar from that of an OO language, for example for a contract `Foo`: - -``` -contract Foo -{ - function sam(string32 in1) { ... } - function bar(uint256 in1, string in2) returns (string out1, bool out2) { ... } - function baz(uint32 in1, real in2) returns bool { ... } - -state: - uint256 tom; -} -``` - -Note you haven't seen this language before. This is a new high level language codenamed Solidity, that will feel mostly similar to something between JavaScript and C++ but with a number of syntactic additions to make it suitable for writing contracts within Ethereum. Language additions include: - -* static typing; -* contracts as first-class entities; -* state as part of a contract able to map & segment information into the storage; -* invariants, pre- and post-conditions as part of a contract; -* variadic return values with named components; -* a safe language subset allowing guaranteed static analysis & proofs; -* an inbuilt test-generation and execution environment for situations where formal proofing is not practical. - -The above would result in three methods being exposed: `bar`, `baz` and `sam`, roughly expressed in JSON as: - -``` -{ - "bar": { - "inputs": [ - "in1": "uint256", - "in2": "string" - ], - "outputs": [ - "out1": "string", - "out2": "bool" - ] - }, - "baz": { - "inputs": [ - "in1": "uint32", - "in2": "real" - ], - "outputs": [ - "__default": "bool" - ] - }, - "sam": { - "inputs": [ - "in1": "string32" - ], - "outputs": [] - } -} -``` - - -In previous versions of the proof-of-concept series, only simple 32-byte values were supported; the ABI adds the ability to also have variably sized arguments. - -### ABI - -See [Ethereum Contract ABI](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI). - -### Documentation - -It is expected that each method, together with the contract itself, will be documented in several ways. Aside from informal descriptions, each method should come with a formalised method to describe exactly its effect on the state of Ethereum. It should also include, where possible, pre- and post-conditions on the contract state, and the contract itself should include invariants over its own state, again each translated into natural language. - -For GavCoin, a meta coin that that is sub-divisible down to 1,000, and includes two functions `balance` and `send`, we might see the basic, undocumented contract as: - -``` -contract GavCoin -{ - function send(address to, uint256 valueInmGAV) { - balances[to] += valueInmGAV; - balances[transaction.sender] -= valueInmGAV; - } - function balance(address who) constant returns (uint256 balanceInmGAV) { - balanceInmGAV = balances[who]; - } - -invariants: - reduce(0, +, map(valueOf, balances)) == 100000000000; - -construction: - balances[transaction.sender] = 100000000000; - -state: - mapping balances (address) returns uint256 with function(address a) returns uint256 { return a; }; -}; -``` - -Of course it is wrong. A static checker will analyse this (with the language assertion that the uint256 type must not be allowed to underflow unless explicitly given that attribute) and come back with something like: - -``` -Line 8: >>> balances[transaction.sender] -= valueInmGAV <<<: - balances[...] may underflow with '-=' operation using unbounded operand valueInmGAV. - Suggestion: surround code with conditional to bound operand valueInmGAV. -``` - -This is basically saying that it can see no reason why `valueInmGAV` could be no bigger than `balances[transaction.sender]`. And it's right. We forgot to check the parameters. It's easily fixed by adding the conditional and altering the method to: - -``` - void send(address to, uint256 valueInmGAV) { - if (balances[transaction.sender] >= valueInmGAV) { - balances[to] += valueInmGAV; - balances[transaction.sender] -= valueInmGAV; - } - } -``` - -This would then be formally documented: - -``` -/// @title Some title here. -/// @author Homer Simpson -contract GavCoin -{ - /// @notice Send `(valueInmGAV / 1000).fixed(0,3)` GAV from the account of - /// `message.caller.address()`, to an account accessible only by `to.address()`. - /// @dev This is the developer documentation. - /// @param to The docs for the first param. - /// @param valueInmGav The docs for the second param. - function send(address to, uint256 valueInmGAV) { - if (balances[message.caller] >= valueInmGAV) { - balances[to] += valueInmGAV; - balances[message.caller] -= valueInmGAV; - } - } - - /// @notice `(balanceInmGAV / 1000).fixed(0,3)` GAV is the total funds available to `who.address()`. - function balance(address who) constant returns (uint256 balanceInmGAV) { - balanceInmGAV = balances[who]; - } - -invariants: - /// @notice The sum total amount of GAV in the system is 1 million. - reduce(0, add, map(valueOf, balances)) == 100000000000; - -construction: - /// @notice Endows `message.caller.address()` with 1m GAV. - balances[message.caller] = 100000000000; - -state: - mapping balances(address) returns uint256 with function(address a) returns uint256 { return a; }; -}; -``` - -This documentation would then allow the Ethereum browser to translate any message (and thus transaction) going in to this contract into English (and on to other languages hence). It would also allow a lay viewer to immediately discern what the contract conforms to; in this case they could see that it's premined in favour of the transaction sender and that the total amount of coins in the system never changes. - -For example, should a DApp, malicious or otherwise, attempt to send a transaction that gives all the user's GAV to itself, the user would, prior to signing and submission, receive a message saying something like: - -``` -Untrusted ÐApp "Foo Sprocket DApp" attempting to transact in your name: -Send 45.780 GAV from the account of Your Name Here to an account accessible only by Foo Sprocket DApp. -Do you wish to allow this? -``` - -Of course, they might be a bit more cunning and send it to an anonymous address, however, by differentiating friends' (and other known people) addresses from anonymous or untrusted addresses both visibly and clearly, we can imagine a mechanism that, at least for simple contracts, allow users a good level of security without excessive harm to their experience. - -### Getting the Documentation in - -The documentation, would be extracted from the source code ready to sit in a (probably JSON) file: - -``` -{ - "source": "...", - "language": "Solidity", - "languageVersion": 1, - "methods": { - "send": { "notice": "Send `(valueInmGAV / 1000).fixed(0,3)` GAV from the account of `message.caller.address()`, to an account accessible only by `to.address()`." }, - "balance": { "notice": "`(balanceInmGAV / 1000).fixed(0,3)` GAV is the total funds available to `who.address()`." } - }, - "invariants": [ - { "notice": "The sum total amount of GAV in the system is 1 million." } - ], - "construction": [ - { "notice": "Endows `message.caller.address()` with 1m GAV." } - ] -} -``` - -The full documentation format, that includes developer-specific documentation includes several more attributes: - -``` -{ - "author": "Gav Wood", - "description": "Some description of this contract.", - "methods": { - "send": { - "title": "Send some GAV.", - "details": "..." - }, - "balance": { - "title": "Send some GAV.", - "details": "..." - } - }, - "invariants": [ - { "title": "...", "details": "Markdown description of the first invariant." } - ], - "construction": { - "details": "Creates the contract with..." - } -} -``` - -This file would be hashed and distributed (either on a centralised website or, more preferably, through Swarm). It would be referenced by the Ethereum Singleton Trust contract in order to allow people or organisations that you know or trust to help inform you of its audit results and trustworth. Of course if you were a coder you could audit it manually (in this case it's pretty trivial) and determine how well the formal documentation matches the code, and also submit newer versions, perhaps in different languages that incorporate changes you feel are required to better descibe its actions & ramifications. - -### The ABI-Description File - -So the ABI description file ("header file") for the contract would be trivially derivable from the contract source code. It would be distributed by the author for anyone who wanted to message or transact with it. It would contain only enough information to compose the input data for a transaction and to decode the output data. Here's how the GAVCoin example contract would look: - -TODO: include `const`ness in the JSON: - -``` -[ - { "name": "send", "const": false, "input": [ { "name": "to", "type": "address" }, { "name": "valueInmGAV", "type": "uint256" } ], "output": [] }, - { "name": "balance", "const": true, "input": [ { "name": "who", "type": "address" } ], "output": [ { "name": "balanceInmGAV", "type": "uint256" } ] } -] -``` - -And that's it. Any questions to Gav. \ No newline at end of file diff --git a/pages/dapp-development/solidity/Solidity-Changelog.md b/pages/dapp-development/solidity/Solidity-Changelog.md deleted file mode 100644 index e1aac63dc..000000000 --- a/pages/dapp-development/solidity/Solidity-Changelog.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -name: Solidity Changelog -category: ---- - - * Improved error messages for unexpected tokens. - -### 0.1.6 (2015-10-16) - - * `.push()` for dynamic storage arrays. - * Tuple expressions (`(1,2,3)` or `return (1,2,3);`) - * Declaration and assignment of multiple variables (`var (x,y,) = (1,2,3,4,5);` or `var (x,y) = f();`) - * Destructuring assignment (`(x,y,) = (1,2,3)`) - * Bugfix: Internal error about usage of library function with invalid types. - * Bugfix: Correctly parse `Library.structType a` at statement level. - * Bugfix: Correctly report source locations of parenthesized expressions (as part of "tuple" story). - -### 0.1.5 (2015-10-07) - - * Breaking change in storage encoding: Encode short byte arrays and strings together with their length in storage. - * Report warnings - * Allow storage reference types for public library functions. - * Access to types declared in other contracts and libraries via `.`. - * Version stamp at beginning of runtime bytecode of libraries. - * Bugfix: Problem with initialized string state variables and dynamic data in constructor. - * Bugfix: Resolve dependencies concerning `new` automatically. - * Bugfix: Allow four indexed arguments for anonymous events. - * Bugfix: Detect too large integer constants in functions that accept arbitrary parameters. - -### 0.1.4 (2015-09-30) - - * Bugfix: Returning fixed-size arrays. - * Bugfix: combined-json output of solc. - * Bugfix: Accessing fixed-size array return values. - * Bugfix: Disallow assignment from literal strings to storage pointers. - * Refactoring: Move type checking into its own module. - -### 0.1.3 (2015-09-25) - - * `throw` statement. - * Libraries that contain functions which are called via CALLCODE. - * Linker stage for compiler to insert other contract's addresses (used for libraries). - * Compiler option to output runtime part of contracts. - * Compile-time out of bounds check for access to fixed-size arrays by integer constants. - * Version string includes libevmasm/libethereum's version (contains the optimizer). - * Bugfix: Accessors for constant public state variables. - * Bugfix: Propagate exceptions in clone contracts. - * Bugfix: Empty single-line comments are now treated properly. - * Bugfix: Properly check the number of indexed arguments for events. - * Bugfix: Strings in struct constructors. - -### 0.1.2 (2015-08-20) - - * Improved commandline interface. - * Explicit conversion between `bytes` and `string`. - * Bugfix: Value transfer used in clone contracts. - * Bugfix: Problem with strings as mapping keys. - * Bugfix: Prevent usage of some operators. - -### 0.1.1 (2015-08-04) - - * Strings can be used as mapping keys. - * Clone contracts. - * Mapping members are skipped for structs in memory. - * Use only a single stack slot for storage references. - * Improved error message for wrong argument count. (#2456) - * Bugfix: Fix comparison between `bytesXX` types. (#2087) - * Bugfix: Do not allow floats for integer literals. (#2078) - * Bugfix: Some problem with many local variables. (#2478) - * Bugfix: Correctly initialise `string` and `bytes` state variables. - * Bugfix: Correctly compute gas requirements for callcode. - -### 0.1.0 (2015-07-10) diff --git a/pages/dapp-development/solidity/Solidity-Features.md b/pages/dapp-development/solidity/Solidity-Features.md deleted file mode 100644 index e131facdb..000000000 --- a/pages/dapp-development/solidity/Solidity-Features.md +++ /dev/null @@ -1,1084 +0,0 @@ ---- -name: Solidity Features -category: ---- - -This is a list to explain and demonstrate new Solidity features as soon as they are completed. -It is used as a kind of changelog and items introduced at some point might be changed at a later point. The official reference is the [Documentation](https://ethereum.github.io/solidity/) which should always reflect the current state of the language. - -## Special Type Treatment for Integer Literals - -[PT](https://www.pivotaltracker.com/story/show/83393282) Expressions only involving integer literals are now essentially treated as "big integers" (i.e. they do not overflow) until they are actually used with a non-literal. The type of the expression is only determined at that point as the smallest integer type that can contain the resulting value. Example: - -``` -contract IntegerLiterals { - function f() { - // The folloing would have caused a type error in earlier versions (cannot add int8 to uint8), - // now the value of x is set to 9 and the type to uint8. - var x = -1 + 10; - // It is even possible to use literals that do not fit any of the Solidity types as long as - // the final value is small enough. The value of y will be 1, its type uint8. - var y = (0x100000000000000000001 * 0x100000000000000000001 * 0x100000000000000000001) & 0xff; - } -} -``` - -## Contracts Inherit all Members from Address - -[PT](https://www.pivotaltracker.com/story/show/85006746) Contract types are implicitly convertible to `address` and explicitly convertible to and from all integer types. Furthermore, a contract type contains all members of the address type with the semantics applying to the contract's address, unless overwritten by the contract. - -``` -contract Helper { - function getBalance() returns (uint bal) { - return this.balance; // balance is "inherited" from the address type - } -} -contract IsAnAddress { - Helper helper; - function setHelper(address a) { - helper = Helper(a); // Explicit conversion, comparable to a downcast - } - function sendAll() { - // send all funds to helper (both balance and send are address members) - helper.send(this.balance); - } -} -``` - -## ABI requires arguments to be padded to 32 bytes - -[PT](https://www.pivotaltracker.com/story/show/85006670) The latest version of the ABI specification -requires arguments to be padded to multiples of 32 bytes. This is not a language feature that can be demonstrated as code examples. Please see the automated tests `SolidityEndToEndTests::packing_unpacking_types` and `SolidityEndToEndTests::packing_signed_types`. - -## Specify value and gas for function calls - -[PT](https://www.pivotaltracker.com/story/show/84983014) External functions have member functions "gas" and "value" that allow to change the default amount of gas (all) and wei (0) sent to the called contract. "new expressions" also have the value member. - -``` -contract Helper { - function getBalance() returns (uint bal) { return this.balance; } -} -contract Main { - Helper helper; - function Main() { helper = new Helper.value(20)(); } - /// @notice Send `val` Wei to `helper` and return its new balance. - function sendValue(uint val) returns (uint balanceOfHelper) { - return helper.getBalance.value(val)(); - } -} -``` - -## delete for structs - -[PT](https://www.pivotaltracker.com/story/show/82574620) `delete` clears all members of a struct. - -``` -contract Contract { - struct Data { - uint deadline; - uint amount; - } - Data data; - function set(uint id, uint deadline, uint amount) { - data.deadline = deadline; - data.amount = amount; - } - function clear(uint id) { delete data; } -} -``` - -Note that, unfortunately, this only works directly on structs for now, so I would propose to not announce "delete" as a feature yet. - -## Contract Inheritance - -[PT1](https://www.pivotaltracker.com/story/show/84976094) -[PT2](https://www.pivotaltracker.com/story/show/86666936) Contracts can inherit from each other. - -``` -contract owned { - function owned() { owner = msg.sender; } - address owner; -} - -// Use "is" to derive from another contract. Derived contracts can access all members -// including private functions and storage variables. -contract mortal is owned { - function kill() { if (msg.sender == owner) suicide(owner); } -} - -// These are only provided to make the interface known to the compiler. -contract Config { function lookup(uint id) returns (address adr) {} } -contract NameReg { function register(string32 name) {} function unregister() {} } - -// Multiple inheritance is possible. Note that "owned" is also a base class of -// "mortal", yet there is only a single instance of "owned" (as for virtual -// inheritance in C++). -contract named is owned, mortal { - function named(string32 name) { - address ConfigAddress = 0xd5f9d8d94886e70b06e474c3fb14fd43e2f23970; - NameReg(Config(ConfigAddress).lookup(1)).register(name); - } - -// Functions can be overridden, both local and message-based function calls take -// these overrides into account. - function kill() { - if (msg.sender == owner) { - address ConfigAddress = 0xd5f9d8d94886e70b06e474c3fb14fd43e2f23970; - NameReg(Config(ConfigAddress).lookup(1)).unregister(); -// It is still possible to call a specific overridden function. - mortal.kill(); - } - } -} - -// If a constructor takes an argument, it needs to be provided in the header. -contract PriceFeed is owned, mortal, named("GoldFeed") { - function updateInfo(uint newInfo) { - if (msg.sender == owner) info = newInfo; - } - - function get() constant returns(uint r) { return info; } - - uint info; -} -``` - -## Function Modifiers - -[PT](https://www.pivotaltracker.com/story/show/85007072) Modifiers can be used to easily change the behaviour of functions, for example to automatically check a condition prior to executing the function. They are inheritable properties of contracts and may be overridden by derived contracts. -``` -contract owned { - function owned() { owner = msg.sender; } - address owner; - - // This contract only defines a modifier but does not use it - it will - // be used in derived contracts. - // The function body is inserted where the special symbol "_" in the - // definition of a modifier appears. - modifier onlyowner { if (msg.sender == owner) _ } -} -contract mortal is owned { - // This contract inherits the "onlyowner"-modifier from "owned" and - // applies it to the "kill"-function, which causes that calls to "kill" - // only have an effect if they are made by the stored owner. - function kill() onlyowner { - suicide(owner); - } -} -contract priced { - // Modifiers can receive arguments: - modifier costs(uint price) { if (msg.value >= price) _ } -} -contract Register is priced, owned { - mapping (address => bool) registeredAddresses; - uint price; - function Register(uint initialPrice) { price = initialPrice; } - function register() costs(price) { - registeredAddresses[msg.sender] = true; - } - function changePrice(uint _price) onlyowner { - price = _price; - } -} -``` - -Multiple modifiers can be applied to a function by specifying them -in a whitespace-separated list and will be evaluated in order. -Explicit returns from a modifier or function -body immediately leave the whole function, while control flow reaching the -end of a function or modifier body continues after the "_" in the previous -modifier. -Arbitrary expressions are allowed for modifier arguments and in this context, -all symbols visible from the function are visible in the modifier. Symbols -introduced in the modifier are not visible in the function (as they might -change by overriding). - - -## Conversion between String and Hash types - -[PT](https://www.pivotaltracker.com/story/show/85907772) The explicit conversion between `string` and `hash` types of equal size is now allowed. Example: - -``` -contract Test { - function convert(hash160 h, string20 s) returns (string20 res_s, hash160 res_h) { - res_s = string20(h); - res_h = hash160(s); - } -} -``` - -## Access to super - -[PT](https://www.pivotaltracker.com/story/show/86688340) In the following contract, the function `kill` is overridden by sibling classes. Due to the fact that the sibling classes do not know of each other, they can only call `mortal.kill()` with the effect that one of the overrides is completely bypassed. A reasonable implementation would call the kill functions in all classes in the inheritance hierarchy. -``` -contract mortal { function kill() { suicide(msg.sender); } } -contract named is mortal { function kill() { /*namereg.unregister();*/ mortal.kill(); } } -contract tokenStorage is mortal { function kill() { /*returnAllTokens();*/ mortal.kill(); } } -contract MyContract is named, tokenStorage {} -``` - -The `super` keyword solves this. Its type is the type of the current contract if it were empty, i.e. it contains all members of the current class' bases. Access to a member of super invokes the usual virtual member lookup, but it ends just above the current class. Using this keyword, the following works as expected: -``` -contract mortal { function kill() { suicide(msg.sender); } } -contract named is mortal { function kill() { /*namereg.unregister();*/ super.kill(); } } -contract tokenStorage is mortal { function kill() { /*returnAllTokens();*/ super.kill(); } } -contract MyContract is named, tokenStorage {} -``` -## State Variable Accessors -[PT](https://www.pivotaltracker.com/story/show/86308642) Public state variables now have accessors created for them. Basically any `public` state variable can be accessed by calling a function with the same name as the variable. - -``` -contract test { - function test() { - data = 42; - } - uint256 data; -} -``` - -For example in the above contract if you tried to call test's `data()` method then you would obtain the result 42. - -``` -contract test { - function test() { - data = 42; - } -private: - uint256 data; -} -``` -On the other hand on the above contract there is no accessor generated since the state variable is private. - -## Events - -[PT](https://www.pivotaltracker.com/story/show/86896642) Events allow the convenient usage of the EVM logging facilities. Events are inheritable members of contracts. When they are called, they cause -the arguments to be stored in the transaction's log. Up to three parameters can receive the -attribute `indexed` which will cause the respective arguments to be treated as log topics instead -of data. The hash of the signature of the event is always one of the topics. All non-indexed -arguments will be stored in the data part of the log. Example: -``` -contract ClientReceipt { - event Deposit(address indexed _from, hash indexed _id, uint _value); - function deposit(hash _id) { - Deposit(msg.sender, _id, msg.value); - } -} -``` -Here, the call to `Deposit` will behave identical to -`log3(msg.value, 0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20, sha3(msg.sender), _id);`. Note that the large hex number is equal to the sha3-hash of "Deposit(address,hash256,uint256)", the event's -signature. - -## Fallback Functions - -[PT](https://www.pivotaltracker.com/story/show/87035858) A contract can have exactly one unnamed -function. This function cannot have arguments and is executed on a call to the contract if -none of the other functions matches the given function identifier (or if no data was supplied at all). - -``` -contract Test { - function() { x = 1; } - uint x; -} - -contract Caller { - function callTest(address testAddress) { - Test(testAddress).send(0); - // results in Test(testAddress).x becoming == 1. - } -} -``` - -## Events in Exported Interfaces - -[PT](https://www.pivotaltracker.com/story/show/87036508) Events are exported to the JSON and Solidity interfaces generated by the compiler. The contract -``` -contract c { - event ev(uint indexed a); -} -``` -generates the JSON interface -``` -[ - { - "inputs" : [ - { - "indexed" : true, - "name" : "a", - "type" : "uint256" - }, - { - "indexed" : false, - "name" : "b", - "type" : "uint256" - } - ], - "name" : "ev", - "type" : "event" - } -] -``` -and the Solidity interface -`contract c{event ev(uint256 indexed a,uint256 b);}`. - -## Visibility Specifiers - -[PT](https://www.pivotaltracker.com/story/show/86635568) Functions and storage variables can be specified as being `public`, `protected` or `private`, where the default for functions is `public` `protected` for storage variables. Public functions are part of the external interface and can be called externally, while for storage variables, an automatic accessor function is generated. Non-public functions are only visible inside a contract and its derived contracts (there is no distinction between `protected` and `private` for now). - -``` -contract c { - function f(uint a) private returns (uint b) { return a + 1; } - uint public data; -} -``` -External functions can call `c.data()` to retrieve the value of `data` in storage, but are not able to call `f`. - -## Numeric Literals with Ether Subdenominations -[PT](https://www.pivotaltracker.com/story/show/84986568) Numeric literals can also be followed by the common ether subdenominations and the value of the assigned to variable will be multiplied by the proper amount. -``` -contract c { - function c() - { - val1 = 1 wei; // 1 - val2 = 1 szabo; // 1 * 10 ** 12 - val3 = 1 finney; // 1 * 10 ** 15 - val4 = 1 ether; // 1 * 10 ** 18 - } - uint256 val1; - uint256 val2; - uint256 val3; - uint256 val4; -} -``` - -## SHA3 with arbitrary arguments -[PT](https://www.pivotaltracker.com/story/show/86896766). `sha3()` can now take an arbitrary number and type of arguments. -``` -contract c { - function c() - { - val2 = 123; - val1 = sha3("foo"); // sha3(0x666f6f) - val3 = sha3(val2, "bar", 1031); //sha3(0x7b626172407) - } - uint256 val1; - uint16 val2; - uint256 val3; -} -``` - -## Optional Parameter Names -[PT](https://www.pivotaltracker.com/story/show/85594334). The names for function parameters and return parameters are now optional. -``` -contract test { - function func(uint k, uint) returns(uint){ - return k; - } -} -``` - -## Generic call Method -[PT](https://www.pivotaltracker.com/story/show/86084248) Address types (and contracts by inheritance) have a method `call` that can receive an arbitrary number of arguments of arbitrary types (which can be serialized in memory) and will invoke a message call on that address while the arguments are ABI-serialized. If the first type has a memory-length of exactly four bytes, it is not padded to 32 bytes, so it is possible to specify a function signature. -``` -contract test { - function f(address addr, uint a) { - addr.call(string4(string32(sha3("fun(uint256)"))), a); - } -} -``` - -## Byte arrays -[PT](https://www.pivotaltracker.com/story/show/87037182) Basic support for variable-length byte arrays. This includes - - `bytes` type for storage variables - - `msg.data` is of `bytes` type and contains the calldata - - functions taking arbitrary parameters (`call`, `sha3`, ...) can be called with `bytes` arguments. - - copying between `msg.data` and `bytes` storage variables - -What is not possible yet: - - function parameters of `bytes` type - - local variables of `bytes` type - - index or slice access - -``` -contract c { - bytes data; - function() { data = msg.data; } - function forward(address addr) { addr.call(data); } - function getLength() returns (uint) { return addr.length; } - function clear() { delete data; } -} -``` - -## Enums -[PT](https://www.pivotaltracker.com/story/show/86670106) Solidity now supports enums. Enums are explicitly convertible to all integer types but implicit conversion is not allowed. - -``` -contract test { - enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill }; - function test() - { - choices = ActionChoices.GoStraight; - } - function getChoice() returns (uint d) - { - d = uint256(choices); - } - ActionChoices choices; - } -``` - -## Visibility Specifiers - -[PT](https://www.pivotaltracker.com/story/show/86487946) The visibility of a function can be specified by giving at most one of the specifiers `external`, `public`, `inheritable` or `private`, where `public` is the default. "External" functions can only be called via message-calls, i.e. from other contracts or from the same contract using `this.function()` (note that this also prevents calls to overwritten functions in base classes). Furthermore, parameters of "external" functions are immutable. "Public" functions can be called from other contracts and from the same contract using stack-based calls. "Inheritable" and "private" functions can only be called via stack-based calls, while "inheritable" functions are only visible in the contract itself and its derived contracts and "private" functions are not even visible in derived contracts. - -``` -contract Base { - function exte() external { } - function publ() public /* can be omitted */ { } - function inhe() inheritable { priv(); } - function priv() private { } -} -contract Derived is Base { - function g() { - this.exte(); - // impossible: exte(); - this.publ(); - publ(); - // impossible: this.inhe(); - inhe(); - // impossible: this.priv(); - // impossible: priv(); - } -} -``` - -## Import Statement -[PT](https://www.pivotaltracker.com/story/show/87165660) We can now import other contracts and/or standard library contracts using the `import` keyword. -``` -import "mortal"; - -contract Test is mortal { - // since we import the standard library "mortal" contract and we inherit from it - // we can call the kill() function that it provides - function killMe() { kill();} -} -``` - -## Inline members initialization -[PT](https://www.pivotaltracker.com/story/show/84982976) Inline members can be initialized at declaration time. -``` -contract test { - function test(){ - m_b = 6; - } - uint m_a = 5; - uint m_b; -} -``` - -## The arguments of the constructor of base contract -[PT](https://www.pivotaltracker.com/story/show/88454388) It is possible to pass arguments to the base contracts constructor. The arguments for the base constructor in the header will be optional later. -``` -contract Base { - function Base(uint i) - { - m_i = i; - } - uint public m_i; -} -contract Derived is Base(0) { - function Derived(uint i) Base(i) {} -} -``` - -## Detect failed CALLs -[PT](https://github.com/ethereum/cpp-ethereum/pull/1212) If a CALL fails, do not just silently continue. Currently, this issues a STOP but it will throw an exception once we have exceptions. -``` -contract C { - function willFail() returns (uint) { - address(709).call(); - return 1; - } -} -``` -`willFail` will always return an empty byte array (unless someone finds the correct private key...). - -## Basic features for arrays -[PT](https://www.pivotaltracker.com/story/show/84119688) Byte arrays and generic arrays of fixed and dynamic size are supported in calldata and storage with the following features: Index access, copying (from calldata to storage, inside storage, both including implicit type conversion), enlarging and shrinking and deleting. Not supported are memory-based arrays (i.e. usage in non-external functions or local variables), array accessors and features like slicing. -Access to an array beyond its length will cause the execution to STOP (exceptions are planned for the future). -``` -contract ArrayExample { - uint[7][] data; - bytes byteData; - function assign(uint[4][] input, bytes byteInput) external { - data = input; // will assign uint[4] to uint[7] correctly, would produce type error if reversed - byteData = byteInput; // bytes are stored in a compact way - } - function indexAccess() { - data.length += 20; - data[3][5] = data[3][2]; - byteData[2] = byteData[7]; // this will access sigle bytes - } - function clear() { - delete data[2]; // will clear all seven elements - data.length = 2; // clears everything after the second element - delete data; // clears the whole array - } -} -``` - -## Now Variable -[PT](https://www.pivotaltracker.com/story/show/89728640) The global scope contains an immutable variable called `now` which is an alias to `block.timestamp`, i.e. it contains the timestamp of the current block. -``` -contract TimedContract { - uint timeout = now + 4 weeks; -} -``` - -## HashXX and StringXX to bytesXX -[Link to PT] (https://www.pivotaltracker.com/story/show/88146508) -+ We replace `hash(XX*8)` and `stringXX` by `bytesXX`. -+ `bytesXX` behaves as `hash(XX*8)` in terms of convertability and operators and as `stringXX` in terms of layout in memory (alignment, etc). - -+ `byte` is an alias for `bytes1`. - -+ `string` is reserved for future use. - - -## `msg.sig` returns the function's signature hash -[Link to PT] (https://www.pivotaltracker.com/story/show/86896308) -New magic type `msg.sig` that will provide the hash of the current function signature as `bytes4` type. - -``` -contract test { - function foo(uint256 a) returns (bytes4 value) { - return msg.sig; - } -} -``` - -Calling that function will return `2FBEBD38` which is the hash of the signature of `foo(uint256)`. - -## Constant variables -[PT](https://www.pivotaltracker.com/story/show/86670364) -Added `constant` specifier for uint, mapping and bytesXX types. Variables declared with `constant` specifier should be initialized at declaration time and can not be changed later. For now local variables can not be constant. Constant variables are not stored in Storage. - -``` -contract Foo { - function getX() returns (uint r) { return x; } - uint constant x = 56; -} -``` - -## Anonymous Events -[PT](https://www.pivotaltracker.com/story/show/89518344) -Added `anonymous` specifier for Event. For the event declared as anonymous the hash of the signature of the event will not be added as a first topic. The format is - -``` -event ([index list]) anonymous; -``` -Anonymous property is also visible for ABI document. - -## Tightly packed storage - -[PT](https://www.pivotaltracker.com/story/show/90011896) -Items in storage are packed tighly as far as possible according to the following rules: - - - The first item in a storage slot is stored lower-order aligned. - - Elementary types use only that many bytes that are necessary to store them. - - If an elementary type does not fit the remaining part of a storage slot, it is moved to the next storage slot. - - Structs and array data always start a new slot and occupy whole slots (but items inside a struct or array are packed tightly according to these rules). - -Examples: -``` -contract C { - uint248 x; // 31 bytes: slot 0, offset 0 - uint16 y; // 2 bytes: slot 1, offset 0 (does not fit in slot 0) - uint240 z; // 30 bytes: slot 1, offset 2 bytes - uint8 a; // 1 byte: slot 2, offset 0 bytes - struct S { - uint8 a; // 1 byte, slot +0, offset 0 bytes - uint256 b; // 32 bytes, slot +1, offset 0 bytes (does not fit) - } - S structData; // 2 slots, slot 3, offset 0 bytes (does not really apply) - uint8 alpha; // 1 byte, slot 4 (start new slot after struct) - uint16[3] beta; // 3*16 bytes, slots 5+6 (start new slot for array) - uint8 gamma; // 1 byte, slot 7 (start new slot after array) -} -``` - -## Common Subexpression Elimination Excluding Memory and Storage - -[PT](https://www.pivotaltracker.com/story/show/89148380) -The optimizer splits code into blocks (at all operations that have non-local side effects like JUMP, CALL, CREATE and for also all instructions that access or modify memory or storage), analyses these blocks by creating an expression graph and establishes equivalences in a bottom-up way, simplifying expressions that e.g. involve constants. In the following code-generation phase, it re-creates the set of instructions that transform a given initial stack configuration into a given target stack configuration utilizing the simplest representatives of these equivalence classes. -In conjunction with the already present jump-optimization, the two code snippets given below should be compiled into the same sequence of instructions: -``` -contract test { - function f(uint x, uint y) returns (uint z) { - var c = x + 3; - var b = 7 + (c * (8 - 7)) - x; - return -(-b | 0); - } -} -``` -``` -contract test { - function f(uint x, uint y) returns (uint z) { - return 10; - } -} -``` - -## Common Subexpression Elimination for Memory and Storage - -[PT](https://www.pivotaltracker.com/story/show/90785926) -This adds support for memory and storage operations to the common subexpression eliminator. This makes it possible to e.g. stretch the equality inference engine across SSTORE, MSTORE and even SHA3 computations (which go via memory). Without optimizer (because of packed storage), there are 4 SLOAD, 3 SSTORE and 4 SHA3 operations. The optimizer reduces those to a single SLOAD, SHA3 and SSTORE each. -``` -contract test { - struct s { uint8 a; uint8 b; uint8 c; } - mapping(uint => s) data; - function f(uint x, uint8 _a, uint8 _b, uint8 _c) { - data[x].a = _a; - data[x].b = _b; - data[x].c = data[x].a; - } -} -``` -## External Types -[PT](https://www.pivotaltracker.com/story/show/88772706) -All functions with visibility more than internal should have external types (ABI types) otherwise raise an error. -For Contract type external type is address type. -``` -contract Foo {} -contract Test { - function func() { - Foo arg; - this.Poo(arg); - Poo(arg); - } - function Poo(Foo c) external {} -} -``` -the ABI interface for Poo is Poo(address) when the Solidity interface is still Poo(Foo). - -## Accessor for Arrays -[PT](https://www.pivotaltracker.com/story/show/88500646) -For Arrays the accessor is generated which accepts the index as parameter and returns an array element -``` -contract test { - uint[3] public data; - function test() { - data[0] = 0; - data[1] = 1; - data[2] = 2; - } -} -``` -In the above contract if you tried to call the data(1) method of the test you would obtain the result 1. - -## Overloading Functions -[PT](https://www.pivotaltracker.com/story/show/85511572) Contracts can have multiple functions of the same name as long as the parameters differ in number or type. If such an overloaded function is referenced, it has to be called immediately to resolve the ambiguity using the types of the arguments. It is an error if not exactly one of the possible functions can be called with the given arguments. - -``` -contract Base { - function f(uint a) {} -} -contract Derived is Base { - function f(uint8 b) {} - function g() { - // f(250); would create a type error since 250 can be implicitly - // converted both to a uint8 and to a uint type - f(2000); // calls f from Base - } -} -``` -Of course overloading a function does not need inheritance, i.e. `f(uint a)` could as well have been defined directly in `Derived`. - -Overloaded functions are also present in the external interface. It is an error if two externally visible functions differ by their Solidity types but not by their external types, e.g. `f(Derived _d)` and `f(address _a)` both end up accepting an `address` type for the ABI although they are considered different inside Solidity. - -## Merging of Basic Blocks -[PT](https://www.pivotaltracker.com/story/show/89148124) Blocks of assembly instructions that do not contain jumps, stops or returns are moved and modified according to the following rules: - -* if the control never simply flows into a block, but it is jumped to unconditionally, the block is moved, eliminating the jump -* blocks that are never jumped to are removed - -These optimizations might sound not very powerful, but together with "Common Subexpression Elimination" (which is does much more than its name might suggest), the following contract is optimized to store `8` in the mapping and return the value without any jump. - -``` -contract c { - function () returns (uint) { return g(8); } - function g(uint pos) internal returns (uint) { setData(pos, 8); return getData(pos); } - function setData(uint pos, uint value) internal { data[pos] = value; } - function getData(uint pos) internal { return data[pos]; } - mapping(uint => uint) data; -} -``` - -## Interface contracts - -[PT](https://www.pivotaltracker.com/story/show/88344782) Contracts can be marked as "not fully implemented" by containing at least one abstract function. A function is abstract if it does not have a body defined. - -``` -contract base { function foo(); } -contract derived is base { function foo() {} } -``` - -For example in the above, foo is an abstract function and as such the base contract is an interface contract. All non-interface contracts that derive from it must implement its abstract functions. - -## Bare Callcode - -[PT](https://www.pivotaltracker.com/story/show/94682212) The address type receives a method `callcode` which is similar to `call`, but uses `CALLCODE` instead of `CALL` when the function is invoked. This means that the code at the given address will be executed in the context of the current contract. Example: - -``` -contract Code { - uint m_data; - function (uint v) { m_data = v; } -} -contract ActualContract { - uint public m_data; - function f() { Code(0x12345).callcode(7); } -} -``` -Assuming the contract `Code` is deployed at the address `0x12345`, calling `f()` of `ActualContract` will result in `m_data` of `ActualContract` being modified. The user has to ensure that the layout of storage in both contracts is suitable for callcode to be used. - -## Gas Estimation - -[PT](https://www.pivotaltracker.com/story/show/90098268) Solidity provides two ways to compute an upper bound on the gas usage of code: A structural one, which can be used to identify expensive statements and a functional one which tries to give an exact gas estimation for each function. -Some gas costs depend on the state of the virtual machine, e.g. on the cost of `sha3` depends on the length of the argument and writing to storage has different costs depending on whether the storage slot had the value zero or not. - -For the structural gas estimation, the gas cost of each opcode is computed assuming the intersection of all states in which the VM could reach this opcode. These costs are accumulated for each opcode that results from a specific statement (in some situations also other AST nodes) in the AST. So in this mode, opcodes are not counted multiple times even if they occur in loops. - -The functional gas estimation takes a different approach: For each function in a contract, the execution of this function is "simulated". As we want to provide an upper bound on the gas costs independent of the actual arguments, this is sometimes not accurate and may even result in "infinite" gas costs. Note that the gas costs of message-called functions are not included in the gas costs of a function. - -## Re-introduce string type - -[PT](https://www.pivotaltracker.com/story/show/95173586) -`string` is added as a type which behaves exactly like `bytes` with the following differences: - - index access is not allowed - - it does not have a length member - -In the ABI encoding (wiki already changed), string is a dynamic type whose "number of elements" field is the number of bytes, not the number of characters. -The encoding of the string is assumed to be UTF-8, but is not yet used inside Solidity. - -## In-memory types - -[PT](https://www.pivotaltracker.com/n/projects/1189488/stories/88238440) -Variables of reference type (structs and arrays including `string` and `bytes`) can either point to memory, storage or calldata. The keywords `storage` and `memory` as part of their declaration are used to indicate that (calldata cannot be used explicitly). Parameters (not return parameters) of external functions are forced to point to calldata. Parameters (also return parameters) of public and return parameters of external functions are forced to point to memory. In all other cases, if neither storage nor memory is given, function parameters default to point to memory and local variables default to point to storage. - -Note that this story enforces the constraints on memory-stored structs, but does not yet fully implement the code-generation part. Arrays, on the other hand, are fully implemented. - -As part of this change, references to storage are also cleaned up: An assignment of a state variable to a local variable or temporary converts it from a reference to a pointer. Assignments to storage pointers do not modify storage but only change the pointer. This means that it is not possible to assign a memory array to a storage pointer. Furthermore, it is illegal to pass a memory-array as an argument to a function that requires a storage reference (note that storage is statically allocated, i.e. there is no place to put this value). Es an example: -```js -contract c { - uint[] x; - function f(uint[] memoryArray) { - x = memoryArray; // works, copies the array to storage - var y = x; // works, assigns a pointer - y[7]; // fine, returns the 8th element - y.length = 2; // fine, modifies storage - delete x; // fine, clears the array - // y = memoryArray; // does not work, would need to create a new temporary / unnamed array in storage, but storage is "statically" allocated - // delete y; // does not work, would set pointer to zero and does not make sense for pointer - } -} -``` - -If possible (i.e. from anything to memory and from anything to a storage reference that is not a pointer), conversions between these data locations are performed automatically by the compiler. Sometimes, this is still not possible, i.e. mappings cannot reside in memory (as their size is unknown) and for now, some types in memory are not yet implemented, this includes structs and multi-dimensional arrays. - -Of course, once a storage array is converted to memory, modifications do not affect the array in storage. You can either assign the modified array back to storage (though this would be vastly inefficient) or you can pass around a storage pointer to begin with. As an example: - -```js -contract BinarySearch { - /// Finds the position of _value in the sorted list _data. - /// Note that "internal" is important here, because storage references only work for internal or private functions - function find(uint[] storage _data, uint _value) internal returns (uint o_position) { - return find(_data, 0, _data.length, _value); - } - function find(uint[] storage _data, uint _begin, uint _len, uint _value) private returns (uint o_position) { - if (_len == 0 || (_len == 1 && _data[_begin] != _value)) - return uint(-1); // failure - uint halfLen = _len / 2; - uint v = _data[_begin + halfLen]; - if (_value < v) - return find(_data, _begin, halfLen, _value); - else if (_value > v) - return find(_data, _begin + halfLen + 1, halfLen - 1, _value); - else - return _begin + halfLen; - } -} -``` - - -On memory usage: Since memory is wiped after each external function call, the Solidity runtime does not include proper memory management. It includes a "level indicator" which points to the next free memory slot. If memory is needed (because a storage object is copied to memory or an external function is called), it is allocated starting from this pointer. Functions that return objects stored in memory will not reset this pointer. This means that temporary memory objects will still take up space in memory even if they are not needed anymore. On the other hand, if a function does not return any memory-stored object, it resets the pointer to the value it had upon function entry (this is not yet implemented). - -The EVM does not allow `CALL` to be used with variably-sized return values. Because of this, return types of message-called functions which are dynamically sized are transparently changed to `void`. Clearing up the confusion which might arise in face of the resulting error message remains to do. - -Memory-stored objects as local variables are correctly zero-initialised: Members of structs and elements of fixed-size arrays are recursively initialised, dynamic arrays are set to zero length. `delete x` assigns a new zero-initialised value to `x`. - -## Positive integers conversion to signed - -[PT](https://www.pivotaltracker.com/n/projects/1189488/stories/92691082) -Positive integer literals are now convertible to signed if in value range. -``` -int8 x = 2; -``` - -## Exceptions in Solidity - -[PT](https://www.pivotaltracker.com/n/projects/1189488/stories/92929256) -Currently, there are two situations, where exceptions can happen in Solidity: If you access an array beyond its length (i.e. x[i] where i >= x.length) or if a function called via a message call does not finish properly (i.e. it runs out of gas or throws an exception itself). In such cases, Solidity will trigger an "invalid jump" and thus cause the EVM to revert all changes made to the state. - -It is planned to also throw and catch exceptions manually. - -## Structs in Memory - -[PT](https://www.pivotaltracker.com/n/projects/1189488/stories/84119690) -Structs can be passed around as function arguments, be returned from functions -and created in memory. - -```js -contract C { - struct S { uint a; uint b; } - struct A { uint x; uint y; S s; } - A data; - function f() internal returns (A) { - // Construct structs inline, pass to a function and return from it. - // Memory is allocated only once, pointers are passed around. - // Construction by member name is possible. - return g(A(5, 7, S({b: 1, a: 2}))); - } - function g(A _a) internal returns (A) { - _a.s.b = 2; - data = _a; // performs a copy - return _a; - } -} -``` - -## Flexible String Literals - -[PT](https://www.pivotaltracker.com/n/projects/1189488/stories/98462528) -String literals can be implicitly converted to `bytesX` (if they are not too long), -`string` and `bytes`, especially, they can be much longer than 32 bytes. - -```js -contract C { - bytes32 x; - function greet() returns (string) { - x = "Hello, World!"; - return "Hello, World!"; - } -} -``` - -## Strings as Mapping Keys - -Strings are allowed as keys for mappings. -```js -contract C { - mapping (string => uint) counter; - function inc(string _s) { counter[_s]++; } -} -``` - -## Libraries (without inheritance) - -[PT](https://www.pivotaltracker.com/n/projects/1189488/stories/82180360) - -Libraries are similar to contracts, but their purpose is that they are deployed only once at a specific address and their functions are called using CALLCODE, i.e. the library's code is called in the context of the calling contract. - -```js -library Math { - function max(uint a, uint b) returns (uint) { - if (a > b) return a; - else return b; - } - function min(uint a, uint b) returns (uint) { - if (a < b) return a; - else return b; - } -} -contract C { - function register(uint value) { - value = Math.max(10, Math.min(100, value)); // clamp value to [10, 100] - // ... - } -} -``` - -The calls to `Math.max` and `Math.min` are both compiled as calls (CALLCODEs) to an external contract. as the compiler cannot know where the library will be deployed at, these addresses have to be filled into the final bytecode by a linker. If the addresses are not given as arguments to the compiler, the compiled hex code will contain placeholders of the form `__Math______` (where `Math` is the name of the library). The address can be filled manually by replacing all those 40 symbols by the hex encoding of the address of the library contract. - -Restrictions for libraries in comparison to contracts: - - no state variables - - cannot inherit nor be inherited - -(these might be lifted at a later point) - -How to use the commandline compiler to link binaries: - -New option `--libraries` to either give a file containing the library addresses or directly as a string (tries to open as a file). Syntax: `:
[, or Whitespace] ...` -The address is a hex string that is optionally prefixed with `0x`. - -If solc is called with the option `--link`, all input files are interpreted to be unlinked binaries (hex-encoded) and are linked in-place (if the input is read from stdin, it is written to stdout). -All options except `--libraries` are ignored (including `-o`). - -## Throw - -[PT](https://www.pivotaltracker.com/story/show/96275370) - -throw is a statement that triggers a solidity exception and thus can be used to revert changes made during the transaction. It does not take any parameters and jumps to the error tag. -``` -contract Sharer { - function sendHalf(address addr) returns (uint balance) { - if (!addr.send(msg.value/2)) - throw; // also reverts the transfer to Sharer - return address(this).balance; - } -} -``` - -## Tightly Stored Byte Arrays and Strings - -[PT](https://www.pivotaltracker.com/story/show/101758652) - -Byte arrays (`bytes`) and strings (`string`) are stored more tightly packed in storage: -Short values (less than 32 bytes) are stored directly together with the length: -`` (the 31 higher-significant bytes contain the value, the least significant byte contains the doubled length) -Long values (at least 32 bytes) are stored as they were stored before, just that the length is doubled and the least significant bit is set to one to indicate "long string". - -Example: "abcdef" is stored as `0x61626364656600000...000d` while `"abcabcabc....abc"` (of length 40) is stored as `0x0000000...0051` in the main slot, and `616263616263...` is stored in the data slots. - -## Internal Types for Libraries - -[PT](https://www.pivotaltracker.com/story/show/101774798) Storage reference types are allowed to be passed to library functions. Together with this change, it is now possible to access internal types of other contracts and libraries and a compiler version stamp is added at the beginning of library runtime code. - -Example: - -``` -/// @dev Models a modifiable and iterable set of uint values. -library IntegerSet -{ - struct data - { - /// Mapping item => index (or zero if not present) - mapping(uint => uint) index; - /// Items by index (index 0 is invalid), items with index[item] == 0 are invalid. - uint[] items; - /// Number of stored items. - uint size; - } - function insert(data storage self, uint value) returns (bool alreadyPresent) - { - uint index = self.index[value]; - if (index > 0) - return true; - else - { - if (self.items.length == 0) self.items.length = 1; - index = self.items.length++; - self.items[index] = value; - self.index[value] = index; - self.size++; - return false; - } - } - function remove(data storage self, uint value) returns (bool success) - { - uint index = self.index[value]; - if (index == 0) - return false; - delete self.index[value]; - delete self.items[index]; - self.size --; - } - function contains(data storage self, uint value) returns (bool) - { - return self.index[value] > 0; - } - function iterate_start(data storage self) returns (uint index) - { - return iterate_advance(self, 0); - } - function iterate_valid(data storage self, uint index) returns (bool) - { - return index < self.items.length; - } - function iterate_advance(data storage self, uint index) returns (uint r_index) - { - index++; - while (iterate_valid(self, index) && self.index[self.items[index]] == index) - index++; - return index; - } - function iterate_get(data storage self, uint index) returns (uint value) - { - return self.items[index]; - } -} - -/// How to use it: -contract User -{ - /// Just a struct holding our data. - IntegerSet.data data; - /// Insert something - function insert(uint v) returns (uint size) - { - /// Sends `data` via reference, so IntegerSet can modify it. - IntegerSet.insert(data, v); - /// We can access members of the struct - but we should take care not to mess with them. - return data.size; - } - /// Computes the sum of all stored data. - function sum() returns (uint s) - { - for (var i = IntegerSet.iterate_start(data); IntegerSet.iterate_valid(data, i); i = IntegerSet.iterate_advance(data, i)) - s += IntegerSet.iterate_get(data, i); - } -} -``` - -## Destructuring Assignments - -[PT](https://www.pivotaltracker.com/story/show/99085194) Inline tuples can be created and assigned to newly declared local variables or already existing lvalues. This makes it possible to access multiple return values from functions. - -``` function f() returns (uint, uint, uint) { return (1,2,3); }``` -``` -var (a,b,c) = f(); -var (,x,) = f(); -var (,y) = f(); -var (z,) = f(); -``` -For newly declared variables it is not possible to specify the types of variables, they will be inferred from the assigned value. Any component in the assigned tuple can be left out. If the first or last element is left out, they can consume an arbitrary number of values. At the end of this code, we will have: -`a == 1`, `b == 2`, `c == 3`, `x == 2`, `y == 3`, `z == 1`. - -For newly constructed tuples, elements may not be left out, except for one special case that allows to distiguish between 1-tuples and single expressions: `(x)` is equivalent to `x`, but `(x,)` is a 1-tuple containing `x`. - -Assigning to pre-existing lvalues is similar to declaring multiple variables and also allows wildcards: - -``` -contract c { - string s; - struct Data {uint a; uint b;} - mapping(uint => Data) data; - function f() { - (s, data[45]) = ("abc", Data(1, 2)); - } -} -``` - -## `.push()` for Dynamic Storage Arrays - -Dynamically-sized storage arrays have a member function `push`, such that -`var l = arr.push(el);` is equivalent to `arr[arr.length++] = el; var l = arr.length;`. - -``` -contract c { - struct Account { address owner; uint balance; } - Account[] accounts; - function newAccount(address _owner, uint _balance) { - accounts.push(Account(_owner, _balance)); - } -} - -``` \ No newline at end of file diff --git a/pages/dapp-development/solidity/Solidity-Tutorial.md b/pages/dapp-development/solidity/Solidity-Tutorial.md deleted file mode 100644 index 737ccc077..000000000 --- a/pages/dapp-development/solidity/Solidity-Tutorial.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -name: Solidity Tutorial -category: ---- - -Solidity is a high-level language whose syntax is similar to that of JavaScript and it is designed to compile to code for the Ethereum Virtual Machine. This -tutorial starts with a basic introduction to Solidity and assumes some knowledge of -the Ethereum Virtual Machine and programming in general. It tries to explain all features present in the language but does not cover features like -the [natural language specification](Ethereum-Natural-Specification-Format) -or formal verification and is also not meant as a final specification -of the language. - -See also [Russian version (русский перевод)](https://github.com/ethereum/wiki/wiki/%D0%A0%D1%83%D0%BA%D0%BE%D0%B2%D0%BE%D0%B4%D1%81%D1%82%D0%B2%D0%BE-%D0%BF%D0%BE-Solidity) ->>>>>>> 787d2cbb44d0ad68fdc567516393c19127d08270 - -*** - -English version moved to a new [site](https://solidity.readthedocs.io/en/latest/). diff --git a/pages/dapp-development/solidity/Solidity-standard-library.md b/pages/dapp-development/solidity/Solidity-standard-library.md deleted file mode 100644 index afc10ce8d..000000000 --- a/pages/dapp-development/solidity/Solidity-standard-library.md +++ /dev/null @@ -1,156 +0,0 @@ ---- -name: Solidity Standard Library -category: ---- - -# Solidity standard library - -### overview - -This is poc of solidity standard library. -Probably all of the contracts, but `owned` && `mortal` will be removed soon. - -Here is solidity tutorial prepared by Eris team. [Click](https://eng.erisindustries.com/tutorials/2015/03/11/solidity-1/) - - -### contracts - -- [owned](#owned) -- [mortal](#mortal) - - -#### owned -``` -contract owned{ - function owned() { - owner = msg.sender; - } - - modifier onlyowner() { - if(msg.sender==owner) _ - } - - address owner; -} -``` - -#### mortal - -``` -import "owned"; - -contract mortal is owned { - function kill() { - if (msg.sender == owner) suicide(owner); - } -} -``` - -### poc_contracts -- [Coin](#coin1) -- [Config](#config) -- [CoinReg](#coinreg) -- [configUser](#configuser) -- [Config](#config) -- [named](#named) -- [NameReg](#namereg) -- [service](#service) -- [std](#std) - -#### coin -``` -import "CoinReg"; -import "Config"; -import "configUser"; - -contract coin is configUser { - function coin(string3 name, uint denom) { - CoinReg(Config(configAddr()).lookup(3)).register(name, denom); - } -} -``` - -#### Coin -``` -contract Coin { - function isApprovedFor(address _target,address _proxy) constant returns(bool _r) {} - function isApproved(address _proxy)constant returns(bool _r){} - function sendCoinFrom(address _from,uint256 _val,address _to){} - function coinBalanceOf(address _a)constant returns(uint256 _r){} - function sendCoin(uint256 _val,address _to){} - function coinBalance()constant returns(uint256 _r){} - function approve(address _a){} -} -``` - -#### CoinReg -``` -contract CoinReg { - function count()constant returns(uint256 r){} - function info(uint256 i)constant returns(address addr,string3 name,uint256 denom){} - function register(string3 name,uint256 denom){}function unregister(){} -} -``` - -#### configUser -``` -contract configUser { - function configAddr()constant returns(address a){ - return 0xc6d9d2cd449a754c494264e1809c50e34d64562b; - } -} -``` - -#### Config -``` -contract Config { - function lookup(uint256 service)constant returns(address a){} - function kill(){}function unregister(uint256 id){} - function register(uint256 id,address service){} -} -``` - -#### configUser -``` -import "Config"; -import "NameReg"; -import "configUser"; - -contract named is configUser { - function named(string32 name) { - NameReg(Config(configAddr()).lookup(1)).register(name); - } -} -``` - -#### NameReg -``` -contract NameReg { - function register(string32 name){} - function addressOf(string32 name)constant returns(address addr){} - function unregister(){}function nameOf(address addr)constant returns(string32 name){} -} -``` - - -#### service -``` -import "Config"; -import "configUser"; - -contract service is configUser { - function service(uint _n){ - Config(configAddr()).register(_n, this); - } -} -``` - -#### std -``` -import "owned"; -import "mortal"; -import "Config"; -import "configUser"; -import "NameReg"; -import "named"; -``` \ No newline at end of file diff --git a/pages/dapp-development/solidity/Solidity.md b/pages/dapp-development/solidity/Solidity.md deleted file mode 100644 index b819e94e1..000000000 --- a/pages/dapp-development/solidity/Solidity.md +++ /dev/null @@ -1,128 +0,0 @@ ---- -name: Solidity -category: ---- - -## This page might be outdated. - -Solidity is probably the first example of a Contract-Oriented Language, a slight reworking of the well-established group of Object-Oriented Languages. Here's an example of Solidity: - -``` -contract PriceFeed is owned, mortal, priced, named("GoldFeed") -{ - function updateInfo(uint newInfo) onlyowner { - info = newInfo; - } - - function get() constant costs returns(uint r) { - r = info; - } - - uint info; -} -``` - -From the syntax, it will feel mostly similar to something between JavaScript and C++ but with a number of additions to make it suitable for writing contracts within Ethereum. Language additions include: - -* static typing; -* property-based language transforms; -* contracts as first-class entities; -* state as part of a contract able to map & segment information into the permanent storage; -* invariants, pre- and post-conditions as part of a contract; -* variadic return values with named components; -* a safe language subset allowing guaranteed static analysis & proofs; -* an inbuilt test-generation and execution environment for situations where formal proofing is not practical. - -### Documentation - -It is expected that each method, together with the contract itself, will be documented in several ways. Aside from informal descriptions, each method should come with a formalised method to describe exactly its effect on the state of Ethereum. It should also include, where possible, pre- and post-conditions on the contract state, and the contract itself should include invariants over its own state, again each translated into natural language. - -For GavCoin, a meta coin that that is sub-divisible down to 1,000, and includes two functions `balance` and `send`, we might see the basic, undocumented contract as: - -``` -contract GavCoin is named("GavCoin") -{ - function GavCoin() { - balances[transaction.sender] = 100000000000; - } - function send(address to, uint256 valueInmGAV) { - balances[to] += valueInmGAV; - balances[transaction.sender] -= valueInmGAV; - } - function balance(address who) constant returns (uint256 balanceInmGAV) { - balanceInmGAV = balances[who]; - } - - invariant reduce(0, +, map(valueOf, balances)) == 100000000000; - - mapping (address => uint256) balances; -}; -``` - -Of course it is wrong. A static checker will analyse this (with the language assertion that the uint256 type must not be allowed to underflow unless explicitly given that attribute) and come back with something like: - -``` -Line 8: >>> balances[transaction.sender] -= valueInmGAV <<<: - balances[...] may underflow with '-=' operation using unbounded operand valueInmGAV. - Suggestion: surround code with conditional to bound operand valueInmGAV. -``` - -This is basically saying that it can see no reason why `valueInmGAV` could be no bigger than `balances[transaction.sender]`. And it's right. We forgot to check the parameters. It's easily fixed by adding the conditional and altering the method to: - -``` - void send(address to, uint256 valueInmGAV) { - if (balances[transaction.sender] >= valueInmGAV) { - balances[to] += valueInmGAV; - balances[transaction.sender] -= valueInmGAV; - } - } -``` - -This would then be formally documented: - -``` -/// @title Some title here. -/// @author Homer Simpson -contract GavCoin is named("GavCoin") -{ - /// @notice Endows `message.caller.address()` with 1m GAV. - function GavCoin() { - balances[transaction.sender] = 100000000000; - } - - /// @notice Send `(valueInmGAV / 1000).fixed(0,3)` GAV from the account of - /// `message.caller.address()`, to an account accessible only by `to.address()`. - /// @dev This is the developer documentation. - /// @param to The docs for the first param. - /// @param valueInmGav The docs for the second param. - function send(address to, uint256 valueInmGAV) { - if (balances[message.caller] >= valueInmGAV) { - balances[to] += valueInmGAV; - balances[message.caller] -= valueInmGAV; - } - } - - /// @notice `(balanceInmGAV / 1000).fixed(0,3)` GAV is the total funds available to `who.address()`. - function balance(address who) constant returns (uint256 balanceInmGAV) { - balanceInmGAV = balances[who]; - } - - /// @notice The sum total amount of GAV in the system is 1 million. - invariant reduce(0, add, map(valueOf, balances)) == 100000000000; - - mapping (address => uint256) balances; -}; -``` - -This documentation would then allow the Ethereum browser to translate any message (and thus transaction) going in to this contract into English (and on to other languages hence). It would also allow a lay viewer to immediately discern what the contract conforms to; in this case they could see that it's premined in favour of the transaction sender and that the total amount of coins in the system never changes. - -For example, should a DApp, malicious or otherwise, attempt to send a transaction that gives all the user's GAV to itself, the user would, prior to signing and submission, receive a message saying something like: - -``` -Untrusted ÐApp "Foo Sprocket DApp" attempting to transact in your name: -Send 45.780 GAV from the account of Your Name Here to an account accessible only by Foo Sprocket DApp. -Do you wish to allow this? -``` - -Of course, they might be a bit more cunning and send it to an anonymous address, however, by differentiating friends' (and other known people) addresses from anonymous or untrusted addresses both visibly and clearly, we can imagine a mechanism that, at least for simple contracts, allow users a good level of security without excessive harm to their experience. - diff --git a/pages/dapp-development/solidity/Tags-for-Solidity-in-code-documentation.md b/pages/dapp-development/solidity/Tags-for-Solidity-in-code-documentation.md deleted file mode 100644 index 8b1378917..000000000 --- a/pages/dapp-development/solidity/Tags-for-Solidity-in-code-documentation.md +++ /dev/null @@ -1 +0,0 @@ - diff --git a/pages/dapp-development/solidity/The-Solidity-Programming-Language.md b/pages/dapp-development/solidity/The-Solidity-Programming-Language.md deleted file mode 100644 index d72d918e5..000000000 --- a/pages/dapp-development/solidity/The-Solidity-Programming-Language.md +++ /dev/null @@ -1,239 +0,0 @@ ---- -name: The Solidity Programming Language -category: ---- - -# This page is not actively maintained. - -The current Solidity documentation can be found at http://ethereum.github.io/solidity/ - -# Foreword - -Solidity is roughly speaking, an object-oriented language designed for writing contracts in Ethereum. Contracts are (typically) small programs which govern the behaviour of accounts within the Ethereum state. These programs operate within the context of the Ethereum environment. Such accounts are able to pass messages between themselves as well as doing practically Turing complete computation. - -Solidity is perhaps the first example of a *contract-oriented* programming language; a slight tweak on the notion of object-orientation. While closely related to object-oriented languages, this is a language designed specifically to help express agreements that must encode ideas and relationships relevant to Real Life, or some formal model thereof. As such we see notions such as ownership, identity, protections and restrictions forming a core part of the vocabulary and idiomatic grammar. - -We see language grammar actually tieing in with many of the aspects of this: the `event` primitives along with the `indexed` keyword explicitly address the logging environment which Ethereum provides. The variadic return values mimic the fact that output data of Ethereum's calling mechanism is, like the input data, an arbitrary byte array. - -# Basic Contract Anatomy - -## Hello, World! - -No language would be complete without a Hello World program. Operating within the Ethereum environment, Solidity has no obvious way of "outputting" a string. The closest we can do is to use a log event to place a string into the blockchain: - -``` -contract HelloWorld { - event Print(string out); - function() { Print("Hello, World!"); } -} -``` - -This contract, if placed on the blockchain and called, would create a log entry on the blockchain of type `Print` with a parameter `"Hello, World!"`. Easy, eh? - -## The Contract - -The contract is the basic structure of Solidity. It is a prototype of an object which lives on the blockchain. A contract may be instantiated into a contract-account (or 'object', or sometimes just 'account') at which point it gets a uniquely identifying address with which is may be called. The address here is similar to a reference or pointer in C-like languages, or just a plain old object in Javascript. Like plain objects in many object-oriented languages, contracts can never run themselves - they may only be called, or, put another way, they can only react to the receipt of a message; they can never be proactive. - -We denote a contract with the `contract` keyword and a name, followed by its definition enclosed in braces (`{` & `}`). Here is the most basic contract: - -``` -contract MostBasicContract { -} -``` - -It doesn't do anything. To make it do something when it receives a message, we can introduce a function. The function you've already seen is the so-called default function. Why this is default will be properly explained later, but for now, suffice it to say that it is simply the function that gets called when this contract (well, an instantiation of it, anyway) receives a message from the Ethereum Environment. - -The syntax of a function is similar to Javascript: it begins with the `function` keyword, then has a parenthesised parameter list, and finally has a braced expression block. - -``` -contract MostBasicContract { - function() { - // executed when a message is received. - } -} -``` - -This expression block is very similar to other C-like languages including Javascript. Within our expression block, we are able to do arbitrary computation; for instance, we might try to determine what the sum of 1 and 1 is and place it into a variable called `two`: - -``` -contract Simple { - function() { - var two = 1 + 1; - } -} -``` - -Unlike in Javascript, all variables must be declared prior to use and typed. However, for convenience, `var` is provided as a way to automatically determine the type through the expression it is initialised to. In this case, the type is `uint`, but more on the types later. - -## Simple Types - -The type system in Solidity revolves largely around the 256-bit word size of the EVM. To this end, there are 4 major types, each of which are specifically 256-bits wide: - -- `uint`: 256-bit unsigned integer, operable with bitwise and unsigned arithmetic operations. -- `int`: 256-bit signed integer, operable with bitwise and signed arithmetic operations. -- `real`: 256-bit signed fixed-point quantity, 127-bit left of the point, 128-bit right. -- `bytes32`: sequence of 32 bytes (256 bit in total). - -In addition to these, there is the intrinsic `address` type used for identifying specific accounts and a bool type for representing true and false: - -- `address`: account identifier, 160-bits. -- `bool`: two-state value. - -Most of the time, we'll tend to use `uint` und `bytes32`; the former if we intend to do arithmetic, the latter when we need to identify or refer to pieces of data, events, &c. - -So to declare a variable it is very similar to the C-like languages: we simply place the type, followed by the variable name and finish the expression with a `;`. For example to declare a uint named `x` we would write: - -``` -uint x; -``` - -If we then wanted to assign `69` to it, we'd use the assignment operator, `=` (not forgetting to place the trailing `;`: - -``` -uint x; -x = 69; -``` - -There is a shorthand to declaring and assigning; those two statements may be collapsed over the `x` into: - -``` -uint x = 69; -``` - -In this situation, where we are simultaneously declaring and initialising the variable, we are able to substitute the type with the keyword `var`. If we do this, the type will be determined through the type of the expression we are assigning: - -``` -var x = 69; -``` - -If we were to assign a decimal, `var` would become equivalent to a real: - -``` -var x = 69; // here, "var" is equivalent to "uint". -var y = 69.42; // here, "var" is equivalent to "real". -``` - -## Literals - -Solidity includes three types of literals; these are used for expressing specific, well-known values. - -# Integers - -Integer literals are formed from a sequence of numbers in the range 0-9. They are interpreted as decimals. Examples include `69` and `01000000`. - - -In terms of literals, addresses are formed from the characters `0x` followed directly by a sequence of pairs of hexadecimal numbers, in the range 0-9 and a-f (not case sensitive). They are interpreted as hexadecimal-encoded bytes. Examples include: - -``` -address a = 0x0123456789abcdef0123; -``` - -# Byte Strings - -Byte string literals are formed by a sequence of arbitrary characters contained between quote characters (`"`). They are generally interpreted as zero-terminated ASCII encoded text, similar to C. The terminating zero need not be supplied. An examples would be: `"Hello, World!"`. - -# Reals - -Reals are formed similar to integers except that they include a decimal point and at least one number on either side of it. An example would be: `3.14159265` and `42.000001`. - -## Parameters and Returns - -Messages can have arbitrary input and output data. Since functions are our way of expressing how messages should be handled, they need a way of expressing how this data should be utilised. As such, like in Javascript and C, functions may take parameters as input; unlike in Javascript and C, they may so return arbitrary parameters as output. The input parameters, and types, must be named, type followed by name. For example, suppose we want our contract to accept messages that present two integers, we would write something like: - -``` -contract Simple { - function(uint _a, uint _b) { - // do something with _a and _b. - } -} -``` - -Parameters are not allowed to be altered; they are so-called *constant* values and as such may not be used on the left-hand side of an expression. - -Returning information through the message is equally simple using the same syntax with the `returns` keyword. For example, suppose we wished to return two results: the sum and the product of the two given integers, then we would write: - -``` -contract Simple { - function(uint _a, uint _b) returns (uint o_sum, uint o_product) { - o_sum = _a + _b; - o_product = _a * _b; - } -} -``` - -Return parameters are always reset to zero; if they are not explicitly set, then they - -## Arithmetic & Flow-control - -There are a number of - -On-hand, we also have the Keccak, aka SHA-3 function. So, - - -### Fields - -Contracts may have data members. - -### Constant - -## Methods - -### Constant - -## The Constructor - -## The Environment - -# More Complex Typing - -## Contracts & Forward Declarations - -### External Calls - -### Limiting Gas and Passing Value - -## Arrays - -There is also a special type - -- `byte[]`: dynamic-length packed byte array. - -## Mappings - -## Structs and Enums - -# Advanced Solidity - -## Visibility - -- Public -- Private -- External - -## Inheritance - -## Function Modifiers - -## Logging - -## Calling conventions - -# The Solidity Library - -### owned - -### multiowned - -### mortal - -### named - -### daylimit - -# Solidity 2.0 - -## Invariants - -## Pre- & Post-conditions - -## The dynamic Keyword diff --git a/pages/design-rationale/[english]-design-rationale.md b/pages/design-rationale/[english]-design-rationale.md deleted file mode 100644 index c50bcedbb..000000000 --- a/pages/design-rationale/[english]-design-rationale.md +++ /dev/null @@ -1,223 +0,0 @@ ---- -name: Design Rationale -category: ---- - -Although Ethereum borrows many ideas that have already been tried and tested for half a decade in older cryptocurrencies like Bitcoin, there are a number of places in which Ethereum diverges from the most common way of handling certain protocol features, and there are also many situations in which Ethereum has been forced to develop completely new economic approaches because it offers functionality that is not offered by other existing systems. The purpose of this document will be to detail all of the finer potentially nonobvious or in some cases controversial decisions that were made in the process of building the Ethereum protocol, as well as showing the risks involved in both our approach and possible alternatives. - -## Principles - -The Ethereum protocol design process follows a number of principles: - -1. **Sandwich complexity model**: we believe that the bottom level architecture of Ethereum should be as simple as possible, and the interfaces to Ethereum (including high level programming languages for developers and the user interface for users) should be as easy to understand as possible. Where complexity is inevitable, it should be pushed into the "middle layers" of the protocol, that are not part of the core consensus but are also not seen by end users - high-level-language compilers, argument serialization and deserialization scripts, storage data structure models, the leveldb storage interface and the wire protocol, etc. However, this preference is not absolute. -2. **Freedom**: users should not be restricted in what they use the Ethereum protocol for, and we should not attempt to preferentially favor or disfavor certain kinds of Ethereum contracts or transactions based on the nature of their purpose. This is similar to the guiding principle behind the concept of "net neutrality". One example of this principle _not_ being followed is the situation in the Bitcoin transaction protocol where use of the blockchain for "off-label" purposes (eg. data storage, meta-protocols) is discouraged, and in some cases explicit quasi-protocol changes (eg. OP_RETURN restriction to 40 bytes) are made to attempt to attack applications using the blockchain in "unauthorized" ways. In Ethereum, we instead strongly favor the approach of setting up transaction fees in such a way as to be roughly incentive-compatible, such that users that use the blockchain in bloat-producing ways internalize the cost of their activities (ie. Pigovian taxation). -3. **Generalization**: protocol features and opcodes in Ethereum should embody maximally low-level concepts, so that they can be combined in arbitrary ways including ways that may not seem useful today but which may become useful later, and so that a bundle of low-level concepts can be made more efficient by stripping out some of its functionality when it is not necessary. An example of this principle being followed is our choice of a LOG opcode as a way of feeding information to (particularly light client) dapps, as opposed to simply logging all transactions and messages as was internally suggested earlier - the concept of "message" is really the agglomeration of multiple concepts, including "function call" and "event interesting to outside watchers", and it is worth separating the two. -4. **We Have No Features**: as a corollary to generalization, we often refuse to build in even very common high-level use cases as intrinsic parts of the protocol, with the understanding that if people really want to do it they can always create a sub-protocol (eg. ether-backed subcurrency, bitcoin/litecoin/dogecoin sidechain, etc) inside of a contract. An example of this is the lack of a Bitcoin-like "locktime" feature in Ethereum, as such a feature can be simulated via a protocol where users send "signed data packets" and those data packets can be fed into a specialized contract that processes them and performs some corresponding function if the data packet is in some contract-specific sense valid. -5. **Non-risk-aversion**: we are okay with higher degrees of risk if a risk-increasing change provides very substantial benefits (eg. generalized state transitions, 50x faster block times, consensus efficiency, etc) - -These principles are all involved in guiding Ethereum development, but they are not absolute; in some cases, desire to reduce development time or not to try too many radical things at once has led us to delay certain changes, even some that are obviously beneficial, to a future release (eg. Ethereum 1.1). - -## Blockchain-level protocol - -This section provides a description of some of the blockchain-level protocol changes made in Ethereum, including how blocks and transactions work, how data is serialized and stored, and the mechanisms behind accounts. - -### Accounts and not UTXOs - -Bitcoin, along with many of its derivatives, stores data about users' balances in a structure based on _unspent transaction outputs_ (UTXOs): the entire state of the system consists of a set of "unspent outputs" (think, "coins"), such that each coin has an owner and a value, and a transaction spends one or more coins and creates one or more new coins, subject to the validity constraints: - -1. Every referenced input must be valid and not yet spent -2. The transaction must have a signature matching the owner of the input for every input -3. The total value of the inputs must equal or exceed the total value of the outputs - -A user's "balance" in the system is thus the total value of the set of coins for which the user has a private key capable of producing a valid signature. - -![](https://bitcoin.org/img/dev/en-transaction-propagation.svg) -(Image from https://bitcoin.org/en/developer-guide) - -Ethereum jettisons this scheme in favor of a simpler approach: the state stores a list of accounts where each account has a balance, as well as Ethereum-specific data (code and internal storage), and a transaction is valid if the sending account has enough balance to pay for it, in which case the sending account is debited and the receiving account is credited with the value. If the receiving account has code, the code runs, and internal storage may also be changed, or the code may even create additional messages to other accounts which lead to further debits and credits. - -The benefits of UTXOs are: - -1. **Higher degree of privacy**: if a user uses a new address for each transaction that they receive then it will often be difficult to link accounts to each other. This applies greatly to currency, but less to arbitrary dapps, as arbitrary dapps often necessarily involve keeping track of complex bundled state of users and there may not exist such an easy user state partitioning scheme as in currency. -2. **Potential scalability paradigms**: UTXOs are more theoretically compatible with certain kinds of scalability paradigms, as we can rely on only the owner of some coins maintaining a Merkle proof of ownership, and even if everyone including the owner decides to forget that data then only the owner is harmed. In an account paradigm, everyone losing the portion of a Merkle tree corresponding to an account would make it impossible to process messages that affect that account at all in any way, including sending to it. However, non-UTXO-dependent scalability paradigms do exist. - -The benefits of accounts are: - -1. **Large space savings**: for example, if an account has 5 UTXO, then switching from a UTXO model to an account model would reduce the space requirements from (20 + 32 + 8) * 5 = 300 bytes (20 for the address, 32 for the txid and 8 for the value) to 20 + 8 + 2 = 30 bytes (20 for the address, 8 for the value, 2 for a nonce(see below)). In reality savings are not nearly this massive because accounts need to be stored in a Patricia tree (see below) but they are nevertheless large. Additionally, transactions can be smaller (eg. 100 bytes in Ethereum vs. 200-250 bytes in Bitcoin) because every transaction need only make one reference and one signature and produces one output. -2. **Greater fungibility**: because there is no blockchain-level concept of the source of a specific set of coins, it becomes less practical, both technically and legally, to institute a redlist/blacklisting scheme and to draw a distinction between coins depending on where they come from. -3. **Simplicity**: easier to code and understand, especially once more complex scripts become involved. Although it is possible to shoehorn arbitrary decentralized applications into a UTXO paradigm, essentially by giving scripts the ability to restrict what kinds of UTXO a given UTXO can be spent to, and requiring spends to include Merkle tree proofs of change-of-application-state-root that scripts evaluate, such a paradigm is much more complicated and ugly than just using accounts. -4. **Constant light client reference**: light clients can at any point access all data related to an account by scanning down the state tree in a specific direction. In a UTXO paradigm, the references change with each transaction, a particularly burdensome problem for long-running dapps that try to use the above mentioned state-root-in-UTXO propagation mechanism. - -We have decided that, particularly because we are dealing with dapps containing arbitrary state and code, the benefits of accounts massively outweigh the alternatives. Additionally, in the spirit of the We Have No Features principle, we note that if people really do care about privacy then mixers and coinjoin can be built via signed-data-packet protocols inside of contracts. - -One weakness of the account paradigm is that in order to prevent replay attacks, every transaction must have a "nonce", such that the account keeps track of the nonces used and only accepts a transaction if its nonce is 1 after the last nonce used. This means that even no-longer-used accounts can never be pruned from the account state. A simple solution to this problem is to require transactions to contain a block number, making them un-replayable after some period of time, and reset nonces once every period. Miners or other users will need to "ping" unused accounts in order to delete them from the state, as it would be too expensive to do a full sweep as part of the blockchain protocol itself. We did not go with this mechanism only to speed up development for 1.0; 1.1 and beyond will likely use such a system. - -## Merkle Patricia Trees - -The Merkle Patricia tree/trie, previously envisioned by Alan Reiner and implemented in the Ripple protocol, is the primary data structure of Ethereum, and is used to store all account state, as well as transactions and receipts in each block. The MPT is a combination of a [Merkle tree](https://en.wikipedia.org/wiki/Merkle_tree) and [Patricia tree](https://en.wikipedia.org/wiki/Radix_tree), taking the elements of both to create a structure that has both of the following properties: - -1. Every unique set of key/value pairs maps uniquely to a root hash, and it is not possible to spoof membership of a key/value pair in a trie (unless an attacker has ~2^128 computing power) -2. It is possible to change, add or delete key/value pairs in logarithmic time - -This gives us a way of providing an efficient, easily updateable, "fingerprint" of our entire state tree. The Ethereum MPT is formally described here: https://github.com/ethereum/wiki/wiki/Patricia-Tree - -Specific design decisions in the MPT include: - -1. **Having two classes of nodes**, kv nodes and diverge nodes (see MPT spec for more details). The presence of kv nodes increases efficiency because if a tree is sparse in a particular area the kv node will serve as a "shortcut" removing the need to have a tree of depth 64. -2. **Making diverge nodes hexary and not binary**: this was done to improve lookup efficiency. We now recognize that this choice was suboptimal, as the lookup efficiency of a hexary tree can be simulated in a binary paradigm by storing nodes batched. However, because the trie construction is so easy to implement incorrectly and end up with at the very least state root mismatches, we have decided to table such a reorganization until 1.1. -3. **No distinction between empty value and non-membership**: this was done for simplicity, and because it works well with Ethereum's default that values that are unset (eg. balances) generally mean zero and the empty string is used to represent zero. However, we do note that it sacrifices some generality and is thus slightly suboptimal. -4. **Distinction between terminating and non-terminating nodes**: technically, the "is this node terminating" flag is unnecessary, as all tries in Ethereum are used to store static key lengths, but we added it anyway to increase generality, hoping that the Ethereum MPT implementations will be used as-is by other cryptographic protocols. -5. **Using sha3(k) as the key in the "secure tree"** (used in the state and account storage tries): this makes it much more difficult to DoS the trie by setting up maximally unfavorable chains of diverge nodes 64 levels deep and repeatedly calling SLOAD and SSTORE on them. Note that this makes it more difficult to enumerate the tree; if you want to have enumeration capability in your client, the simplest approach is to maintain a database mapping `sha3(k) -> k`. - -## RLP - -RLP ("recursive length prefix") encoding is the main serialization format used in Ethereum, and is used everywhere - for blocks, transactions, account state data and wire protocol messages. RLP is formally described here: https://github.com/ethereum/wiki/wiki/RLP - -RLP is intended to be a highly minimalistic serialization format; its sole purpose is to store nested arrays of bytes. Unlike [protobuf](https://developers.google.com/protocol-buffers/docs/pythontutorial), [BSON](http://bsonspec.org/) and other existing solutions, RLP does not attempt to define any specific data types such as booleans, floats, doubles or even integers; instead, it simply exists to store structure, in the form of nested arrays, and leaves it up to the protocol to determine the meaning of the arrays. Key/value maps are also not explicitly supported; the semi-official suggestion for supporting key/value maps is to represent such maps as `[[k1, v1], [k2, v2], ...]` where `k1, k2...` are sorted using the standard ordering for strings. - -The alternative to RLP would have been using an existing algorithm such as protobuf or BSON; however, we prefer RLP because of (1) simplicity of implementation, and (2) guaranteed absolute byte-perfect consistency. Key/value maps in many languages don't have an explicit ordering, and floating point formats have many special cases, potentially leading to the same data leading to different encodings and thus different hashes. By developing a protocol in-house we can be assured that it is designed with these goals in mind (this is a general principle that applies also to other parts of the code, eg. the VM). Note that bencode, used by BitTorrent, may have provided a passable alternative for RLP, although its use of decimal encoding for lengths makes it slightly suboptimal compared to the binary RLP. - -## Compression algorithm - -The wire protocol and the database both use a custom compression algorithm to store data. The algorithm can best be described as run-length-encoding zeroes and leaving other values as they are, with the exception of a few special cases for common values like `sha3('')`. For example: - - >>> compress('horse') - 'horse' - >>> compress('donkey dragon 1231231243') - 'donkey dragon 1231231243' - >>> compress('\xf8\xaf\xf8\xab\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbe{b\xd5\xcd\x8d\x87\x97') - '\xf8\xaf\xf8\xab\xa0\xfe\x9e\xbe{b\xd5\xcd\x8d\x87\x97' - >>> compress("\xc5\xd2F\x01\x86\xf7#<\x92~}\xb2\xdc\xc7\x03\xc0\xe5\x00\xb6S\xca\x82';{\xfa\xd8\x04]\x85\xa4p") - '\xfe\x01' - -Before the compression algorithm existed, many parts of the Ethereum protocol had a number of special cases; for example, `sha3` was often overridden so that `sha3('') = ''`, as that would save 64 bytes from not needing to store code or storage in accounts. However, a change was made recently where all of these special cases were removed, making Ethereum data structures much bulkier by default, instead adding the data saving functionality to a layer outside the blockchain protocol by putting it on the wire protocol and seamlessly inserting it into users' database implementations. This adds modularity, simplifying the consensus layer, and also allows continued upgrades to the compression algorithm to be deployed relatively easily (eg. via network protocol versions). - -## Trie Usage - -Warning: this section assumes knowledge of how bloom filters work. For an introduction, see http://en.wikipedia.org/wiki/Bloom_filter - -Every block header in the Ethereum blockchain contains pointers to three tries: the _state trie_, representing the entire state after accessing the block, the _transaction trie_, representing all transactions in the block keyed by index (ie. key 0: the first transaction to execute, key 1: the second transaction, etc), and the _receipt tree_, representing the "receipts" corresponding to each transaction. A receipt for a transaction is an RLP-encoded data structure: - - [ medstate, gas_used, logbloom, logs ] - -Where: - -* `medstate` is the state trie root after processing the transaction -* `gas_used` is the amount of gas used after processing the transaction -* `logs` is a list of items of the form `[address, [topic1, topic2...], data]` that are produced by the `LOG0` ... `LOG4` opcodes during the execution of the transaction (including by the main call and sub-calls). `address` is the address of the contract that produced the log, the topics are up to 4 32-byte values, and the data is an arbitrarily sized byte array. -* `logbloom` is a bloom filter made up of the addresses and topics of all logs in the transaction. - -There is also a bloom in the block header, which is the OR of all of the blooms for the transactions in the block. The purpose of this construction is to make the Ethereum protocol light-client friendly in as many ways as possible. For more details on Ethereum light clients and their use cases, see the [light client page (principles section)](https://github.com/ethereum/wiki/wiki/Light-client-protocol#principles). - -## Uncle incentivization - -The "Greedy Heaviest Observed Subtree" (GHOST) protocol is an innovation [first introduced](http://eprint.iacr.org/2013/881.pdf) by Yonatan Sompolinsky and Aviv Zohar in December 2013, and is the first serious attempt at solving the issues preventing much faster block times. The motivation behind GHOST is that blockchains with fast confirmation times currently suffer from reduced security due to a high stale rate - because blocks take a certain time to propagate through the network, if miner A mines a block and then miner B happens to mine another block before miner A's block propagates to B, miner B's block will end up wasted ("stale") and will not contribute to network security. Furthermore, there is a centralization issue: if miner A is a mining pool with 30% hashpower and B has 10% hashpower, A will have a risk of producing a stale block 70% of the time (since the other 30% of the time A produced the last block and so will get mining data immediately) whereas B will have a risk of producing a stale block 90% of the time. Thus, if the block interval is short enough for the stale rate to be high, A will be substantially more efficient simply by virtue of its size. With these two effects combined, blockchains which produce blocks quickly are very likely to lead to one mining pool having a large enough percentage of the network hashpower to have de facto control over the mining process. - -As described by Sompolinsky and Zohar, GHOST solves the first issue of network security loss by including stale blocks in the calculation of which chain is the "longest"; that is to say, not just the parent and further ancestors of a block, but also the stale descendants of the block's ancestor (in Ethereum jargon, "uncles") are added to the calculation of which block has the largest total proof of work backing it. - -To solve the second issue of centralization bias, we adopt a different strategy: we provide block rewards to stales: a stale block receives 7/8 (87.5%) of its base reward, and the nephew that includes the stale block receives 1/32 (3.125%) of the base reward as an inclusion bounty. Transaction fees, however, are not awarded to uncles or nephews. - -In Ethereum, stale block can only be included as an uncle by up to the seventh-generation descendant of one of its direct siblings, and not any block with a more distant relation. This was done for several reasons. First, unlimited GHOST would include too many complications into the calculation of which uncles for a given block are valid. Second, unlimited uncle incentivization as used in Ethereum removes the incentive for a miner to mine on the main chain and not the chain of a public attacker. Finally, calculations show that restricting to seven levels provides most of the desired effect without many of the negative consequences. - -* A simulator that measures centralization risks is available at https://github.com/ethereum/economic-modeling/blob/master/ghost.py -* A high-level discussion can be found at https://blog.ethereum.org/2014/07/11/toward-a-12-second-block-time/ - -Design decisions in our block time algorithm include: - -* **12 second block time**: 12 seconds was chosen as a time that is as fast as possible, but is at the same time substantially longer than network latency. A [2013 paper](http://www.tik.ee.ethz.ch/file/49318d3f56c1d525aabf7fda78b23fc0/P2P2013_041.pdf) by Decker and Wattenhofer in Zurich measures Bitcoin network latency, and determines that 12.6 seconds is the time it takes for a new block to propagate to 95% of nodes; however, the paper also points out that the bulk of the propagation time is proportional to block size, and thus in a faster currency we can expect the propagation time to be drastically reduced. The constant portion of the propagation interval is about 2 seconds; however, for safety we assume that blocks take 12 seconds to propagate in our analysis. -* **7 block ancestor limit**: this is part of a design goal of wanting to make block history very quickly "forgettable" after a small number of blocks, and 7 blocks has been proven to provide most of the desired effect -* **1 block descendant limit** (eg. `c(c(p(p(p(head)))))`, where c = child and p = parent, is invalid): this is part of a design goal of simplicity, and the simulator above shows that it does not pose large centralization risks. -* **Uncle validity requirements**: uncles have to be valid headers, not valid blocks. This is done for simplicity, and to maintain the model of a blockchain as being a linear data structure (and not a block-DAG, as in Sompolinsky and Zohar's newer models). Requiring uncles to be valid blocks is also a valid approach. -* **Reward distribution**: 7/8 of the base mining reward to the uncle, 1/32 to the nephew, 0% of transaction fees to either. This will make uncle incentivization ineffective from a centralization perspective if fees dominate; however, this is one of the reasons why Ethereum is meant to continue issuing ether for as long as we continue using PoW. - -## Difficulty Update Algorithm - -The difficulty in Ethereum is currently updated according to the following rule: - - diff(genesis) = 2^32 - - diff(block) = diff.block.parent + floor(diff.block.parent / 1024) * - 1 if block.timestamp - block.parent.timestamp < 9 else - -1 if block.timestamp - block.parent.timestamp >= 9 - -The design goals behind the difficulty update rule are: - -* **Fast updating**: the time between blocks should readjust quickly given increasing or decreasing hashpower -* **Low volatility**: the difficulty should not bounce excessively if the hashpower is constant -* **Simplicity**: the algorithm should be relatively simple to implement -* **Low memory**: the algorithm should not rely on more than a few blocks of history, and should include as few "memory variables" as possible. Assume that the last ten blocks, plus all memory variables placed in the block headers of the last ten blocks, are all that is available for the algorithm to work with -* **Non-exploitability**: the algorithm should not excessively encourage miners to fiddle with timestamps, or mining pools to repeatedly add and remove hashpower, in an attempt to maximize their revenue - -We have already determined that our current algorithm is highly suboptimal on low volatility and non-exploitability, and at the very least we plan to switch the timestamps compares to be the parent and grandparent, so that miners only have the incentive to modify timestamps if they are mining two blocks in a row. Another more powerful formula with simulations is located at https://github.com/ethereum/economic-modeling/blob/master/diffadjust/blkdiff.py (the simulator uses Bitcoin mining power, but uses the per-day average for the entire day; it at one point simulates a 95% crash in a single day). - -## Gas and Fees - -Whereas all transactions in Bitcoin are roughly the same, and thus their cost to the network can be modeled to a single unit, transactions in Ethereum are more complex, and so a transaction fee system needs to take into account many ingredients, including cost of bandwidth, cost of storage and cost of computation. Of particular importance is the fact that the Ethereum programming language is Turing-complete, and so transactions may use bandwidth, storage and computation in arbitrary quantities, and the latter may end up being used in quantities that due to the halting problem cannot even be reliably predicted ahead of time. Preventing denial-of-service attacks via infinite loops is a key objective. - -The basic mechanism behind transaction fees is as follows: - -* Every transaction must specify a quantity of "gas" that it is willing to consume (called `startgas`), and the fee that it is willing to pay per unit gas (`gasprice`). At the start of execution, `startgas * gasprice` ether are removed from the transaction sender's account. -* All operations during transaction execution, including database reads and writes, messages, and every computational step taken by the virtual machine consumes a certain quantity of gas. -* If a transaction execution processes fully, consuming less gas than its specified limit, say with `gas_rem` gas remaining, then the transaction executes normally, and at the end of the execution the transaction sender receives a refund of `gas_rem * gasprice` and the miner of the block receives a reward of `(startgas - gas_rem) * gasprice`. -* If a transaction "runs out of gas" mid-execution, then all execution reverts, but the transaction is nevertheless valid, and the only effect of the transaction is to transfer the entire sum `startgas * gasprice` to the miner. -* When a contract sends a message to the other contract, it also has the option to set a gas limit specifically on the sub-execution arising out of that message. If the sub-execution runs out of gas, then the sub-execution is reverted, but the gas is nevertheless consumed. - -Each of the above components is necessary. For example: - -* If transactions did not need to specify a gas limit, then a malicious user could send a transaction that makes a multi-billion round loop, and no one would be able to process it since processing such a transaction would take longer than a block interval, but miners would not be able to tell beforehand, leading to a denial-of-service vulnerability. -* The alternative to strict gas-counting, time-limiting, does not work because it is too highly subjective (some machines are faster than others, and even among identical machines close-calls will always exist) -* The entire value `startgas * gasprice` has to be taken out at the start as a deposit so that there arise no situations where an account "bankrupts" itself mid-execution and becomes unable to pay for its gas costs. Note that balance checking is not sufficient, because an account can send its balance somewhere else. -* If execution did not revert in the event of an insufficient gas error, then contracts would need to take strong and difficult security measures to prevent themselves from being exploited by transactions or messages that provide only enough gas halfway through, thereby leading to some of the changes in a contract execution being executed but not others. -* If sub-limits did not exist, then hostile accounts could enact a denial-of-service attack against other contracts by entering into agreements with them, and then inserting an infinite loop at the beginning of computation so that any attempts by the victim contract to compensate the attack contract or send a message to it would starve the entire transaction execution. -* Requiring transaction senders to pay for gas instead of contracts substantially increases developer usability. Very early versions of Ethereum had contracts pay for gas, but this led to the rather ugly problem that every contract had to implement "guard" code that would make sure that every incoming message compensated the contract with enough ether to pay for the gas that it consumed. - -Note the following particular features in gas costs: - -* 21000 gas is charged for any transaction as a "base fee". This covers the cost of an elliptic curve operation to recover the sender address from the signature as well as the disk and bandwidth space of storing the transaction. -* A transaction can include an unlimited amount of "data", and there exist opcodes in the virtual machine which allow the contract receiving a transaction to access this data. The gas fee for data is 1 gas per zero byte and 5 gas per nonzero byte. This formula arose because we saw that most transaction data in contracts written by users was organized into a series of 32-byte arguments, most of which had many leading zero bytes, and given that such constructions seem inefficient but are actually efficient due to compression algorithms, we wanted to encourage their use in place of more complicated mechanisms which would try to tightly pack arguments according to the expected number of bytes, leading to very substantial complexity increase at compiler level. This is an exception to the sandwich complexity model, but a justified one due to the ratio of cost to benefit. -* The cost of the SSTORE opcode, which sets values in account storage, is either: (i) 20000 gas when changing a zero value to a nonzero value, (ii) 5000 gas when changing a zero value to a zero value or a nonzero value to a nonzero value, or (iii) 5000 gas when changing a nonzero value to a zero value, plus a 20000 gas refund to be given at the end of successful transaction execution (ie. NOT an execution leading to an out-of-gas exception). Refunds are capped at 50% of the total gas spent by a transaction. This provides a small incentive to clear storage, as we noticed that lacking such an incentive many contracts would leave storage unused, leading to quickly increasing bloat, providing most of the benefits of "charging rent" for storage without the cost of losing the assurance that a contract once placed will continue to exist forever. The delayed refund mechanism is necessary to prevent denial-of-service attacks where the attacker sends a transaction with a low amount of gas that repeatedly clears a large number of storage slots as part of a long-running loop, and then runs out of gas, consuming a large amount of verifiers' computing power without actually clearing storage or spending a lot of gas. The 50% cap is needed to ensure that a miner given a transaction with some quantity of gas can still determine an upper bound on the computational time to execute the transaction. -* There is no gas cost to data in messages provided by contracts. This is because there is no need to actually "copy" any data during a message call, as the call data can simply be viewed as a pointer to the parent contract's memory which will not change while the child execution is in progress. -* Memory is an infinitely expandable array. However, there is a gas cost of 1 per 32 bytes of memory expansion, rounding up. -* Some opcodes, whose computation time is highly argument-dependent, have variable gas costs. For example, the gas cost of EXP is 10 + 10 per byte in the exponent (ie. x^0 = 1 gas, x^1 ... x^255 = 2 gas, x^256 ... x^65535 = 3 gas, etc), and the gas cost of the copy opcodes (CALLDATACOPY, CODECOPY, EXTCODECOPY) is 1 + 1 per 32 bytes copies, rounding up (LOG also has a similar rule). The memory expansion gas cost is not sufficient to cover this, as it opens up a quadratic attack (50000 rounds of CALLDATACOPY of 50000 gas ~= 50000^2 computing effort, but only ~50000 gas before the variable gas cost was introduced) -* The CALL opcode (and CALLCODE for symmetry) costs an additional 9000 gas if the value is nonzero. This is because any value transfer causes significant bloat to history storage for an archival node. Note that the actual fee _charged_ is 6700; on top of this we add a mandatory 2300 gas minimum that is automatically given to the recipient. This is in order to ensure that wallets that receive transactions to at least have enough gas to make a log of the transaction. - -The other important part of the gas mechanism is the economics of the gas price itself. The default approach, used in Bitcoin, is to have purely voluntary fees, relying on miners to act as the gatekeepers and set dynamic minimums; the equivalent in Ethereum would be allowing transaction senders to set arbitrary gas costs. This approach has been received very favorably in the Bitcoin community particularly because it is "market-based", allowing supply and demand between miners and transaction senders determine the price. The problem with this line of reasoning is, however, that transaction processing is not a market; although it is intuitively attractive to construe transaction processing as a service that the miner is offering to the sender, in reality every transaction that a miner includes will need to be processed by every node in the network, so the vast majority of the cost of transaction processing is borne by third parties and not the miner that is making the decision of whether or not to include it. Hence, tragedy-of-the-commons problems are very likely to occur. - -Currently, due to a lack of clear information about how miners will behave in reality, we are going with a fairly simple approach: a voting system. Miners have the right to set the gas limit for the current block to be within ~0.0975% (1/1024) of the gas limit of the last block, and so the resulting gas limit should be the median of miners' preferences. The hope is that in the future we will be able to soft-fork this into a more precise algorithm. - -## Virtual Machine - -The Ethereum virtual machine is the engine in which transaction code gets executed, and is the core differentiating feature between Ethereum and other systems. Note that the _virtual machine_ should be considered separately from the _contract and message model_ - for example, the SIGNEXTEND opcode is a feature of the VM, but the fact that contracts can call other contracts and specify gas limits to sub-calls is part of the contract and message model. Design goals in the EVM include: - -* **Simplicity**: as few and as low-level opcodes as possible, as few data types as possible and as few virtual-machine-level constructs as possible -* **Total determinism**: there should be absolutely no room for ambiguity in any part of the VM specification, and the results should be completely deterministic. Additionally, there should be a precise concept of computational step which can be measured so as to compute gas consumption. -* **Space savings**: EVM assembly should be as compact as possible (eg. the 4000 byte base size of default C programs is NOT acceptable) -* **Specialization to expected applications**: the ability to handle 20-byte addresses and custom cryptography with 32-byte values, modular arithmetic used in custom cryptography, read block and transaction data, interact with state, etc -* **Simple security**: it should be easy to come up with a gas cost model for operations that makes the VM non-exploitable -* **Optimization-friendliness**: it should be easy to apply optimizations so that JIT-compiled and otherwise sped-up versions of the VM can be built. - -Some particular design decisions that were made: - -* **Temporary/permanent storage distinction** - a distinction exists between temporary storage, which exists within each instance of the VM and disappears when VM execution finishes, and permanent storage, which exists on the blockchain state level on a per-account basis. For example, suppose the following tree of execution takes place (using S for permanent storage and M for temporary): (i) A calls B, (ii) B sets `B.S[0] = 5`, `B.M[0] = 9`, (iii) B calls C, (iv) C calls B. At this point, if B tries to read `B.S[0]`, it will receive the value stored in B earlier, 5, but is B tries to read `B.M[0]` it will receive 0 because it is a new instance of the virtual machine with fresh temporary storage. If B now sets `B.M[0] = 13` and `B.S[0] = 17` in this inner call, and then both this inner call and C's call terminate, bringing the execution back to B's outer call, then B reading M will see `B.M[0] = 9` (since the last time this value was set was in the same VM execution instance) and `B.S[0] = 17`. If B's outer call ends and A calls B again, then B will see `B.M[0] = 0` and `B.S[0] = 17`. The purpose of this distinction is to (1) provide each execution instance with its own memory that is not subject to corruption by recursive calls, making secure programming easier, and (2) to provide a form of memory which can be manipulated very quickly, as storage updates are necessarily slow due to the need to modify the trie. -* **Stack/memory model** - the decision was made early on to have three types of computational state (aside from the program counter which points to the next instruction): stack (a standard LIFO stack of 32-byte values), memory (an infinitely expandable temporary byte array) and storage (permanent storage). On the temporary storage side, the alternative to stack and memory is a memory-only paradigm, or some hybrid of registers and memory (not very different, as registers basically are a kind of memory). In such a case, every instruction would have three arguments, eg. `ADD R1 R2 R3: M[R1] = M[R2] + M[R3]`. The stack paradigm was chosen for the obvious reason that it makes the code four times smaller. -* **32 byte word size** - the alternative is 4 or 8 byte words, as in most other architectures, or unlimited, as in Bitcoin. 4 or 8 byte words are too restrictive to store addresses and big values for crypto computations, and unlimited values are too hard to make a secure gas model around. 32 bytes is ideal because it is just large enough to store 32 byte values common in many crypto implementations, as well as addresses (and provides the ability to pack address and value into a single storage index as an optimization), but not so large as to be extremely inefficient. -* **Having our own VM at all** - the alternative is reusing Java, or some Lisp dialect, or Lua. We decided that having a specialized VM was appropriate because (i) our VM spec is much simpler than many other virtual machines, because other virtual machines have to pay a much lower cost for complexity, whereas in our case every additional unit of complexity is a step toward high barriers of entry creating development centralization and potential for security flaws including consensus failures, (ii) it allows us to specialize the VM much more, eg. by having a 32 byte word size, (iii) it allows us not to have a very complex external dependency which may lead to installation difficulties, and (iv) a full security review of Ethereum specific to our particular security needs would necessitate a security review of the external VM anyway, so the effort savings are not that large. -* **Using a variable extendable memory size** - we deemed a fixed memory size unnecessarily restrictive if the size is small and unnecessarily expensive if the size is large, and noted that if statements for memory access are necessary in any case to check for out-of-bounds access, so fixed size would not even make execution more efficient. -* **Not having a stack size limit** - no particular justification either way; note that limits are not strictly necessary in many cases as the combination of gas costs and a block-level gas limit will always act as a ceiling on the consumption of every resource. -* **Having a 1024 call depth limit** - many programing languages break at high stack depths much more quickly than they break at high levels of memory usage or computational load, so the implied limit from the block gas limit may not be sufficient. -* **No types** - done for simplicity. Instead, signed and unsigned opcodes for DIV, SDIV, MOD, SMOD are used instead (it turns out that for ADD and MUL the behavior of signed and unsigned opcodes is equivalent), and the transformations for fixed point arithmetic (high-depth fixed-point arithmetic is another benefit of 32-byte words) are in all cases simple, eg. at 32 bits of depth, `a * b -> (a * b) / 2^32`, `a / b -> a * 2^32 / b`, and +, - and * are unchanged from integer cases. - -The function and purpose of some opcodes in the VM is obvious, however other opcodes are less so. Some particular justifications are given below: - -* **ADDMOD**, **MULMOD**: in most cases, `mulmod(a, b, c) = a * b % c`. However, in the specific case of many classes of elliptic curve cryptography, 32-byte modular arithmetic is used, and doing `a * b % c` directly is therefore actually doing `((a * b) % 2^256) % c`, which gives a completely different result. A formula that calculates `a * b % c` with 32-byte values in 32 bytes of space is rather nontrivial and bulky. -* **SIGNEXTEND**: the purpose of SIGNEXTEND is to facilitate typecasting from a larger signed integer to a smaller signed integer. Small signed integers are useful because JIT-compiled virtual machines may in the future be able to detect long-running chunks of code that deals primarily with 32-byte integers and speed it up considerably. -* **SHA3**: SHA3 is very highly applicable in Ethereum code as secure infinite-sized hash maps that use storage will likely need to use a secure hash function so as to prevent malicious collisions, as well as for verifying Merkle trees and even verifying Ethereum-like data structures. A key point is that its companions `SHA256`, `ECRECOVER` and `RIPEMD160` are included not as opcodes but as pseudo-contracts. The purpose of this is to place them into a separate category so that, if/when we come up with a proper "native extensions" system later, more such contracts can be added without filling up the opcode space. -* **ORIGIN**: the primary use of the ORIGIN opcode, which provides the sender of a transaction, is to allow contracts to make refund payments for gas. -* **COINBASE**: the primary uses of the COINBASE opcode are to (i) allow sub-currencies to contribute to network security if they so choose, and (ii) open up the use of miners as a decentralized economic set for sub-consensus-based applications like Schellingcoin. -* **PREVHASH**: used as a semi-secure source of randomness, and to allow contracts to evaluate Merkle tree proofs of state in the previous block without requiring a highly complex recursive "Ethereum light client in Ethereum" construction. -* **EXTCODESIZE**, **EXTCODECOPY**: the primary uses here are to allow contracts to check the code of other contracts against a template, or even simulating them, before interacting with them. See http://lesswrong.com/lw/aq9/decision_theories_a_less_wrong_primer/ for applications. -* **JUMPDEST**: JIT-compiled virtual machines become much easier to implement when jump destinations are restricted to a few indices (specifically, the computational complexity of a variable-destination jump is roughly O(log(number of valid jump destinations)), although static jumps are always constant-time). Hence, we need (i) a restriction on valid variable jump destinations, and (ii) an incentive to use static over dynamic jumps. To meet both goals, we have the rules that (i) jumps that are immediately preceded by a push can jump anywhere but another jump, and (ii) other jumps can only jump to a JUMPDEST. The restriction against jumping on jumps is needed so that the question of whether a jump is dynamic or static can be determined by simply looking at the previous operation in the code. The lack of a need for JUMPDEST operations for static jumps is the incentive to use them. The prohibition against jumping into push data also speeds up JIT VM compilation and execution. -* **LOG**: LOG is meant to log events, see trie usage section above. -* **CALLCODE**: the purpose of this is to allow contracts to call "functions" in the form of code stored in other contracts, with a separate stack and memory, but using the contract's own storage. This makes it much easier to scalably implement "standard libraries" of code on the blockchain. -* **SUICIDE**: an opcode which allows a contract to quickly delete itself if it is no longer needed. The fact that SUICIDES are processed at the end of transaction execution, and not immediately, is motivated by the fact that having the ability to revert suicides that were already executed would substantially increase the complexity of the cache that would be required in an efficient VM implementation. -* **PC**: although theoretically not necessary, as all instances of the PC opcode can be replaced by simply putting in the actual program counter at that index as a push, using PC in code allows for the creation of position-independent code (ie. compiled functions which can be copy/pasted into other contracts, and do not break if they end up at different indices). diff --git a/pages/dev-technologies/Node-discovery-protocol.md b/pages/dev-technologies/Node-discovery-protocol.md deleted file mode 100644 index f0b9f6f34..000000000 --- a/pages/dev-technologies/Node-discovery-protocol.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -name: Node Discovery Protocol -category: ---- - -In a nutshell: -* Aimed at discovering _RLPx nodes_ to connect to -* UDP-based RPC protocol ([kademlia](https://en.wikipedia.org/wiki/Kademlia)-like) -* Defines 4 packet types: _ping_, _pong_, _findnode_ and _neighbors_ - -See details at either: -* [devp2p](https://github.com/ethereum/devp2p) repository's [node discovery protocol](https://github.com/ethereum/devp2p/blob/master/rlpx.md) page -* [go-ethereum](https://github.com/ethereum/go-ethereum) repository's [node discovery protocol](https://github.com/ethereum/go-ethereum/wiki/RLPx-----Node-Discovery-Protocol) page \ No newline at end of file diff --git a/pages/dev-technologies/Web3-Secret-Storage-Definition.md b/pages/dev-technologies/Web3-Secret-Storage-Definition.md deleted file mode 100644 index 0fd0641b3..000000000 --- a/pages/dev-technologies/Web3-Secret-Storage-Definition.md +++ /dev/null @@ -1,172 +0,0 @@ ---- -name: Web3 Secret Storage Definition -category: ---- - -This documents version 3 of the Web3 Secret Storage Definition. - -## Definition - -The actual encoding and decoding of the file remains largely unchanged from version 1, except that the crypto algorithm is no longer fixed to AES-128-CBC (AES-128-CTR is now the minimal requirement). Most of the meanings/algorithm are similar to version 1, except `mac`, which is given as the SHA3 (keccak-256) of the concatenation of the last 16 bytes of the derived key together with the full `ciphertext`. - -Secret key files are stored directly in `~/.web3/keystore` (for Unix-like systems) and `~/AppData/Web3/keystore` (for Windows). They may be named anything, but a good convention is `.json`, where `` is the 128-bit UUID given to the secret key (a privacy-preserving proxy for the secret key's address). - -All such files have an associated password. To derive a given `.json` file's secret key, first derive the file's encryption key; this is done through taking the file's password and passing it through a key derivation function as described by the `kdf` key. KDF-dependent static and dynamic parameters to the KDF function are described in `kdfparams` key. - -PBKDF2 must be supported by all minimally-compliant implementations, denoted though: - -- `kdf`: `pbkdf2` - -For PBKDF2, the `kdfparams` include: - -- `prf`: Must be `hmac-sha256` (may be extended in the future); -- `c`: number of iterations; -- `salt`: salt passed to PBKDF; -- `dklen`: length for the derived key. Must be >= 32. - -One the file's key has been derived, it should be verified through the derivation of the MAC. The MAC should be calculated as the SHA3 (keccak-256) hash of the byte array formed as the concatenations of the second-leftmost 16 bytes of the derived key with the `ciphertext` key's contents, i.e.: - -``` -KECCAK(DK[16..31] ++ ) -``` - -(where `++` is the concatenation operator) - -This value should be compared to the contents of the `mac` key; if they are different, an alternative password should be requested (or the operation cancelled). - -After the file's key has been verified, the cipher text (the `ciphertext` key in the file) may be decrypted using the symmetric encryption algorithm specified by the `cipher` key and parameterised through the `cipherparams` key. If the derived key size and the algorithm's key size are mismatched, the zero padded, rightmost bytes of the derived key should be used as the key to the algorithm. - -All minimally-compliant implementations must support the AES-128-CTR algorithm, denoted through: - -- `cipher`: `aes-128-ctr` - -This cipher takes the following parameters, given as keys to the `cipherparams` key: - -- `iv`: 128-bit initialisation vector for the cipher. - -The key for the cipher is the leftmost 16 bytes of the derived key, i.e. `DK[0..15]` - -The creation/encryption of a secret key should be essentially the reverse of these instructions. Make sure the `uuid`, `salt` and `iv` are actually random. - -In addition to the `version` field, which should act as a "hard" identifier of version, implementations may also use `minorversion` to track smaller, non-breaking changes to the format. - -## Test Vectors - -Details: - -- Address: `008aeeda4d805471df9b2a5b0f38a0c3bcba786b` -- ICAP: `XE542A5PZHH8PYIZUBEJEO0MFWRAPPIL67` -- UUID: `3198bc9c-6672-5ab3-d9954942343ae5b6` -- Password: `testpassword` -- Secret: `7a28b5ba57c53603b0b07b56bba752f7784bf506fa95edc395f5cf6c7514fe9d` - -### PBKDF2-SHA-256 - -Test vector using AES-128-CTR and PBKDF2-SHA-256: - -File contents of `~/.web3/keystore/3198bc9c-6672-5ab3-d9954942343ae5b6.json`: -```json -{ - "crypto" : { - "cipher" : "aes-128-ctr", - "cipherparams" : { - "iv" : "6087dab2f9fdbbfaddc31a909735c1e6" - }, - "ciphertext" : "5318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46", - "kdf" : "pbkdf2", - "kdfparams" : { - "c" : 262144, - "dklen" : 32, - "prf" : "hmac-sha256", - "salt" : "ae3cd4e7013836a3df6bd7241b12db061dbe2c6785853cce422d148a624ce0bd" - }, - "mac" : "517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2" - }, - "id" : "3198bc9c-6672-5ab3-d995-4942343ae5b6", - "version" : 3 -} -``` - -Intermediates: - -- Derived key: `f06d69cdc7da0faffb1008270bca38f5e31891a3a773950e6d0fea48a7188551` -- MAC Body: `e31891a3a773950e6d0fea48a71885515318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46` -- MAC `517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2` -- Cipher key: `f06d69cdc7da0faffb1008270bca38f5` - -### Scrypt - -Test vector using AES-128-CTR and Scrypt: - -```json -{ - "crypto" : { - "cipher" : "aes-128-ctr", - "cipherparams" : { - "iv" : "83dbcc02d8ccb40e466191a123791e0e" - }, - "ciphertext" : "d172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c", - "kdf" : "scrypt", - "kdfparams" : { - "dklen" : 32, - "n" : 262144, - "r" : 1, - "p" : 8, - "salt" : "ab0c7876052600dd703518d6fc3fe8984592145b591fc8fb5c6d43190334ba19" - }, - "mac" : "2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097" - }, - "id" : "3198bc9c-6672-5ab3-d995-4942343ae5b6", - "version" : 3 -} -``` - -Intermediates: - -- Derived key: `fac192ceb5fd772906bea3e118a69e8bbb5cc24229e20d8766fd298291bba6bd` -- MAC Body `bb5cc24229e20d8766fd298291bba6bdd172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c` -- MAC: `2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097` -- Cipher key: `fac192ceb5fd772906bea3e118a69e8b` - -## Alterations from Version 1 - -This version fixes several inconsistencies with the version 1 published [here](https://github.com/ethereum/go-ethereum/wiki/Passphrase-protected-key-store-spec). In brief these are: - -- Capitalisation is unjustified and inconsistent (`scrypt` lowercase, `Kdf` mixed-case, `MAC` uppercase). -- `Address` unnecessary and compromises privacy. -- `Salt` is intrinsically a parameter of the key derivation function and deserves to be associated with it, not with the crypto in general. -- `SaltLen` unnecessary (just derive it from `Salt`). -- The key derivation function is given, yet the crypto algorithm is hard specified. -- `Version` is intrinsically numeric yet is a string (structured versioning would be possible with a string, but can be considered out of scope for a rarely changing configuration file format). -- KDF and cipher are notionally sibling concepts yet are organised differently. -- MAC is calculated through a whitespace agnostic piece of data(!) - -Changes have been made to the format to give the following file, functionally equivalent to the example given on the previously linked page: - -```json -{ - "crypto": { - "cipher": "aes-128-cbc", - "ciphertext": "07533e172414bfa50e99dba4a0ce603f654ebfa1ff46277c3e0c577fdc87f6bb4e4fe16c5a94ce6ce14cfa069821ef9b", - "cipherparams": { - "iv": "16d67ba0ce5a339ff2f07951253e6ba8" - }, - "kdf": "scrypt", - "kdfparams": { - "dklen": 32, - "n": 262144, - "p": 1, - "r": 8, - "salt": "06870e5e6a24e183a5c807bd1c43afd86d573f7db303ff4853d135cd0fd3fe91" - }, - "mac": "8ccded24da2e99a11d48cda146f9cc8213eb423e2ea0d8427f41c3be414424dd", - "version": 1 - }, - "id": "0498f19a-59db-4d54-ac95-33901b4f1870", - "version": 2 -} -``` - -## Alterations from Version 2 - -Version 2 was an early C++ implementation with a number of bugs. All essentials remain unchanged from it. \ No newline at end of file diff --git a/pages/dev-technologies/enode-url-format.md b/pages/dev-technologies/enode-url-format.md deleted file mode 100644 index 96208ce8a..000000000 --- a/pages/dev-technologies/enode-url-format.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -name: ENode URL Format -category: ---- - -An Ethereum node can be described with a URL scheme "enode". - -The hexadecimal node ID is encoded in the username portion of the URL, separated from the host by an @ sign. The hostname can only be given as an IP address, DNS domain names are not allowed. The port -in the host name section is the TCP listening port. If the TCP and UDP (discovery) ports differ, the UDP port is specified as query parameter "discport". - -In the following example, the node URL describes a node with IP address `10.3.58.6`, TCP listening port `30303` and UDP discovery port `30301`. - -``` -enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@10.3.58.6:30303?discport=30301 -``` - -The enode url scheme is used by the Node discovery protocol and can be used in the `bootnodes` command line option of the client or as the argument to `suggestPeer(nodeURL)` function in the JSRE. - -See also -- https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options -- https://github.com/ethereum/go-ethereum/wiki/JavaScript-Console diff --git a/pages/dev-technologies/libp2p-Whitepaper.md b/pages/dev-technologies/libp2p-Whitepaper.md deleted file mode 100644 index 613ee68b2..000000000 --- a/pages/dev-technologies/libp2p-Whitepaper.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -name: Lib P2P Whitepaper -category: ---- - -**NOTE:** *This is a work-in-progress* - -For Ethereum to succeed, and for the ultimate goals of Ethereum to be achieved, Ethereum needs to employ a number of secure decentralised data systems. The generalised Turing-complete, extensible-state blockchain is one component in this, but for it to be leveraged to its full potential for building decentralised applications (ÐApps), a suite of additional data systems are necessary. Each decentralised-datasystem solves specific needs; in general it is difficult to predict what data systems will ultimately be required since the decentralised paradigm is not immediately comparable, like-for-like with traditional centralised architected systems. - -Three types of data systems in particular are required for many current massively multi-user applications (MMAs, aka generally Web-based applications but also mobile phone apps and e.g. MMORPGs). In addition to a transactional database ("Ethereum"), a publication and download system would be required in addition to a generalised low-level "bulletin-board" system for posting messages. - -We can, however, imagine many more such types of decentralised communications systems in the future including, e.g., those for identity-based RTC. Each of these components have a number of shared prerequisites, such as peer-discovery and recording; network well-formedness; transport-level buffering, scheduling and framing; and authentication and security. Any computer scientist worth their salt would instantly scream out "abstraction opportunity!". - -### What it is - -libp2p (aka ÐΞVp2p) aims to provide a lightweight abstraction layer that provides these low-level algorithms, protocols and services in a transparent framework without predetermining the eventual transmission-use-cases of the protocols. - -Its specific aims are to provide a language-agnostic API and specification which is: -- *Universal:* Pairwise addressing (ala Telehash), broadcast (ala Bitcoin), groupwise (some DHT designs & filesharing) are all reasonable. There may be others. It should provide only the network structure, not dictate usage over it. -- *Ubiquitous:* The same peer-set/-network should be able to be used for all protocols. -- *Secure:* Encryption between physical peers is a given. Peer introduction can provide a good level of defence against systematic MitM attacks. -- *Efficient:* Framing and prioritisation to guarantee QoS over each protocol. Multiplexing allows access to limited resources to be easily controlled between p2p protocols. Kademlia-style network well-formedness guarantees a low maximum hope distance to any peer in the network and its group. -- *Simple:* A minimal, developer-driven API gives source-level future-proofing. - -Ultimately, additional secondary features will also be explored: -- *DPI security:* Framing and bandwidth control can be used to control traffic shape. -- *Transport-layer Agnostic:* TCP/IP v4 and v6 are provided with initial protocol specifications. Others should be able to be added on at later dates without altering the API. Mesh networking devices could even ultimately implement this natively. - -### Basic Design - -- Peers can each be identified by a node-ID. -- Provides ability *only* to communicate with peers. -- Everything happens in typed, ordered datagrams. -- Any number of datagram types can be registered - these are automatically negotiated at the handshake. -- Peers can be requested via a libp2p physical endpoint. -- Peers can be rated per-protocol using a local metric. -- Peer set is dynamic and "steered" by libp2p internally, going from ratings. -- First packets are either DH key exchange or, if node known from peer introduction, PKI-encrypted session key, or if node known from previous session, new session key encrypted by old. Retry can be made after failed negotiation using prior knowledge, with the corresponding removal of any trust. -- Peer-set is made up from multiple sub-protocol slots. -- Each slot is given over to maximise rating for that particular sub-protocol. - -There is no preordained inter-node message routing system (this is left to a higher-level), and no preordained high-level identity system (again, higher level). diff --git a/pages/dev-technologies/web.js-0.9.md b/pages/dev-technologies/web.js-0.9.md deleted file mode 100644 index ad77e2330..000000000 --- a/pages/dev-technologies/web.js-0.9.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -name: Web.js 0.9 -category: ---- - -Web3.js 0.9 changes - -I would like to apply KISS principle to web3.js. I used the library recently much more and I realised that we are doing to many things implicitly. eg: - -1, newFilter it should either get all logs or poll for new logs. It shouldn't do both in the same time. In my story, I don't want to poll for filter changes, but I want to get all logs between block X and Y. Same as caktux here: https://github.com/ethereum/web3.js/issues/250 - - examples of new solution - - 1st. - - ``` -var x = web3.eth.filter(...); // sync: eth_newFilter -x.watch(function (err, log) { // async poll: eth_getFilterChanges - -}) - ``` - - - 2nd. - - - ``` -web3.eth.filter(..., function (err, x) { // async: eth_newFilter - x.watch(function (err, log) { // async poll: eth_getFilterChanges - - }) -}) - - ``` - - 3rd. - - - ``` -var x = web3.eth.filter(...) // sync: eth_newFilter -var logs = x.logs(); // sync: eth_getFilterLogs - ``` - - 4th. - ``` -var x = web3.eth.filter(...) // sync: eth_newFilter -var logs = x.logs(function (err, logs) { // sync: eth_getFilterLogs - -} - ``` diff --git "a/pages/dev-technologies/\303\220\316\236Vp2p-Wire-Protocol.md" "b/pages/dev-technologies/\303\220\316\236Vp2p-Wire-Protocol.md" deleted file mode 100644 index 4ac80109d..000000000 --- "a/pages/dev-technologies/\303\220\316\236Vp2p-Wire-Protocol.md" +++ /dev/null @@ -1,90 +0,0 @@ ---- -name: DEV P2P Wire Protocol -category: ---- - -Peer-to-peer communications between nodes running Ethereum/Whisper/&c. clients are designed to be governed by a simple wire-protocol making use of existing ÐΞV technologies and standards such as [RLP](https://github.com/ethereum/wiki/wiki/RLP) wherever practical. - -This document is intended to specify this protocol comprehensively. - -### Low-Level - -ÐΞVp2p nodes may connect to each other over TCP only. Peers are free to advertise and accept connections on any port(s) they wish, however, a default port on which the connection may be listened and made will be 30303. - -Though TCP provides a connection-oriented medium, ÐΞVp2p nodes communicate in terms of packets. These packets are formed as a 4-byte synchronisation token (0x22400891), a 4-byte "payload size", to be interpreted as a big-endian integer and finally an N-byte RLP-serialised data structure, where N is the aforementioned "payload size". To be clear, the payload size specifies the number of bytes in the packet ''following'' the first 8. - -### Payload Contents - -There are a number of different types of payload that may be encoded within the RLP. This ''type'' is always determined by the first entry of the RLP, interpreted as an integer. - -ÐΞVp2p is designed to support arbitrary sub-protocols (aka _capabilities_) over the basic wire protocol. Each sub-protocol is given as much of the message-ID space as it needs (all such protocols must statically specify how many message IDs they require). On connection and reception of the `Hello` message, both peers have equivalent information about what subprotocols they share (including versions) and are able to form consensus over the composition of message ID space. - -Message IDs are assumed to be compact from ID 0x10 onwards (0x00-0x10 is reserved for ÐΞVp2p messages) and given to each shared (equal-version, equal name) sub-protocol in alphabetic order. Sub-protocols that are not shared are ignored. If multiple versions are shared of the same (equal name) sub-protocol, the numerically highest wins, others are ignored. - -### P2P - -**Hello** -[`0x00`: `P`, `p2pVersion`: `P`, `clientId`: `B`, [[`cap1`: `B_3`, `capVersion1`: `P`], [`cap2`: `B_3`, `capVersion2`: `P`], `...`], `listenPort`: `P`, `nodeId`: `B_64`] First packet sent over the connection, and sent once by both sides. No other messages may be sent until a Hello is received. -* `p2pVersion` Specifies the implemented version of the P2P protocol. Now must be 1. -* `clientId` Specifies the client software identity, as a human-readable string (e.g. "Ethereum(++)/1.0.0"). -* `cap` Specifies a peer capability name as a length-3 ASCII string. Current supported capabilities are `eth`, `shh`. -* `capVersion` Specifies a peer capability version as a positive integer. Current supported versions are 34 for `eth`, and 1 for `shh`. -* `listenPort` specifies the port that the client is listening on (on the interface that the present connection traverses). If 0 it indicates the client is not listening. -* `nodeId` is the Unique Identity of the node and specifies a 512-bit hash that identifies this node. - -**Disconnect** -[`0x01`: `P`, `reason`: `P`] Inform the peer that a disconnection is imminent; if received, a peer should disconnect immediately. When sending, well-behaved hosts give their peers a fighting chance (read: wait 2 seconds) to disconnect to before disconnecting themselves. -* `reason` is an optional integer specifying one of a number of reasons for disconnect: - * `0x00` Disconnect requested; - * `0x01` TCP sub-system error; - * `0x02` Breach of protocol, e.g. a malformed message, bad RLP, incorrect magic number &c.; - * `0x03` Useless peer; - * `0x04` Too many peers; - * `0x05` Already connected; - * `0x06` Incompatible P2P protocol version; - * `0x07` Null node identity received - this is automatically invalid; - * `0x08` Client quitting; - * `0x09` Unexpected identity (i.e. a different identity to a previous connection/what a trusted peer told us). - * `0x0a` Identity is the same as this node (i.e. connected to itself); - * `0x0b` Timeout on receiving a message (i.e. nothing received since sending last ping); - * `0x10` Some other reason specific to a subprotocol. - -**Ping** -[`0x02`: `P`] Requests an immediate reply of `Pong` from the peer. - -**Pong** -[`0x03`: `P`] Reply to peer's `Ping` packet. - -**NotImplemented (was GetPeers)** -[`0x04`: `...`] - -**NotImplemented (was Peers)** -[`0x05`: `...`] - -### Node identity and reputation - -In a later version of this protocol, node ID will become the public key. Nodes will have to demonstrate ownership over their ID by interpreting a packet encrypted with their node ID (or perhaps signing a random nonce with their private key). - -A proof-of-work may be associated with the node ID through the big-endian magnitude of the public key. Nodes with a great proof-of-work (public key of lower magnitude) may be given preference since it is less likely that the node will alter its ID later or masquerade under multiple IDs. - -Nodes are free to store ratings for given IDs (how useful the node has been in the past) and give preference accordingly. Nodes may also track node IDs (and their provenance) in order to help determine potential man-in-the-middle attacks. - -Clients are free to mark down new nodes and use the node ID as a means of determining a node's reputation. In a future version of this wire protocol, n - -### Example Packets - -`0x22400891000000088400000043414243` - -A Hello packet specifying the client id is "ABC". - -Peer 1: `0x22400891000000028102` - -Peer 2: `0x22400891000000028103` - -A Ping and the returned Pong. - -### Session Management - -Upon connecting, all clients (i.e. both sides of the connection) must send a `Hello` message. Upon receiving the `Hello` message and verifying compatibility of the network and versions, a session is active and any other P2P messages may be sent. - -At any time, a Disconnect message may be sent. \ No newline at end of file diff --git a/pages/eip/Geth-Dapp-loading-proposal.md b/pages/eip/Geth-Dapp-loading-proposal.md deleted file mode 100644 index a24ca2799..000000000 --- a/pages/eip/Geth-Dapp-loading-proposal.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -name: Geth DAPP Loading Proposal -category: ---- - -To have a simple way to load and start Dapps vinay and I came up with a great idea: - -1. Dapp packages can be downloaded as .zip/.rlp/.dapp - - they will contain a `dapp.json` with author info and a dapp name and version. - - and a `swarm.json`, with all the file paths and hashes, [see here](https://github.com/ethereum/go-ethereum/wiki/URL-Scheme#server-config-examples)) - -2. run `$ geth install mydapp.zip`, which will verify, extract and copy the dapp locally somewhere. -**Note** This could also get a name reg domain and looks up the hash an content online, fetches it and installs it. - -3. run `$ geth start mydapp` will start a node, with the correct options (rpc, corsdomain etc) and start a local server which points with its root into the dapps folder and resolves path and files through the `swarm.json` - -4. goto `http://localhost:5555` to see you dapp running (needs to be thought of, as dapps would share localstorage, maybe use a different and reusable port per dapp) - -## Update - -- run `$ geth update mydapp.zip`, which will extract, and overwrites the old dapp files - -## Bundle dapp - -- run `$ geth bundle myDappFolder/dist/`, which will create a dapp bundle from a folder, to share with others. - -- run `$ geth deploy myDappFolder/dist/` could save it to pastebin and register it in namereg. diff --git a/pages/eip/JSON-RPC-Error-Codes-Improvement-Proposal.md b/pages/eip/JSON-RPC-Error-Codes-Improvement-Proposal.md deleted file mode 100644 index ad45ac86b..000000000 --- a/pages/eip/JSON-RPC-Error-Codes-Improvement-Proposal.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -name: JSON RPC Error Codes Improvement Proposal -category: ---- - -To help developers add proper error handling in the dapp side, we need to implement custom error codes for the returned JSON RPC errors. - -## JSON RPC Standard errors - -| Code | Possible Return message | Description | -| --------|-------------------------|-------------| -|-32700 | Parse error | Invalid JSON was received by the server. An error occurred on the server while parsing the JSON text. | -|-32600 | Invalid Request | The JSON sent is not a valid Request object. | -|-32601 | Method not found | The method does not exist / is not available. | -|-32602 | Invalid params | Invalid method parameter(s). | -|-32603 | Internal error | Internal JSON-RPC error. | -|-32000 to -32099 | `Server error`. Reserved for implementation-defined server-errors. | - -## Custom error codes: - -| Code | Possible Return message | Description | -| --------|-------------------------|-------------| -|1 | Unauthorized | Should be used when some action is not authorized, e.g. sending from a locked account. -|2 | Action not allowed | Should be used when some action is not allowed, e.g. preventing an action, while another depending action is processing on, like sending again when a confirmation popup is shown to the user (?). -|3 | Execution error | Will contain a subset of custom errors in the data field. See below. | - -### Custom error fields - -Custom error `3` can contain custom error(s) to further explain what went wrong. -They will be contained in the `data` field of the RPC error message as follows: - -```js -{ - code: 3, - message: 'Execution error', - data: [{ - code: 102, - message: 'Innsufficient gas', - reason: 'GAS' - }, - { - code: 103, - message: 'Gas limit exceeded', - reason: 'GAS' - }] -} -``` - -| Code | Reson values | Possible Return message | Description | -| --------|--------------|-------------------------|-------------| -|100 | ? | X doesn't exist | Should be used when something which should be there is not found. (Doesn't apply for not found transactions or blocks. They return a success with value `null`) -|101 | `ETHER` ? | Requires X | Should be used for actions which require somethin else, e.g. gas or a value. -|102 | `GAS`, `ETHER` | X to low | Should be used when a to low value of something was given, e.g. an to low gas amount. -|103 | `GAS` | X limit exceeded | Should be used when a limit is exceeded, e.g. for the gas limit in a block. -|104 | `CODE` ? | Rejected | Should be used when an action was rejected, e.g. because of its content (to long contract code, containing wrong characters ?, should differ from `-32602` - Invalid params). - - -## Possible future error codes? - -| Code | Possible Return message | Description | -| --------|-------------------------|-------------| -|105 | Timeout | Should be used when an action timedout. -|106 | Conflict | Should be used when an action conflicts with another (ongoing?) action. \ No newline at end of file diff --git a/pages/eip/Mix-improvement-proposal.md b/pages/eip/Mix-improvement-proposal.md deleted file mode 100644 index 2eb055a4b..000000000 --- a/pages/eip/Mix-improvement-proposal.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -name: Mix Improvement Proposal -category: ---- - -how it currently looks, its working well for very simple scripts, but its hard to impossible to use for any advanced javascript application, using require.js, common.js, bower, npm, angualr.js, ember, canjs, meteor or any more advanced js framework. As the current deploy method forces you to do things in a simplistic way (linking ethereum.js, contracts files and add the contract variable) - -This also makes it hard to test your application as the deploy process is the one, which uploads the contracts as well and nobody want to deploy its app and contracts without being able to thoroughly test them on the main/test net beforehand. - -Additionally not all dapps use one or more contracts, but might want to deploy contracts on the fly (like the wallet dapp) and need a simple way to get the compiled contract code. - -So here a re my suggestions: - -- Deploy should only deploy the app files (with the possibility to choose a to-deploy-folder), and can include the automated name reg stuff as well - -- contracts should be deployed by right clicking them -> deploy contract, which then asks where to deploy (testnet, mainnet) and gives back the ABI and address (maybe in a `myContract-deployed.js`) - -- contracts should also be compiled with right click -> compile contract, giving the compiled HEX string and ABI in an `myContract-compiled.js` (or just use one `myContract-mix.js`) - -- the files in the sidebar should show the folder structure and not sort by type, as any advanced js application needs more than just an index.html and js file. (folders are good ;) - -- the deployable file should be zip, not rlp so people can unpack it easily and discover the content which will be deployed. This also allows to understand it and write separate bundle scripts for them. **(But, might anyway become obsolete with swarm)** - -I think this improvements, will allow for greater flexibility without compromising the use of mix. \ No newline at end of file diff --git a/pages/eip/Proposal:-BlockHashesFromNumbers.md b/pages/eip/Proposal:-BlockHashesFromNumbers.md deleted file mode 100644 index f67fbc158..000000000 --- a/pages/eip/Proposal:-BlockHashesFromNumbers.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: BlockHashesFromNumbers Proposal -category: ---- - -# Problem - -During initial synchronization to a large blockchain downloading block hashes can take significant time. Current protocol does not allow parallel hashes downloading. Hashes can be requested sequentially up the chain, making it impossible to start blocks downloading until all of the hashes up to the known hash or genesis are received. A malicious peer can feed an infinite hash chain. Currently it is not straightforward to protect against such an attack as there is no additional information on the number of hashes. The only strategy is to estimate a reasonable number of hashes using current date, genesis date and average block time, and then reject the peer after downloading that many hashes. - -# Solution - -There should be a way to request a list of hashes by the block number. This will allow parallel downloading, starting block downloading and validation immediately after receiving first hashes, rejecting malicious peers right away. - -# Specification - -1. Introduce a new packet: `BlockHashesFromNumber`, into the slot `+0x08` (new). - -**BlockHashesFromNumber** -[`+0x08`: `P`, `number`: `P`, `maxBlocks`: `P`] -Requests a BlockHashes message detailing a number of the first block hash and a total of hashes to be sent. Returned hash list must be ordered by block number in ascending order. diff --git a/pages/eip/Proposal:-Extend-GetBlockHashes-with-target-hash.md b/pages/eip/Proposal:-Extend-GetBlockHashes-with-target-hash.md deleted file mode 100644 index c5758e84b..000000000 --- a/pages/eip/Proposal:-Extend-GetBlockHashes-with-target-hash.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -name: Extend GetBlockHashes With Target Hash Proposal -category: ---- - -# Problem - -The current protocol specification does not provide the means to mitigate an infinite chain feeding attack. A malicious peer can make up arbitrary blocks on the fly, and feed their hashes indefinitely to a target, without ever linking to the existing chain. This will result in an eventual memory exhaustion and crash. The root cause is that the protocol provides no means to validate any blocks, without first pulling the entire hash chain. - -# Solution - -Peers should be able to request hashes not only backwards towards the genesis block, but forward too to some specific target hash. This would allow the downloader to start pulling actual blocks and verify them concurrently with fetching the hashes. If no peers (including the hash provider) has the blocks to back up the hashes, the chain is rejected. - -This forward synchronization strategy requires the capacity to locate a common ancestor block to our blockchain and that of a remote peer in order to know the joining point from which to request the hashes. This can be facilitated with the same mechanism by doing a binary search on our blockchain, requesting 1xhashes from the remote (towards its advertised head) side to see if it knows about it or not, honing in on the common ancestor. - -# Specification - -1. Extend `GetBlockHashes` packet with an additional field: - - **GetBlockHashes** [`+0x03`: `P`, `srcHash`: `B_32`, `targetHash`: `B_32`, `maxBlocks`: `P`] - * `targetHash`: The endpoint in a remote blockchain towards which to retrieve hashes - -2. Modify `BlockHashes`'s returned hash order: - - * Adhere to that requested by `GetBlockHashes`, opposed to the current "hard coded" young -> old ordering - -The benefit of this proposal is that beside providing the means to do forward syncing, it retains the capacity to implement the currently specified reverse fetch behavior by passing the genesis block's hash to `targetHash`. This way Ethereum implementations don't have to immediately devise a new downloader strategy to cope with the update, but can function as they are until ready to evolve. - -# Supersedes - -[[Proposal: BlockHashesFromNumbers]] - -The main issue the `BlockHashesFromNumbers` set out to resolve was the slow download of hashes (which was stalling the synchronization), by introducing parallel fetches based on height/block-number based hash retrievals. It also inherently provided a mechanism to limit the number of potentially invalid hashes downloaded to that of the current chain's height. - -The current proposal however approaches the challenge from the opposite direction. By downloading hashes towards the end of a chain - after the first hash delivery - blocks can be immediately retrieved in parallel (compared to which hash downloads are insignificant in size and hence latency), so there is no need for the added complexity and potential issues with parallelizing hash downloads. Additionally, by limiting the number of pending hashes, we can also prevent any infinite chain attacks. - -Given that the current proposal addresses all of the issues `BlockHashesFromNumbers` aimed to fix, while being much less invasive (requires the addition of single packet field); is gracefully compatible with previous protocol implementations (they can continue to function without an algorithm update); and implementation wise is straightforward and easy to reason about; we believe it is a superior proposal. - -### Critique - -- Closer to the present protocol than `BlockHashesFromNumbers`. -- Less general and expansive than `BlockHashesFromNumbers`: it is designed for a very particular strategy and is less likely to be adaptable to future, unknown strategies. -- Does not support parallel hash-chain downloading alongside forward hash-chain downloading (`BlockHashesFromNumbers` supports both). -- Somewhat more complex in terms of semantics: - - The notion of a series of hash going from a source hash to a destination hash is found nowhere else in the protocol or codebase. Exchanging number to/from hash is already found in the API. - - Not immediately clear with edge cases (e.g. if from is genesis and to is leaf, or if from doesn't exist in the chain but leaf does, or vice-versa). `BlockHashesFromNumbers` is well-defined under all circumstances. -- Somewhat more complex in terms of implementation; how to efficiently determine the fork point or common ancestor? `BlockHashesFromNumbers` would make it trivial with a binary chop. diff --git a/pages/eip/Proposal:-NewBlockHashes.md b/pages/eip/Proposal:-NewBlockHashes.md deleted file mode 100644 index 83ebdf613..000000000 --- a/pages/eip/Proposal:-NewBlockHashes.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -name: NewBlockHashes Proposal -category: ---- - -# Problem - -Block propagation is slow. This is partly due to the problematic strategy decision of either sending out a new block to all peers (costly in terms of bandwidth, especially when considered at the network level where most nodes will receive a block from most of their peers) or send a new block to a randomly selected subset of peers (making worst-case propagation times substantial). - -# Solution - -Much better would be a low-bandwidth full propagation of the hash. All nodes would receive a hash for each new block from most of their peers (peers who have demonstrated knowledge of the hash would not be notified). However, the block itself would need only be transferred once per node. - -# Specification - -Introduce a new packet: `NewBlockHashes`, into the slot `+0x01` (original taken by `GetTransactions`, which is not defunct). - -**NewBlockHashes** -[`+0x01`: `P`, `hash1`: `B_32`, `hash2`: `B_32`, `...`] Specify one or more new blocks which have appeared on the network. Including hashes that the sending peer could reasonable be considered to know that the receiving node is aware of is considered Bad Form, and may reduce the reputation of the sending node. Including hashes that the sending node later refuses to honour with a proceeding `GetBlocks` message is considered Bad Form, and may reduce the reputation of the sending node. - - diff --git a/pages/eip/Proposal:-Reversion-Notification.md b/pages/eip/Proposal:-Reversion-Notification.md deleted file mode 100644 index ecff74482..000000000 --- a/pages/eip/Proposal:-Reversion-Notification.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -name: Reversion Notification Proposal -category: ---- - -## **JSONRPC** changes: - -`eth_getFilterChanges`, `eth_getFilterLogs` both return additional fields: "type" and "polarity" - -- `type`: `STRING` - `pending` when the log is pending. `mined` if log is already mined. -- `polarity`:`BOOL` - either `true` (the transaction pertaining to this log was mined or arrived as pending compared to the previous notification/notified block) or `false` (the transaction pertaining to this log was reverted or was deleted compared to the previous notification/notified block). - -```diff -// Result -{ - "id":1, - "jsonrpc":"2.0", - "result": [{ - "logIndex": "0x1", // 1 - "blockNumber":"0x1b4" // 436 - "blockHash": "0x8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcfdf829c5a142f1fccd7d", - "transactionHash": "0xdf829c5a142f1fccd7d8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcf", - "transactionIndex": "0x0", // 0 - "address": "0x16c5785ac562ff41e2dcfdf829c5a142f1fccd7d", - "data":"0x0000000000000000000000000000000000000000000000000000000000000000", -+ "type":"mined", -+ "polarity": true, - "topics": ["0x59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a5"] - },{ - ... - }] -} -``` - -- logs order - -logs should be returned in order, from earliest to latest. - -In case of fork, the order should be following: - -``` -// -// ......1 - 2 - 3a - 4a -// ...............\- 3b - 4b - 5b -// -// getLogs({fromBlock: 4a, toBlock: 5b}) should return -// 4a, 3a, 3b, 4b, 5b -// -``` - - - -## **JSONRPC** new methods: - -- `eth_newFilterEx` (new version of `eth_newFilter`) -- `eth_getLogsEx` (new version of `eth_getLogs`) - -They expect 'fromBlock', 'toBlock' to be block hash instead of block number. - -```diff -params: [{ -- "fromBlock": "0x1", -+ "fromBlock": "0x599438826541d3e8c29c167fa15b491d91b65e422f8b8a3da69eaa9a43c832e1", -- "toBlock": "0x2", -+ "toBlock": "0x599438826541d3e8c29c167fa15b491d91b65e422f8b8a3da69eaa9a43c832e1", - "address": "0x8888f1f195afa192cfee860698584c030f4c9db1", - "topics": ["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b"] -}] -``` - -- `eth_getFilterChangesEx` (new version of `eth_getFilterChanges`) -- `eth_getFilterLogsEx` (new version of `eth_getFilterLogs`) - -`eth_getFilterChangesEx` && `eth_getFilterLogsEx` have the same input params as `eth_getFilterChanges` && `eth_getFilterLogs`, but different format of returned objects. - -``` -// Result -{ - "id":1, - "jsonrpc":"2.0", - "result": [{ - "blockNumber":"0x1b4" // 436 - "blockHash": "0x8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcfdf829c5a142f1fccd7d", - "type": "pending", - "polarity": true, - "logs": [{ - "logIndex": "0x1", // 1 - "transactionHash": "0xdf829c5a142f1fccd7d8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcf", - "transactionIndex": "0x0", // 0 - "address": "0x16c5785ac562ff41e2dcfdf829c5a142f1fccd7d", - "data":"0x0000000000000000000000000000000000000000000000000000000000000000", - "topics": ["0x59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a5"] - },{ - ... - }], - },{ - ... - }] -} -``` - - -## Comments: - -**Fabian**: I like it but i would change three things: - -1. `polarity: true` -> `invalidated: true` or `invalid: true` -2. get rid of the old filter and add `eth_newFilterEx` as `eth_newLogFilter`, to make it fit the other filter type names (`eth_newBlockFilter`, `etH_newPendingTransactionFilter`) -3. Don't return logs grouped by blocks, as i don't see an advantage besides that it is harder to parse. (Logs don't really care in which block they came, though we need to add the `blockX` properties for reference) \ No newline at end of file diff --git a/pages/eip/Proposal:-Transaction-Proxy-Hooks.md b/pages/eip/Proposal:-Transaction-Proxy-Hooks.md deleted file mode 100644 index 09e59b2eb..000000000 --- a/pages/eip/Proposal:-Transaction-Proxy-Hooks.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -name: Transaction Proxy Hooks Proposal -category: ---- - -## Requirements - -Need an abstraction mechanism to allow ÐApps like the Wallet provide their services in an integrated manner without compromising the neutrality of the browser or placing undue burden on third-party ÐApp developers to support them. - -## Basic Design - -The ethereum.js interface may be utilised to allow the ÐApp client to register itself as the transaction handler for each of a number of accounts; in doing so it will provide an additional callback. - -This is done through one addition to the ethereum.js `web3.eth` object, `registerProxyTransactor`: - -``` -var addresses = []; -// TODO: populate addresses - -function f(tx) { - // tx includes tx.from, tx.to, tx.data, tx.value, tx.gasPrice, tx.gas - // and is *exactly* the same as what was passed to eth.transact, but probably not in this - // JS environment. - // tx.from is guaranteed to be an element of addresses. - // TODO: do something -} - -web3.eth.registerProxyTransactor(addresses, f); -``` - -That's the entire JS API. - -In terms of JSON-RPC, there must be an alteration to `eth_accounts`: rather than just including the accounts that we have the secret key for (and that the user has accepted are valid for this dapp to use and know about), all accounts passed as the first argument to `registerProxyTransactor` should also be contained (with the same safeguards as per user acceptance). - -There are also two additional calls in the JSON-RPC; one for polling the status of whether any transactions are waiting to be signed by our callback that we registered as the second argument of `registerProxyTransactor`, and one for letting the core know that our ethereum.js object is capable of proxying transactions sent from the addresses passed as the first argument of `registerProxyTransactor`. - -The first is `eth_registerAddressHandler`; it takes one argument which is an array of addresses and returns an integer identifier. Any otherwise unsignable transactions whose from address is included in this array should be, at some time later, returned to this session as a result of polling the RPC function `eth_checkProxyTransactions`. - -`eth_checkProxyTransactions` takes one argument - the previous integer identifier and returns an array of transactions, each of the form that are passed to `web3.eth.transact`. - -### Core - -Cores must maintain queues of proxy transactions together with sets of addresses, one each per ethereum.js `web3.eth` object (identified through the integer returned to `eth_registerAddressHandler` and provided by `eth_checkProxyTransactions`). These transactions are to be returned to the session via `eth_checkProxyTransactions`. They are to be filled whenever an `eth_transact` is called (from any session) with a `from` address that is contained in the corresponding set of proxyable addresses. - - -### Notes - -If it's called twice, all previous state associated with it is replaced. If two ethereum.js `web3.eth` objects both try to handle the same address, the first one wins and the second silently fails. - -NatSpec messages should be shown for all transactions, ideally only a single ultimate user action required for any given high-level transaction. E.g.: - -- Send 56 ether to `Dave - 0x56789123` from account `Gav's Bank Account - 0x12345678`. -- Wallet ÐApp handling account `Gav's Bank Account - 0x12345678` requests authorisation to conduct the above through: Message from `Gav - 0x34343455` to `Gav's Bank Account - 0x12345678` to: Send 56 ether to `Dave - 0x56789123`. - -The first NatSpec line just corresponds to the first bare and impossible-to-sign transaction from a contract. The second is the actual transaction that will be signed, stating that Gav (the account for which we have a secret key), would sign a transaction instructing the wallet to send the funds. \ No newline at end of file diff --git a/pages/eip/newBlockFilter-Improvement-Proposal.md b/pages/eip/newBlockFilter-Improvement-Proposal.md deleted file mode 100644 index 7cdfe93de..000000000 --- a/pages/eip/newBlockFilter-Improvement-Proposal.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -name: NewBlockFilter Improvement Proposal -category: ---- - -Currently a filter created with `eth_newBlockFilter` and call `eth_getFilterLogs`, or `get_filterChanges` should return `[null]` or `[null, null,...]` If multiple blocks came in since the last poll. - -Thats fine as you can check for the current block e.g. using: - -```js -web3.eth.filter('latest').watch(function(err, res){ - // i can get the current block here - web3.eth.getBlock('latest'); -}); -``` - -The problem is that when a lot of blocks came in since the last time you polled with a return of `[null, null, null, ...]`, your callback will fire multiple times accordingly, but using `eth.getBlock` inside will always give me the latest block, which is actually wrong. - - - -# New Proposal - -After discussing with Gavin we came up with the following improvement: - -```js -// eth_newBlockFilter will receive no parameter -{"jsonrpc":"2.0","method":"eth_newBlockFilter","params":[],"id":529} - -// poll -{"jsonrpc":"2.0","method":"eth_getFilterChanges","params":["0xb"],"id":530} // we assume the filter ID is "0xb" - -// should return one or more blocks, -// depending on how much arrived since the last poll -{ - "id": 530, - "jsonrpc": "2.0", - "result": ['0x234234234..','0x342342342..'] // block hashes of the incoming blocks - } -``` - -```js -// eth_newPendingTransactionFilter will receive no parameter -{"jsonrpc":"2.0","method":"eth_newPendingTransactionFilter","params":[],"id":529} - -// poll -{"jsonrpc":"2.0","method":"eth_getFilterChanges","params":["0xb"],"id":530} // we assume the filter ID is "0xb" - -// should return one or more pending transactions, -// which were added to the pending state since the last poll -{ - "id": 530, - "jsonrpc": "2.0", - "result": ['0x234234234..','0x342342342..'] // tx hashes of new pending transactions - } -``` - -**Note** This requires that `eth_getTransactionByHash` also return pending transactions! \ No newline at end of file diff --git a/pages/eip/sendTransaction-return-value-proposal.md b/pages/eip/sendTransaction-return-value-proposal.md deleted file mode 100644 index 0a4b21de0..000000000 --- a/pages/eip/sendTransaction-return-value-proposal.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -name: SendTransaction Return Value Proposal -category: ---- - -After talking to Marek we came to the conclusion, that the current return value of `eth_sendTransaction` is not enough to be able to work with self send transactions. - -If you send a contract creation transaction, you get the contract address back, but not the transaction hash. - -Additional with the new proposal, we could even let non-constant contract functions return values, like gavin wanted to do it in https://github.com/ethereum/dapp-bin/blob/master/wallet/wallet2.sol#L237 (Currently thats impossible and that contract would be wrong) - -## Proposal - -Instead of returning the hash or a contract address lets return a object contain everything: - -```js -{ - transactionHash: '0x234567..', - contractAddress: '0x123456' // or null - returnValue: '0x342567' // or null -} -``` \ No newline at end of file diff --git a/pages/ethash-dagger-hashimoto/Dagger-Hashimoto.md b/pages/ethash-dagger-hashimoto/Dagger-Hashimoto.md deleted file mode 100644 index 680e23845..000000000 --- a/pages/ethash-dagger-hashimoto/Dagger-Hashimoto.md +++ /dev/null @@ -1,338 +0,0 @@ ---- -name: Dagger Hashimoto -category: ---- - -## Introduction - -Dagger Hashimoto is a proposed spec for the mining algorithm for Ethereum 1.0. Dagger Hashimoto aims to simultaneously satisfy two goals: - -1. **ASIC-resistance**: the benefit from creating specialized hardware for the algorithm should be as small as possible, ideally to the point that even in an economy where ASICs have been developed the speedup is sufficiently small that it is still marginally profitable for users on ordinary computers to mine with spare CPU power. -2. **Light client verifiability**: a block should be relatively efficiently verifiable by a light client. - -With an additional modification, we also specify how to fulfill a third goal if desired, but at the cost of additional complexity: - -3. **Full chain storage**: mining should require storage of the complete blockchain state (due to the irregular structure of the Ethereum state trie, we anticipate that some pruning will be possible, particularly of some often-used contracts, but we want to minimize this). - -Dagger Hashimoto builds on two key pieces of previous work: - -* [Hashimoto](http://vaurum.com/hashimoto.pdf), an algorithm by Thaddeus Dryja which intends to achieve ASIC resistance by being IO-bound, ie. making memory reads the limiting factor in the mining process. The theory is that RAM is in principle inherently a much more generic ingredient than computation, and billions of dollars of research already go into optimizing it for different use cases which often involve near-random access patterns (hence "random access memory"); hence, existing RAM is likely to be moderately close to optimal for evaluating the algorithm. Hashimoto uses the blockchain as a source of data, simultaneously satisfying (1) and (3) above. -* [Dagger](http://vitalik.ca/ethereum/dagger.html), an algorithm by Vitalik Buterin which uses directed acyclic graphs to simultaneously achieve memory-hard computation but memory-easy validation. The core principle is that each individual nonce only requires a small portion of a large total data tree, and recomputing the subtree for each nonce is prohibitive for mining - hence the need to store the tree - but okay for a single nonce's worth of verification. Dagger was meant to be an alternative to existing memory-hard algorithms like [Scrypt](http://en.wikipedia.org/wiki/Scrypt), which are memory-hard but are also very hard to verify when their memory-hardness is increased to genuinely secure levels. However, Dagger was proven to be vulnerable to shared memory hardware acceleration [by Sergio Lerner](https://bitslog.wordpress.com/2014/01/17/ethereum-dagger-pow-is-flawed/) and was then dropped in favor of other avenues of research. - -Approaches that were tried between Dagger and Dagger Hashimoto but are currently not our primary focus include: - -* "Blockchain-based proof of work" - a proof of work function that involves running contracts taken from the blockchain. The approach was abandoned because it was long-range attack vulnerabilities, since attackers can create forks and populate them with contracts that they have a secret fast "trapdoor" execution mechanism for. -* "Random circuit" - a proof of work function developed largely by Vlad Zamfir that involves generating a new program every 1000 nonces - essentially, choosing a new hash function each time, faster than even FPGAs can reconfigure. The approach was temporarily put aside because it was difficult to see what mechanism one can use to generate random programs that would be general enough so that specialization gains would be low; however, we see no fundamental reasons why the concept cannot be made to work. - -The difference between Dagger Hashimoto and Hashimoto is that, instead of using the blockchain as a data source, Dagger Hashimoto uses a custom-generated 1 GB data set, which updates based on block data every N blocks. The data set is generated using the Dagger algorithm, allowing for the efficient calculation of a subset specific to every nonce for the light client verification algorithm. The difference between Dagger Hashimoto and Dagger is that, unlike in the original Dagger, the dataset used to query the block is semi-permanent, only being updated at occasional intervals (eg. once per week). This means that the portion of the effort that goes toward generating the dataset is close to zero, so Sergio Lerner's arguments regarding shared memory speedups become negligible. - -## DAG Generation - -The code for the algorithm will be defined in Python below. First, we give `encode_int` for marshaling unsigned ints of specified precision to strings. Its inverse is also given: - -```python -NUM_BITS = 512 - -def encode_int(x): - "Encode an integer x as a string of 64 characters using a big-endian scheme" - o = '' - for _ in range(NUM_BITS / 8): - o = chr(x % 256) + o - x //= 256 - return o - -def decode_int(s): - "Unencode an integer x from a string using a big-endian scheme" - x = 0 - for c in s: - x *= 256 - x += ord(c) - return x -``` - -We next assume that `sha3` is a function that takes an integer and outputs an integer, and `dbl_sha3` is a double-sha3 function; if converting this reference code into an implementation use: - -```python -from pyethereum import utils -def sha3(x): - if isinstance(x, (int, long)): - x = encode_int(x) - return decode_int(utils.sha3(x)) - -def dbl_sha3(x): - if isinstance(x, (int, long)): - x = encode_int(x) - return decode_int(utils.sha3(utils.sha3(x))) -``` - -### Parameters - -The parameters used for the algorithm are: - -```python -SAFE_PRIME_512 = 2**512 - 38117 # Largest Safe Prime less than 2**512 - -params = { - "n": 4000055296 * 8 // NUM_BITS, # Size of the dataset (4 Gigabytes); MUST BE MULTIPLE OF 65536 - "n_inc": 65536, # Increment in value of n per period; MUST BE MULTIPLE OF 65536 - # with epochtime=20000 gives 882 MB growth per year - "cache_size": 2500, # Size of the light client's cache (can be chosen by light - # client; not part of the algo spec) - "diff": 2**14, # Difficulty (adjusted during block evaluation) - "epochtime": 100000, # Length of an epoch in blocks (how often the dataset is updated) - "k": 1, # Number of parents of a node - "w": w, # Used for modular exponentiation hashing - "accesses": 200, # Number of dataset accesses during hashimoto - "P": SAFE_PRIME_512 # Safe Prime for hashing and random number generation -} -``` - -`P` in this case is a prime chosen such that `log₂(P)` is just slightly less than 512, which corresponds to the 512 bits we have been using to represent our numbers. Note that only the latter half of the DAG actually needs to be stored, so the de-facto RAM requirement starts off at 1 GB and grows by 441 MB per year. - -### Dagger graph building - -The dagger graph building primitive is defined as follows: - -```python -def produce_dag(params, seed, length): - P = params["P"] - picker = init = pow(sha3(seed), params["w"], P) - o = [init] - for i in range(1, length): - x = picker = (picker * init) % P - for _ in range(params["k"]): - x ^= o[x % i] - o.append(pow(x, params["w"], P)) - return o -``` - -Essentially, it starts off a graph as a single node, `sha3(seed)`, and from there starts sequentially adding on other nodes based on random previous nodes. When a new node is created, a modular power of the seed is computed to randomly select some indices less than `i` (using `x % i` above), and the values of the nodes at those indices are used in a calculation to generate a new a value for `x`, which is then fed into a small proof of work function (based on XOR) to ultimately generate the value of the graph at index `i`. The rationale behind this particular design is to force sequential access of the DAG; the next value of the DAG that will be accessed cannot be determined until the current value is known. Finally, modular exponentiation is used to further hash the result. - -This algorithm relies on several results from number theory. See the appendix below for a discussion. - -## Light Client Evaluation - -The intent of the above graph construction is to allow each individual node in the graph can be reconstructed by computing a subtree of only a small number of nodes, and requiring only a small amount of auxiliary memory. Note that with k=1, the subtree is only a chain of values going up to the first element in the DAG. - -The light client computing function for the DAG works as follows: - -```python -def quick_calc(params, seed, p): - w, P = params["w"], params["P"] - cache = {} - - def quick_calc_cached(p): - if p in cache: - pass - elif p == 0: - cache[p] = pow(sha3(seed), w, P) - else: - x = pow(sha3(seed), (p + 1) * w, P) - for _ in range(params["k"]): - x ^= quick_calc_cached(x % p) - cache[p] = pow(x, w, P) - return cache[p] - - return quick_calc_cached(p) -``` - -Essentially, it is simply a rewrite of the above algorithm that removes the loop of computing the values for the entire DAG and replaces the earlier node lookup with a recursive call or a cache lookup. Note that for `k=1` the cache is unnecessary, although a further optimization actually precomputes the first few thousand values of the DAG and keeps that as a static cache for computations; see the appendix for a code implementation of this. - -## Double Buffer of DAGs - -In a full client, a [*double buffer*](https://en.wikipedia.org/wiki/Multiple_buffering) of 2 DAGs produced by the above formula is used. The idea is that DAGs are produced every `epochtime` number of blocks according to the params above. The client does not use the latest DAG produced, but the previous one. The benefit of this is that it allows the DAGs to be replaced over time without needing to incorporate a step where miners must suddenly recompute all of the data. Otherwise, there is the potential for an abrupt temporary slowdown in chain processing at regular intervals and dramatically increasing centralization and thus 51% attack risks within those few minutes before all data is recomputed. - -The algorithm used to generate the actual set of DAGs used to compute the work for a block is as follows: - -```python -def get_prevhash(n): - from pyethereum.blocks import GENESIS_PREVHASH - from pyethreum import chain_manager - if n <= 0: - return hash_to_int(GENESIS_PREVHASH) - else: - prevhash = chain_manager.index.get_block_by_number(n - 1) - return decode_int(prevhash) - -def get_seedset(params, block): - seedset = {} - seedset["back_number"] = block.number - (block.number % params["epochtime"]) - seedset["back_hash"] = get_prevhash(seedset["back_number"]) - seedset["front_number"] = max(seedset["back_number"] - params["epochtime"], 0) - seedset["front_hash"] = get_prevhash(seedset["front_number"]) - return seedset - -def get_dagsize(params, block): - return params["n"] + (block.number // params["epochtime"]) * params["n_inc"] - -def get_daggerset(params, block): - dagsz = get_dagsize(params, block) - seedset = get_seedset(params, block) - if seedset["front_hash"] <= 0: - # No back buffer is possible, just make front buffer - return {"front": {"dag": produce_dag(params, seedset["front_hash"], dagsz), - "block_number": 0}} - else: - return {"front": {"dag": produce_dag(params, seedset["front_hash"], dagsz), - "block_number": seedset["front_number"]}, - "back": {"dag": produce_dag(params, seedset["back_hash"], dagsz), - "block_number": seedset["back_number"]}} -``` - -## Hashimoto - -The idea behind the original Hashimoto is to use the blockchain as a dataset, performing a computation which selects N indices from the blockchain, gathers the transactions at those indices, performs an XOR of this data, and returns the hash of the result. Thaddeus Dryja's original algorithm, translated to Python for consistency, is as follows: - -```python -def orig_hashimoto(prev_hash, merkle_root, list_of_transactions, nonce): - hash_output_A = sha256(prev_hash + merkle_root + nonce) - txid_mix = 0 - for i in range(64): - shifted_A = hash_output_A >> i - transaction = shifted_A % len(list_of_transactions) - txid_mix ^= list_of_transactions[transaction] << i - return txid_max ^ (nonce << 192) -``` - -Unfortunately, while Hashimoto is considered RAM hard, it relies on 256-bit arithmetic, which has considerable computational overhead. To address this issue, dagger hashimoto only uses the least significant 64 bits when indexing its dataset. - -```python -def hashimoto(dag, dagsize, params, header, nonce): - m = dagsize / 2 - mix = sha3(encode_int(nonce) + header) - for _ in range(params["accesses"]): - mix ^= dag[m + (mix % 2**64) % m] - return dbl_sha3(mix) -``` - -The use of double sha3 allows for a form of zero-data, near-instant pre-verification, verifying only that a correct intermediate value was provided. This outer layer of PoW is highly ASIC-friendly and fairly weak, but exists to make DDoS even more difficult since that small amount of work must be done in order to produce a block that will not be rejected immediately. Here is the light-client version: - -```python -def quick_hashimoto(seed, dagsize, params, header, nonce): - m = dagsize // 2 - mix = sha3(nonce + header) - for _ in range(params["accesses"]): - mix ^= quick_calc(params, seed, m + (mix % 2**64) % m) - return dbl_sha3(mix) -``` - -## Mining and Verifying - -Now, let us put it all together into the mining algo: - -```python -def mine(daggerset, params, block): - from random import randint - nonce = randint(0, 2**64) - while 1: - result = hashimoto(daggerset, get_dagsize(params, block), - params, decode_int(block.prevhash), nonce) - if result * params["diff"] < 2**256: - break - nonce += 1 - if nonce >= 2**64: - nonce = 0 - return nonce -``` - -Here is the verification algorithm: -```python -def verify(daggerset, params, block, nonce): - result = hashimoto(daggerset, get_dagsize(params, block), - params, decode_int(block.prevhash), nonce) - return result * params["diff"] < 2**256 -``` - -Light-client friendly verification: - -```python -def light_verify(params, header, nonce): - seedset = get_seedset(params, block) - result = quick_hashimoto(seedset["front_hash"], get_dagsize(params, block), - params, decode_int(block.prevhash), nonce) - return result * params["diff"] < 2**256 -``` - -Also, note that Dagger Hashimoto imposes additional requirements on the block header: - -* For two-layer verification to work, a block header must have both the nonce and the middle value pre-sha3 -* Somewhere, a block header must store the sha3 of the current seedset - -# Appendix - -As noted above, the RNG used for DAG generation relies on some results from number theory. First, we provide assurance that the Lehmer RNG that is the basis for the `picker` variable has a wide period. Second, we show that `pow(x,3,P)` will not map `x` to `1` or `P-1` provided `x ∈ [2,P-2]` to start. Finally, we show that `pow(x,3,P)` has a low collision rate when treated as a hashing function. - -## Lehmer Random Number Generator - -While the `produce_dag` function does not need to produce unbiased random numbers, a potential threat is that `seed**i % P` only takes on a handful of values. This could provide an advantage to miners recognizing the pattern over those that do not. - -To avoid this, a result from number theory is appealed to. A [*Safe Prime*](https://en.wikipedia.org/wiki/Safe_prime) is defined to be a prime `P` such that `(P-1)/2` is also prime. The *order* of a member `x` of the [multiplicative group](https://en.wikipedia.org/wiki/Multiplicative_group_of_integers_modulo_n) `ℤ/nℤ` is defined to be the minimal `m` such that
xᵐ mod P ≡ 1
-Given these definitions, we have: - -> Observation 1. Let `x` be a member of the multiplicative group `ℤ/Pℤ` for a safe prime `P`. If `x mod P ≠ 1 mod P` and `x mod P ≠ P-1 mod P`, then the order of `x` is either `P-1` or `(P-1)/2`. - -*Proof*. Since `P` is a safe prime, then by [Lagrange's Theorem][Lagrange] we have that the order of `x` is either `1`, `2`, `(P-1)/2`, or `P-1`. - -The order of `x` cannot be `1`, since by Fermat's Little Theorem we have: -
xP-1 mod P ≡ 1
-Hence `x` must be a multiplicative identity of `ℤ/nℤ`, which is unique. Since we assumed that `x ≠ 1` by assumption, this is not possible. - -The order of `x` cannot be `2` unless `x = P-1`, since this would violate that `P` is prime. -
- -From the above proposition, we can recognize that iterating `(picker * init) % P` will have a cycle length of at least `(P-1)/2`. This is because we selected `P` to be a safe prime approximately equal to be a higher power of two, and `init` is in the interval `[2,2**256+1]`. Given the magnitude fo `P`, we should never expect a cycle from modular exponentiation. - -When we are assigning the first cell in the DAG (the variable labeled `init`), we compute `pow(sha3(seed) + 2, 3, P)`. At first glance, this does not guarantee that the result is neither `1` nor `P-1`. However, since `P-1` is a safe prime, we have the following additional assuance, which is a corollary of Observation 1: - -> Observation 2. Let `x` be a member of the multiplicative group `ℤ/Pℤ` for a safe prime `P`, and let `w` be a natural number. If `x mod P ≠ 1 mod P` and `x mod P ≠ P-1 mod P`, as well as `w mod P ≠ P-1 mod P` and `w mod P ≠ 0 mod P`, then `xʷ mod P ≠ 1 mod P` and `xʷ mod P ≠ P-1 mod P` - -[Lagrange]: https://en.wikipedia.org/wiki/Lagrange%27s_theorem_(group_theory) - -## Modular Exponentiation as a Hash Function - -For certain values of `P` and `w`, the function `pow(x, w, P)` may have many collisions. For instance, `pow(x,9,19)` only takes on values `{1,18}`. - -Given that `P` is prime, then an appropriate `w` for a modular exponentation hashing function can be chosen using the following result: - -> Observation 3. Let `P` be a prime; `w` and `P-1` are relatively prime if and only if for all `a` and `b` in `ℤ/Pℤ`:
`aʷ mod P ≡ bʷ mod P` if and only if `a mod P ≡ b mod P`
- -Thus, given that `P` is prime and `w` is relatively prime to `P-1`, we have that `|{pow(x, w, P) : x ∈ ℤ}| = P`, implying that the hashing function has the minimal collision rate possible. - -In the special case that `P` is a safe prime as we have selected, then `P-1` only has factors 1, 2, `(P-1)/2` and `P-1`. Since `P` > 7, we know that 3 is relatively prime to `P-1`, hence `w=3` satisfies the above proposition. - -## More Efficient Cache-based Evaluation Algos - - def quick_calc(params, seed, p): - cache = produce_dag(params, seed, params["cache_size"]) - return quick_calc_cached(cache, params, p) - - def quick_calc_cached(cache, params, p): - P = params["P"] - if p < len(cache): - return cache[p] - else: - x = pow(cache[0], p + 1, P) - for _ in range(params["k"]): - x ^= quick_calc_cached(cache, params, x % p) - return pow(x, params["w"], P) - - def quick_hashimoto(seed, dagsize, params, header, nonce): - cache = produce_dag(params, seed, params["cache_size"]) - return quick_hashimoto_cached(cache, dagsize, params, header, nonce) - - def quick_hashimoto_cached(cache, dagsize, params, header, nonce): - m = dagsize // 2 - mask = 2**64 - 1 - mix = sha3(encode_int(nonce) + header) - for _ in range(params["accesses"]): - mix ^= quick_calc_cached(cache, params, m + (mix & mask) % m) - return dbl_sha3(mix) - - ------------------------------------ - -Special thanks to feedback from: - -* Tim Hughes -* Matthew Wampler-Doty -* Thaddeus Dryja diff --git a/pages/ethash-dagger-hashimoto/Dagger.md b/pages/ethash-dagger-hashimoto/Dagger.md deleted file mode 100644 index d0c2231d6..000000000 --- a/pages/ethash-dagger-hashimoto/Dagger.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -name: Dagger -category: ---- - -**Note: we will not be using Dagger as our Proof of Work algorithm. This page is pending deletion** - -Over the past five years of experience with Bitcoin and alternative cryptocurrencies, one important property for proof of work functions that has been discovered is that of "memory-hardness" - computing a valid proof of work should require not only a large number of computations, but also a large amount of memory. Currently, there are three major categories of memory-hard functions used in mining: scrypt, Primecoin mining and the birthday problem. However, both are imperfect: neither require nearly as much memory as an ideal memory-hard function could require, and both suffer from time-memory tradeoff attacks, where the function can be computed with significantly less memory than intended at the cost of sacrificing some computational efficiency. - -Dagger is a proof of work algorithm intended to solve these problems, providing a memory-hard proof of work based on moderately connected directed acyclic graphs (DAGs, hence the name), which, while far from optimal, has much stronger memory-hardness properties than anything else in use today. - -## Why Be Memory-Hard? - -The main reason why memory hardness is important is to make the proof of work function resistant to specialized hardware. With Bitcoin, whose mining algorithm requires only a simple SHA256 computation, companies have already existed for over a year that create specialized "application-specific integrated circuits" (ASICs) designed and configured in silicon for the sole purpose of computing billions of SHA256 hashes in an attempt to "mine" a valid Bitcoin block. These chips have no legitimate applications outside of Bitcoin mining and password cracking, and the presence of these chips, which are thousands of times more efficient per dollar and kilowatt hour at computing hashes than generic CPUs, makes it impossible for ordinary users with generic CPU and GPU hardware to compete. - -This dominance of specialized hardware has several detrimental effects: - -1. **It negates the democratic distribution aspect of cryptocurrency mining**. In a generic hardware-dominated ecosystem, the fact that everyone has a computer guarantees that everyone will have an equal opportunity to earn at least some of the initial money supply. With specialized hardware, this factor does not exist; each economic actor's mining potential is linear (in fact, slightly superlinear) in their quantity of pre-existing capital, potentially exacerbating existing wealth inequalities. -2. **It increases resource waste**. In an efficient market, marginal revenue approaches marginal cost. Since mining revenue is a linear function of money spent on mining hardware and electricity, this also implies that total revenue approaches total cost. Hence, in a specialized hardware dominated ecosystem, the quantity of resources wasted is close to 100% of the security level of the network. In a CPU and GPU-dominated ecosystem, because everyone already has a computer, people do not need to buy specialized hardware for the first few hashes per second worth of mining power. Hence, revenue is sublinear in cost - everyone gets a bit of revenue "for free". This implies that the quantity of resources wasted by the network is potentially considerably lower than its security parameter. -3. **It centralizes mining in the hands of a few actors** (ie. ASIC manufacturers), making 51% attacks much more likely and potentially opening the network up to regulatory pressure. - -Specialized hardware is so powerful because it includes many thousands of circuits specifically designed for computing the proof of work function, allowing the hardware to compute the function thousands of times in parallel. Memory hardness alleviates this problem by making the main limiting factor not CPU power, but memory. One can also make a modest improvement by targeting CPU clock speed, but the extent to which such optimizations can be made is fundamentally limited to a very low value by technological considerations. Thus, improvement through parallelization hits a roadblock: running ten memory-hard computations in parallel requires ten times as much memory. Specialized hardware menufacturers can certainly pack terabytes of memory into their devices, but the effect of this is mitigated by two factors. First, hobbyists can achieve the same effect by simply buying many off-the-shelf memory cards. Second, memory is much more expensive to produce (if measured in laptop equivalents) than SHA256 hashing chips; the RAM used in ordinary computers is already essentially optimal. - -## Objections to Memory-Hardness - -1. **All algorithms will be vulnerable to ASICs eventually**. This point has become more popular especially after the recent announcement from a company producing ASICs for Scrypt, and essentially states that theoretically any algorithm can be better done by specialized hardware than general purpose hardware, and so there is no point in trying to make algorithms targeted to general purpose hardware. What the argument misses, however, is that the speedup from applying specialized hardware to the moderately memory-hard Scrypt has been demonstrated to be much lower than for Bitcoin. Furthermore, there are indeed reasons to suggest the trend will continue - as described above, the memory found in commodity hardware is much closer to optimal than the computing circuits. -2. **Botnets will take over the mining process**. This point can also be addressed in two ways: empirically and theoretically. Empirically, botnets so far have not been substantially involved in mounting 51% attacks in existing altcoins, generally, they are content simply to extract revenue as "legitimate" miners. Theoretically, the current public prominence of botnets as a threat is backed largely by their performance in network flooding / denial of service attacks - situations where each computer in a botnet is only used for the number of connections that it can make. In the context of mining, however, botnet-infected computers tend to be running older operating systems and have weaker specifications, meaning that they will have a much lower performance and impact on the network than their size might initially suggest. - -## Existing alternatives - -The existence of every new algorithm, protocol of cryptographic primitive as opposed to existing and more well-tested technologies must always be strongly justified; in as delicate an area as cryptocurrency, caution is very important both because the system will handle millions of dollars of capital and because if a mistake is made there is no way to simply upgrade to a new version with a bugfix. The purpose of this section will be to go through the three existing alternatives and show why they are inadequate. - -### Scrypt - -Scrypt is the algorithm used by Litecoin, Dogecoin and most other new cryptocurrencies coming out today. A very simplified description of Scrypt-like algorithms is as follows: - -1. Let `H[0] = D+N` where D is the underlying data and N is the nonce. -2. For `i` from `1` to `N` let `H[i] = f(H[0] ... H[i-1])` where f is some hash-like function that takes multiple inputs. -3. For `i` from `1` to `M` let `R[i] = random([1 ... M])` -4. `SCRYPT(D,N) = f(H[R[0]] ... H[R[M]]`. If `SCRYPT(D,N)` is low enough, then `N` is a valid nonce. - -The idea is that there is no way to practically compute `SCRYPT(D)` without building the entire `H` array and keeping it in memory for the last step. However, Scrypt-like algorithms have a property that inherently limits just how memory-hard they can be: verification requires computing one round of the entire function, so the function is as memory-hard to verify as it is memory-hard to compute. Thus, while scrypt may be viable for achieving memory hardness around a few megabytes per thread, it is a non-starter for memory hardness in the area of hundreds of megabytes per thread. In fact, hundreds of megabytes per thread is arguably necessary; there are already companies [http://www.cryptocoinsnews.com/2013/11/22/alpha-technologies-offer-scrypt-mining-asics/ working on ASICs for scrypt] today. - -### Primecoin - -Primecoin's algorithm is not designed to be memory-hard, but it does have that property to some extent. The algorithm requires miners to find so-called Cunningham chains of prime numbers - chains of the form `[ n+1, 2n+1, 4n+1 ... n*2^k+1 ]` for a sufficiently large `k`. As it turns out, it is very difficult to do this for any significant length without first filling in a data structure known as a sieve. The advantage of Primecoin is that verification is nearly instant and very memory-cheap; all that one needs to do is run the Fermat primality test to make sure that all of the values are prime. However, the Primecoin algorithm has two weaknesses in this regard: - -1. '''Time-memory tradeoff''' - an ASIC has the option of removing much of the memory required by sacrificing some computational efficiency; even with only 100 KB per thread a miner can be fairly efficient. -2. '''All clear effect''' - as it turns out, it is possible for GPUs and ASICs to have multiple threads share the same memory. Since Primecoin mining only requires the sieve to be filled once, an ASIC can calculate a sieve first and then run thousands of threads through it. - -### Birthday attack - -The birthday attack algorithm is ingenious, and works as follows: - -1. Let `H[i] = sha256(D + N + i)` for `i` from 0 to 232 - 1 given data `D` and nonce `N`. -2. If `abs(H[i] - H[j])` is sufficiently low, then `(N,i,j)` is a valid solution triple. - -The ingenuity of the protocol comes from the fact that while efficiently computing the birthday attack requires storing the hashes in a data structure so that every new hash can be checked against all previous ones, verifying the solution only requires checking two hashes. The algorithm is resistant against the all-clear effect because memory must be flushed every 232 rounds. However, there are several shortcuts and time-memory tradeoff attacks. First, one can optimize by storing only the first few bytes of each hash instead of the entire hash. Second, one can only store hashes with the first two bits being 00; this takes 75% of possible solutions out of consideration, reducing time efficiency by 4x, but it also increases space efficiency by 4x. Finally, there is potential for optimization by examining the various options between storing hashes in a large array, a binary or red-black tree, and other more complex structures; the optimal algorithm may be quite complicated. - -Dagger intends to solve all of these issues, having a currency that is memory-hard to computer but memory-easy to verify, has no all clear effect, no time-memory tradeoff even at a 1:1 ratio, and for which a close-to-optimal algorithm is the naive one. - -## Algorithm specification: - -Essentially, the Dagger algorithm works by creating a directed acyclic graph (the technical term for a tree where each node is allowed to have multiple parents) with a total of 223 - 1 nodes in sequence. Each node depends on 3-15 randomly selected nodes before it. If the miner finds a node between index 222 and 223 such that this resulting hash is below 2256 divided by the difficulty parameter, the result is a valid proof of work. - -Let `D` be the underlying data (eg. in Bitcoin's case the block header), `N` be the nonce and `||` be the string concatenation operator (ie. `'foo' || 'bar' == 'foobar'`) . The entire code for the algorithm is as follows: - - - - D(data,xn,0) = sha3(data) - D(data,xn,n) = - with v = sha3(data + xn + n) - L = 2 if n < 2^21 else 11 if n < 2^22 else 3 - a[k] = floor(v/n^k) mod n for 0 <= k < 2 - a[k] = floor(v/n^k) mod 2^22 for 2 <= k < L - sha3(v ++ D(data,xn,a[0]) ++ D(data,xn,a[1]) ++ ... ++ D(data,xn,a[L-1])) - - - -## Properties: -Objective: find `xn`, `n` such that `n > 2^22` and `D(data,xn,n) < 2^256 / diff` - -1. With 228 bytes (256 MB) of memory, the optimal algorithm is to run `D` all the way through from start to finish. -2. One potential problem is lazy evaluation; parts of the tree can be evaluated only as needed in order to reduce the number of hashes required. However, because a (pseudo-) random node out of 225 is taken 228 times, we can statistically estimate that each node has a 1 / e8 change of remaining unused - only about 0.03%. Hence, the benefit from lazy evaluation is insubstantial. -3. It is possible to run the algorithm with much less memory using lazy evaluation. However, empirical tests show that computing one nonce requires 3000 - 25000 hashes. -4. Verification also requires 3000 - 25000 hashes. -5. Because the 2^21 to 2^22 phase requires 11 parents, the time-memory tradeoff attack is severely weakened - attempting to store 2^21 nodes instead of 2^23 reduces memory usage by a factor of 4 but slows down computation by a factor about 20. Thus, no practical time-memory tradeoff attack exists; close to the full 256 MB is required for any reasonable level of efficiency. - -## Conclusion - -This algorithm provides a proof of work mining function with memory hardness properties that are not ideal, but that are nevertheless a massive improvement over anything available previously. It takes 512 MB to evaluate, 112 KB memory and 4078 hashes to verify, and even the tinest time-memory tradeoff is not worthwhile to implement because of the bottom-level branching adjustment. These parameters allow Dagger to be much more daring in its memory requirements than Primecoin or scrypt, asking for 512 MB of RAM for a single thread. Because the primary determinant of hardness is memory, and not computation, specialized hardware has only a tiny advantage; even an optimal Dagger mining ASIC would have little to offer over a hobbyist purchasing hundreds of gigabytes of memory cards off the shelf and plugging them into a medium-power GPU. And even in such an equilibrium, mining with ordinary CPUs will likely continue to be practical. - -## Acknowledgements - -* Thanks to Adam Back and Charles Hoskinson, for discussion and critique of earlier drafts of the protocol -* See also: [Fabien Coelho's paper](http://www.cri.ensmp.fr/classement/doc/A-370-v1.pdf), in which Fabien Coelho had independently discovered a similar algorithm in 2005. \ No newline at end of file diff --git a/pages/ethash-dagger-hashimoto/Ethash-C-API.md b/pages/ethash-dagger-hashimoto/Ethash-C-API.md deleted file mode 100644 index cb6bb248a..000000000 --- a/pages/ethash-dagger-hashimoto/Ethash-C-API.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -name: Ethash C API -category: ---- - -This is just a documentation of the request of the C API described in [this PR](https://github.com/ethereum/ethash/pull/11). - -```c -typedef int(*Callback)(unsigned); -typedef /*...*/ ethash_light_t; -typedef /*...*/ ethash_full_t; -typedef struct ethash_h256 { uint8_t b[32]; } ethash_h256_t; -typedef struct ethash_result { ethash_h256_t value; ethash_h256_t hixhash; } ethash_result_t; - -ethash_light_t ethash_light_new(unsigned number); -ethash_result_t ethash_light_compute(ethash_light_t light, ethash_h256_t header_hash, uint64_t nonce); -void ethash_light_delete(ethash_light_t light); - -ethash_full_t ethash_full_new(ethash_light_t light, CallBack c); -uint64_t ethash_full_dag_size(ethash_full_t full); -void const* ethash_full_dag(ethash_full_t full); -ethash_result_t ethash_full_compute(ethash_full_t full, ethash_h256_t header_hash, uint64_t nonce); -void ethash_full_delete(ethash_full_t full); -``` - -non-zero return from Callback means "cancel DAG creation" - this should cause an immediate return of `ethash_full_new` with 0. - -an object of type `ethash_full_t` may be tested for validity with != 0 - -### Example usage: -```c -int callback(unsigned _progress) -{ - printf("\rGenerating DAG. %d%% done...", _progress); - return 0; -} -void main() -{ - ethash_light_t light; - ethash_h256_t seed; - // TODO: populate p, seed, light - ethash_full_t dag = ethash_full_new(light, seed, &callback); - if (!dag) - { - printf("Failed generating DAG :-(\n"); - exit(-1); - } - printf("DAG Generated OK!\n"); - - ethash_h256_t headerHash; - // TODO: populate headerHash - uint64_t nonce = time(0); - ethash_result ret; - for (; !isWinner(ret); nonce++) - ret = ethash_full_compute(dag, headerHash, nonce); - printf("Got winner! nonce is %d\n", nonce); - ethash_full_delete(dag); -} -``` \ No newline at end of file diff --git a/pages/ethash-dagger-hashimoto/Ethash-DAG-Disk-Storage-Format.md b/pages/ethash-dagger-hashimoto/Ethash-DAG-Disk-Storage-Format.md deleted file mode 100644 index 15493aafc..000000000 --- a/pages/ethash-dagger-hashimoto/Ethash-DAG-Disk-Storage-Format.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -name: Ethash DAG -category: ---- - -Ethash is the PoW system. It requires a great huge dataset known as the DAG (name refers to [Dagger Hashimoto](https://github.com/ethereum/wiki/wiki/Dagger-Hashimoto)). This takes a good long while to generate which is a pain. As such we tend to memoise it. Clients wishing to store the DAG in a cache should conform to this spec in order to share the cache with other clients: - -#### Location - -The DAG should be stored in a 1GB dump (for the initial epoch, anyway), in a file: - -- Mac/Linux: `$(HOME)/.ethash/full-R-` -- Windows: `$(HOME)/Appdata/Local/Ethash/full-R-` - -Where: - -- `` is a decimal integer, given as the C-constant `REVISION` in `libethash/ethash.h`; -- `` is 16 lowercase hex digits specifying the first 8 bytes of the epoch's seed hash. - -There may be many such DAGs stored in this directory; it is up to the client and/or user to remove out of date ones. - -#### Format - -Each file should begin with an 8-byte magic number, `0xfee1deadbaddcafe`, written in little-endian format (i.e., bytes `fe ca dd ba ad de e1 fe`). - -The Ethash algorithm expects the DAG as a two-dimensional array of uint32s (4-byte unsigned ints), with dimension (n × 16) where n is a large number. (n starts at 16777186 and grows from there.) Following the magic number, the rows of the DAG should be written sequentially into the file, with no delimiter between rows and each unint32 encoded in little-endian format. \ No newline at end of file diff --git a/pages/ethash-dagger-hashimoto/Ethash-Design-Rationale.md b/pages/ethash-dagger-hashimoto/Ethash-Design-Rationale.md deleted file mode 100644 index 191b1f1b7..000000000 --- a/pages/ethash-dagger-hashimoto/Ethash-Design-Rationale.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -name: Ethash Design Rationale -category: ---- - -Ethash is intended to satisfy the following goals: - -1. **IO saturation**: The algorithm should consume nearly the entire available memory access bandwidth (this is a strategy toward achieving ASIC resistance, the argument being that commodity RAM, especially in GPUs, is much closer to the theoretical optimum than commodity computing capacity) -2. **GPU friendliness**: We try to make it as easy as possible to mine with GPUs. Targeting CPUs is almost certainly impossible, as potential specialization gains are too great, and there do exist criticisms of CPU-friendly algorithms that they are vulnerable to botnets, so we target GPUs as a compromise. -3. **Light client verifiability**: a light client should be able to verify a round of mining in under 0.01 seconds on a desktop in C, and under 0.1 seconds in Python or Javascript, with at most 1 MB of memory (but exponentially increasing) -4. **Light client slowdown**: the process of running the algorithm with a light client should be much slower than the process with a full client, to the point that the light client algorithm is not an economically viable route toward making a mining implementation, including via specialized hardware. -5. **Light client fast startup**: a light client should be able to become fully operational and able to verify blocks within 40 seconds in Javascript. - -### FNV - -FNV was used to provide a data aggregation function which is (i) non-associative, and (ii) easy to compute. A commutative and associative alternative to FNV would be XOR. - -### Parameters - -* A 16 MB cache was chosen because a smaller cache would allow for an ASIC to be produced far too easily using the light-evaluation method. The 16 MB cache still requires a very high bandwidth of cache reading, whereas a smaller cache could be much more easily optimized. A larger cache would lead to the algorithm being too hard to evaluate with a light client. -* 256 parents per DAG item was chosen in order to ensure that time-memory tradeoffs can only be made at a worse-than-1:1 ratio. -* The 1 GB DAG size was chosen in order to require a level of memory larger than the size at which most specialized memories and caches are built, but still small enough for ordinary computers to be able to mine with it. -* The ~0.73x per year growth level was chosen to roughly be balanced with Moore's law increases at least initially (exponential growth has a risk of overshooting Moore's law, leading to a situation where mining requires very large amounts of memory and ordinary GPUs are no longer usable for mining). -* 64 accesses was chosen because a larger number of accesses would lead to light verification taking too long, and a smaller number would mean that the bulk of the time consumption is the SHA3 at the end, not the memory reads, making the algorithm not so strongly IO-bound. -* The epoch length cannot be infinite (ie. constant dataset) because then the algorithm could be optimized via ROM, and very long epoch lengths make it easier to create memory which is designed to be updated very infrequently and only read often. Excessively short epochs would increase barriers to entry as weak machines would need to spend much of their time on a fixed cost of updating the dataset. The epoch length can probably be reduced or increased substantially if design considerations require it. -* The cache size and dataset size is prime in order to help mitigate the risk of cycles appearing in dataset item generation or mining. \ No newline at end of file diff --git a/pages/ethash-dagger-hashimoto/Ethash.md b/pages/ethash-dagger-hashimoto/Ethash.md deleted file mode 100644 index 49cec0a41..000000000 --- a/pages/ethash-dagger-hashimoto/Ethash.md +++ /dev/null @@ -1,998 +0,0 @@ ---- -name: Ethash -category: ---- - -**This spec is REVISION 23. Whenever you substantively (ie. not clarifications) update the algorithm, please update the revision number in this sentence. Also, in all implementations please include a spec revision number** - -Ethash is the planned PoW algorithm for Ethereum 1.0. It is the latest version of Dagger-Hashimoto, although it can no longer appropriately be called that since many of the original features of both algorithms have been drastically changed in the last month of research and development. See [https://github.com/ethereum/wiki/wiki/Dagger-Hashimoto](https://github.com/ethereum/wiki/wiki/Dagger-Hashimoto) for the original version. - -The general route that the algorithm takes is as follows: - -1. There exists a **seed** which can be computed for each block by scanning through the block headers up until that point. -2. From the seed, one can compute a **16 MB pseudorandom cache**. Light clients store the cache. -3. From the cache, we can generate a **1 GB dataset**, with the property that each item in the dataset depends on only a small number of items from the cache. Full clients and miners store the dataset. The dataset grows linearly with time. -4. Mining involves grabbing random slices of the dataset and hashing them together. Verification can be done with low memory by using the cache to regenerate the specific pieces of the dataset that you need, so you only need to store the cache. - -The large dataset is updated once every 30000 blocks, so the vast majority of a miner's effort will be reading the dataset, not making changes to it. - -See [https://github.com/ethereum/wiki/wiki/Ethash-Design-Rationale](https://github.com/ethereum/wiki/wiki/Ethash-Design-Rationale) for design rationale considerations for this algorithm. - -### Definitions - -We employ the following definitions: - -``` -WORD_BYTES = 4 # bytes in word -DATASET_BYTES_INIT = 2**30 # bytes in dataset at genesis -DATASET_BYTES_GROWTH = 2**23 # dataset growth per epoch -CACHE_BYTES_INIT = 2**24 # bytes in dataset at genesis -CACHE_BYTES_GROWTH = 2**17 # cache growth per epoch -CACHE_MULTIPLIER=1024 # Size of the DAG relative to the cache -EPOCH_LENGTH = 30000 # blocks per epoch -MIX_BYTES = 128 # width of mix -HASH_BYTES = 64 # hash length in bytes -DATASET_PARENTS = 256 # number of parents of each dataset element -CACHE_ROUNDS = 3 # number of rounds in cache production -ACCESSES = 64 # number of accesses in hashimoto loop -``` - -### Parameters - -The parameters for Ethash's cache and dataset depend on the block number. The cache size and dataset size both grow linearly; however, we always take the highest prime below the linearly growing threshold in order to reduce the risk of accidental regularities leading to cyclic behavior. - -```python -def get_cache_size(block_number): - sz = CACHE_BYTES_INIT + CACHE_BYTES_GROWTH * (block_number // EPOCH_LENGTH) - sz -= HASH_BYTES - while not isprime(sz / HASH_BYTES): - sz -= 2 * HASH_BYTES - return sz - -def get_full_size(block_number): - sz = DATASET_BYTES_INIT + DATASET_BYTES_GROWTH * (block_number // EPOCH_LENGTH) - sz -= MIX_BYTES - while not isprime(sz / MIX_BYTES): - sz -= 2 * MIX_BYTES - return sz -``` - -Tables of dataset and cache size values are provided in the appendix. - -### Cache Generation - -Now, we specify the function for producing a cache: - -```python -def mkcache(cache_size, seed): - n = cache_size // HASH_BYTES - - # Sequentially produce the initial dataset - o = [sha3_512(seed)] - for i in range(1, n): - o.append(sha3_512(o[-1])) - - # Use a low-round version of randmemohash - for _ in range(CACHE_ROUNDS): - for i in range(n): - v = o[i][0] % n - o[i] = sha3_512(map(xor, o[(i-1+n) % n], o[v])) - - return o -``` - -[Sergio2014]: http://www.hashcash.org/papers/memohash.pdf - -The cache production process involves first sequentially filling up 32 MB of memory, then performing two passes of Sergio Demian Lerner's *RandMemoHash* algorithm from [*Strict Memory Hard Hashing Functions* (2014)](http://www.hashcash.org/papers/memohash.pdf). The output is a set of 524288 64-byte values. - -### Data aggregation function - -We use an algorithm inspired by the [FNV hash](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function) in some cases as a non-associative substitute for XOR. Note that we multiply the prime with the full 32-bit input, in contrast with the FNV-1 spec which multiplies the prime with one byte (octet) in turn. - -```python -FNV_PRIME = 0x01000193 - -def fnv(v1, v2): - return (v1 * FNV_PRIME ^ v2) % 2**32 -``` - -### Full dataset calculation - -Each 64-byte item in the full 1 GB dataset is computed as follows: - -```python -def calc_dataset_item(cache, i): - n = len(cache) - r = HASH_BYTES // WORD_BYTES - # initialize the mix - mix = copy.copy(cache[i % n]) - mix[0] ^= i - mix = sha3_512(mix) - # fnv it with a lot of random cache nodes based on i - for j in range(DATASET_PARENTS): - cache_index = fnv(i ^ j, mix[j % r]) - mix = map(fnv, mix, cache[cache_index % n]) - return sha3_512(mix) -``` - -Essentially, we combine data from 256 pseudorandomly selected cache nodes, and hash that to compute the dataset node. The entire dataset is then generated by: - -```python -def calc_dataset(full_size, cache): - return [calc_dataset_item(cache, i) for i in range(full_size // HASH_BYTES)] -``` - -### Main Loop - -Now, we specify the main "hashimoto"-like loop, where we aggregate data from the full dataset in order to produce our final value for a particular header and nonce. In the code below, `header` represents the SHA3-256 _hash_ of the RLP representation of a _truncated_ block header, that is, of a header excluding the fields **mixHash** and **nonce**. `nonce` is the eight bytes of a 64 bit unsigned integer in big-endian order. So `nonce[::-1]` is the eight-byte little-endian representation of that value: - -```python -def hashimoto(header, nonce, full_size, dataset_lookup): - n = full_size / HASH_BYTES - w = MIX_BYTES // WORD_BYTES - mixhashes = MIX_BYTES / HASH_BYTES - # combine header+nonce into a 64 byte seed - s = sha3_512(header + nonce[::-1]) - # start the mix with replicated s - mix = [] - for _ in range(MIX_BYTES / HASH_BYTES): - mix.extend(s) - # mix in random dataset nodes - for i in range(ACCESSES): - p = fnv(i ^ s[0], mix[i % w]) % (n // mixhashes) * mixhashes - newdata = [] - for j in range(MIX_BYTES / HASH_BYTES): - newdata.extend(dataset_lookup(p + j)) - mix = map(fnv, mix, newdata) - # compress mix - cmix = [] - for i in range(0, len(mix), 4): - cmix.append(fnv(fnv(fnv(mix[i], mix[i+1]), mix[i+2]), mix[i+3])) - return { - "mix digest": serialize_hash(cmix), - "result": serialize_hash(sha3_256(s+cmix)) - } - -def hashimoto_light(full_size, cache, header, nonce): - return hashimoto(header, nonce, full_size, lambda x: calc_dataset_item(cache, x)) - -def hashimoto_full(full_size, dataset, header, nonce): - return hashimoto(header, nonce, full_size, lambda x: dataset[x]) -``` - -Essentially, we maintain a "mix" 128 bytes wide, and repeatedly sequentially fetch 128 bytes from the full dataset and use the `fnv` function to combine it with the mix. 128 bytes of sequential access are used so that each round of the algorithm always fetches a full page from RAM, minimizing translation lookaside buffer misses which ASICs would theoretically be able to avoid. - -If the output of this algorithm is below the desired target, then the nonce is valid. Note that the extra application of `sha3_256` at the end ensures that there exists an intermediate nonce which can be provided to prove that at least a small amount of work was done; this quick outer PoW verification can be used for anti-DDoS purposes. It also serves to provide statistical assurance that the result is an unbiased, 256 bit number. - -### Mining - -The mining algorithm is defined as follows: - -```python -def mine(full_size, dataset, header, difficulty): - target = zpad(encode_int(2**256 // difficulty), 64)[::-1] - from random import randint - nonce = randint(0, 2**64) - while hashimoto_full(full_size, dataset, header, nonce) > target: - nonce = (nonce + 1) % 2**64 - return nonce -``` - -### Defining the Seed Hash - -In order to compute the seed hash that would be used to mine on top of a given block, we use the following algorithm: - -```python - def get_seedhash(block): - s = '\x00' * 32 - for i in range(block.number // EPOCH_LENGTH): - s = serialize_hash(sha3_256(s)) - return s -``` - -Note that for smooth mining and verifying, we recommend pre-computing future seedhashes and datasets in a separate thread. - -### Appendix - -The following code should be prepended if you are interested in running the above python spec as code. - -```python -import sha3, copy - -# Assumes little endian bit ordering (same as Intel architectures) -def decode_int(s): - return int(s[::-1].encode('hex'), 16) if s else 0 - -def encode_int(s): - a = "%x" % s - return '' if s == 0 else ('0' * (len(a) % 2) + a).decode('hex')[::-1] - -def zpad(s, length): - return s + '\x00' * max(0, length - len(s)) - -def serialize_hash(h): - return ''.join([zpad(encode_int(x), 4) for x in h]) - -def deserialize_hash(h): - return [decode_int(h[i:i+WORD_BYTES]) for i in range(0, len(h), WORD_BYTES)] - -def hash_words(h, sz, x): - if isinstance(x, list): - x = serialize_hash(x) - y = h(x) - return deserialize_hash(y) - -def serialize_cache(ds): - return ''.join([serialize_hash(h) for h in ds]) - -serialize_dataset = serialize_cache - -# sha3 hash function, outputs 64 bytes -def sha3_512(x): - return hash_words(lambda v: sha3.sha3_512(v).digest(), 64, x) - -def sha3_256(x): - return hash_words(lambda v: sha3.sha3_256(v).digest(), 32, x) - -def xor(a, b): - return a ^ b - -def isprime(x): - for i in range(2, int(x**0.5)): - if x % i == 0: - return False - return True -``` - -### Data Sizes - -The following lookup tables provide approximately 2048 tabulated epochs of data sizes and cache sizes. They were generated with the *Mathematica* function provided here: - -```python -def get_datasize(block_number): - return data_sizes[block_number // EPOCH_LENGTH] - -def get_cachesize(block_number): - return cache_sizes[block_number // EPOCH_LENGTH] - -data_sizes = [ -1073739904, 1082130304, 1090514816, 1098906752, 1107293056, -1115684224, 1124070016, 1132461952, 1140849536, 1149232768, -1157627776, 1166013824, 1174404736, 1182786944, 1191180416, -1199568512, 1207958912, 1216345216, 1224732032, 1233124736, -1241513344, 1249902464, 1258290304, 1266673792, 1275067264, -1283453312, 1291844992, 1300234112, 1308619904, 1317010048, -1325397376, 1333787776, 1342176128, 1350561664, 1358954368, -1367339392, 1375731584, 1384118144, 1392507008, 1400897408, -1409284736, 1417673344, 1426062464, 1434451072, 1442839168, -1451229056, 1459615616, 1468006016, 1476394112, 1484782976, -1493171584, 1501559168, 1509948032, 1518337664, 1526726528, -1535114624, 1543503488, 1551892096, 1560278656, 1568669056, -1577056384, 1585446272, 1593831296, 1602219392, 1610610304, -1619000192, 1627386752, 1635773824, 1644164224, 1652555648, -1660943488, 1669332608, 1677721216, 1686109312, 1694497664, -1702886272, 1711274624, 1719661184, 1728047744, 1736434816, -1744829056, 1753218944, 1761606272, 1769995904, 1778382464, -1786772864, 1795157888, 1803550592, 1811937664, 1820327552, -1828711552, 1837102976, 1845488768, 1853879936, 1862269312, -1870656896, 1879048064, 1887431552, 1895825024, 1904212096, -1912601216, 1920988544, 1929379456, 1937765504, 1946156672, -1954543232, 1962932096, 1971321728, 1979707264, 1988093056, -1996487552, 2004874624, 2013262208, 2021653888, 2030039936, -2038430848, 2046819968, 2055208576, 2063596672, 2071981952, -2080373632, 2088762752, 2097149056, 2105539712, 2113928576, -2122315136, 2130700672, 2139092608, 2147483264, 2155872128, -2164257664, 2172642176, 2181035392, 2189426048, 2197814912, -2206203008, 2214587264, 2222979712, 2231367808, 2239758208, -2248145024, 2256527744, 2264922752, 2273312128, 2281701248, -2290086272, 2298476672, 2306867072, 2315251072, 2323639168, -2332032128, 2340420224, 2348808064, 2357196416, 2365580416, -2373966976, 2382363008, 2390748544, 2399139968, 2407530368, -2415918976, 2424307328, 2432695424, 2441084288, 2449472384, -2457861248, 2466247808, 2474637184, 2483026816, 2491414144, -2499803776, 2508191872, 2516582272, 2524970368, 2533359232, -2541743488, 2550134144, 2558525056, 2566913408, 2575301504, -2583686528, 2592073856, 2600467328, 2608856192, 2617240448, -2625631616, 2634022016, 2642407552, 2650796416, 2659188352, -2667574912, 2675965312, 2684352896, 2692738688, 2701130624, -2709518464, 2717907328, 2726293376, 2734685056, 2743073152, -2751462016, 2759851648, 2768232832, 2776625536, 2785017728, -2793401984, 2801794432, 2810182016, 2818571648, 2826959488, -2835349376, 2843734144, 2852121472, 2860514432, 2868900992, -2877286784, 2885676928, 2894069632, 2902451584, 2910843008, -2919234688, 2927622784, 2936011648, 2944400768, 2952789376, -2961177728, 2969565568, 2977951616, 2986338944, 2994731392, -3003120256, 3011508352, 3019895936, 3028287104, 3036675968, -3045063808, 3053452928, 3061837696, 3070228352, 3078615424, -3087003776, 3095394944, 3103782272, 3112173184, 3120562048, -3128944768, 3137339264, 3145725056, 3154109312, 3162505088, -3170893184, 3179280256, 3187669376, 3196056704, 3204445568, -3212836736, 3221224064, 3229612928, 3238002304, 3246391168, -3254778496, 3263165824, 3271556224, 3279944576, 3288332416, -3296719232, 3305110912, 3313500032, 3321887104, 3330273152, -3338658944, 3347053184, 3355440512, 3363827072, 3372220288, -3380608384, 3388997504, 3397384576, 3405774208, 3414163072, -3422551936, 3430937984, 3439328384, 3447714176, 3456104576, -3464493952, 3472883584, 3481268864, 3489655168, 3498048896, -3506434432, 3514826368, 3523213952, 3531603584, 3539987072, -3548380288, 3556763264, 3565157248, 3573545344, 3581934464, -3590324096, 3598712704, 3607098752, 3615488384, 3623877248, -3632265856, 3640646528, 3649043584, 3657430144, 3665821568, -3674207872, 3682597504, 3690984832, 3699367808, 3707764352, -3716152448, 3724541056, 3732925568, 3741318016, 3749706368, -3758091136, 3766481536, 3774872704, 3783260032, 3791650432, -3800036224, 3808427648, 3816815488, 3825204608, 3833592704, -3841981568, 3850370432, 3858755968, 3867147904, 3875536256, -3883920512, 3892313728, 3900702592, 3909087872, 3917478784, -3925868416, 3934256512, 3942645376, 3951032192, 3959422336, -3967809152, 3976200064, 3984588416, 3992974976, 4001363584, -4009751168, 4018141312, 4026530432, 4034911616, 4043308928, -4051695488, 4060084352, 4068472448, 4076862848, 4085249408, -4093640576, 4102028416, 4110413696, 4118805632, 4127194496, -4135583104, 4143971968, 4152360832, 4160746112, 4169135744, -4177525888, 4185912704, 4194303616, 4202691968, 4211076736, -4219463552, 4227855488, 4236246656, 4244633728, 4253022848, -4261412224, 4269799808, 4278184832, 4286578048, 4294962304, -4303349632, 4311743104, 4320130432, 4328521088, 4336909184, -4345295488, 4353687424, 4362073472, 4370458496, 4378852736, -4387238528, 4395630208, 4404019072, 4412407424, 4420790656, -4429182848, 4437571456, 4445962112, 4454344064, 4462738048, -4471119232, 4479516544, 4487904128, 4496289664, 4504682368, -4513068416, 4521459584, 4529846144, 4538232704, 4546619776, -4555010176, 4563402112, 4571790208, 4580174464, 4588567936, -4596957056, 4605344896, 4613734016, 4622119808, 4630511488, -4638898816, 4647287936, 4655675264, 4664065664, 4672451968, -4680842624, 4689231488, 4697620352, 4706007424, 4714397056, -4722786176, 4731173248, 4739562368, 4747951744, 4756340608, -4764727936, 4773114496, 4781504384, 4789894784, 4798283648, -4806667648, 4815059584, 4823449472, 4831835776, 4840226176, -4848612224, 4857003392, 4865391488, 4873780096, 4882169728, -4890557312, 4898946944, 4907333248, 4915722368, 4924110976, -4932499328, 4940889728, 4949276032, 4957666432, 4966054784, -4974438016, 4982831488, 4991221376, 4999607168, 5007998848, -5016386432, 5024763776, 5033164672, 5041544576, 5049941888, -5058329728, 5066717056, 5075107456, 5083494272, 5091883904, -5100273536, 5108662144, 5117048192, 5125436032, 5133827456, -5142215296, 5150605184, 5158993024, 5167382144, 5175769472, -5184157568, 5192543872, 5200936064, 5209324928, 5217711232, -5226102656, 5234490496, 5242877312, 5251263872, 5259654016, -5268040832, 5276434304, 5284819328, 5293209728, 5301598592, -5309986688, 5318374784, 5326764416, 5335151488, 5343542144, -5351929472, 5360319872, 5368706944, 5377096576, 5385484928, -5393871232, 5402263424, 5410650496, 5419040384, 5427426944, -5435816576, 5444205952, 5452594816, 5460981376, 5469367936, -5477760896, 5486148736, 5494536832, 5502925952, 5511315328, -5519703424, 5528089984, 5536481152, 5544869504, 5553256064, -5561645696, 5570032768, 5578423936, 5586811264, 5595193216, -5603585408, 5611972736, 5620366208, 5628750464, 5637143936, -5645528192, 5653921408, 5662310272, 5670694784, 5679082624, -5687474048, 5695864448, 5704251008, 5712641408, 5721030272, -5729416832, 5737806208, 5746194304, 5754583936, 5762969984, -5771358592, 5779748224, 5788137856, 5796527488, 5804911232, -5813300608, 5821692544, 5830082176, 5838468992, 5846855552, -5855247488, 5863636096, 5872024448, 5880411008, 5888799872, -5897186432, 5905576832, 5913966976, 5922352768, 5930744704, -5939132288, 5947522432, 5955911296, 5964299392, 5972688256, -5981074304, 5989465472, 5997851008, 6006241408, 6014627968, -6023015552, 6031408256, 6039796096, 6048185216, 6056574848, -6064963456, 6073351808, 6081736064, 6090128768, 6098517632, -6106906496, 6115289216, 6123680896, 6132070016, 6140459648, -6148849024, 6157237376, 6165624704, 6174009728, 6182403712, -6190792064, 6199176064, 6207569792, 6215952256, 6224345216, -6232732544, 6241124224, 6249510272, 6257899136, 6266287744, -6274676864, 6283065728, 6291454336, 6299843456, 6308232064, -6316620928, 6325006208, 6333395584, 6341784704, 6350174848, -6358562176, 6366951296, 6375337856, 6383729536, 6392119168, -6400504192, 6408895616, 6417283456, 6425673344, 6434059136, -6442444672, 6450837376, 6459223424, 6467613056, 6476004224, -6484393088, 6492781952, 6501170048, 6509555072, 6517947008, -6526336384, 6534725504, 6543112832, 6551500672, 6559888768, -6568278656, 6576662912, 6585055616, 6593443456, 6601834112, -6610219648, 6618610304, 6626999168, 6635385472, 6643777408, -6652164224, 6660552832, 6668941952, 6677330048, 6685719424, -6694107776, 6702493568, 6710882176, 6719274112, 6727662976, -6736052096, 6744437632, 6752825984, 6761213824, 6769604224, -6777993856, 6786383488, 6794770816, 6803158144, 6811549312, -6819937664, 6828326528, 6836706176, 6845101696, 6853491328, -6861880448, 6870269312, 6878655104, 6887046272, 6895433344, -6903822208, 6912212864, 6920596864, 6928988288, 6937377152, -6945764992, 6954149248, 6962544256, 6970928768, 6979317376, -6987709312, 6996093824, 7004487296, 7012875392, 7021258624, -7029652352, 7038038912, 7046427776, 7054818944, 7063207808, -7071595136, 7079980928, 7088372608, 7096759424, 7105149824, -7113536896, 7121928064, 7130315392, 7138699648, 7147092352, -7155479168, 7163865728, 7172249984, 7180648064, 7189036672, -7197424768, 7205810816, 7214196608, 7222589824, 7230975104, -7239367552, 7247755904, 7256145536, 7264533376, 7272921472, -7281308032, 7289694848, 7298088832, 7306471808, 7314864512, -7323253888, 7331643008, 7340029568, 7348419712, 7356808832, -7365196672, 7373585792, 7381973888, 7390362752, 7398750592, -7407138944, 7415528576, 7423915648, 7432302208, 7440690304, -7449080192, 7457472128, 7465860992, 7474249088, 7482635648, -7491023744, 7499412608, 7507803008, 7516192384, 7524579968, -7532967296, 7541358464, 7549745792, 7558134656, 7566524032, -7574912896, 7583300992, 7591690112, 7600075136, 7608466816, -7616854912, 7625244544, 7633629824, 7642020992, 7650410368, -7658794112, 7667187328, 7675574912, 7683961984, 7692349568, -7700739712, 7709130368, 7717519232, 7725905536, 7734295424, -7742683264, 7751069056, 7759457408, 7767849088, 7776238208, -7784626816, 7793014912, 7801405312, 7809792128, 7818179968, -7826571136, 7834957184, 7843347328, 7851732352, 7860124544, -7868512384, 7876902016, 7885287808, 7893679744, 7902067072, -7910455936, 7918844288, 7927230848, 7935622784, 7944009344, -7952400256, 7960786048, 7969176704, 7977565312, 7985953408, -7994339968, 8002730368, 8011119488, 8019508096, 8027896192, -8036285056, 8044674688, 8053062272, 8061448832, 8069838464, -8078227328, 8086616704, 8095006592, 8103393664, 8111783552, -8120171392, 8128560256, 8136949376, 8145336704, 8153726848, -8162114944, 8170503296, 8178891904, 8187280768, 8195669632, -8204058496, 8212444544, 8220834176, 8229222272, 8237612672, -8246000768, 8254389376, 8262775168, 8271167104, 8279553664, -8287944064, 8296333184, 8304715136, 8313108352, 8321497984, -8329885568, 8338274432, 8346663296, 8355052928, 8363441536, -8371828352, 8380217984, 8388606592, 8396996224, 8405384576, -8413772672, 8422161536, 8430549376, 8438939008, 8447326592, -8455715456, 8464104832, 8472492928, 8480882048, 8489270656, -8497659776, 8506045312, 8514434944, 8522823808, 8531208832, -8539602304, 8547990656, 8556378752, 8564768384, 8573154176, -8581542784, 8589933952, 8598322816, 8606705024, 8615099264, -8623487872, 8631876992, 8640264064, 8648653952, 8657040256, -8665430656, 8673820544, 8682209152, 8690592128, 8698977152, -8707374464, 8715763328, 8724151424, 8732540032, 8740928384, -8749315712, 8757704576, 8766089344, 8774480768, 8782871936, -8791260032, 8799645824, 8808034432, 8816426368, 8824812928, -8833199488, 8841591424, 8849976448, 8858366336, 8866757248, -8875147136, 8883532928, 8891923328, 8900306816, 8908700288, -8917088384, 8925478784, 8933867392, 8942250368, 8950644608, -8959032704, 8967420544, 8975809664, 8984197504, 8992584064, -9000976256, 9009362048, 9017752448, 9026141312, 9034530688, -9042917504, 9051307904, 9059694208, 9068084864, 9076471424, -9084861824, 9093250688, 9101638528, 9110027648, 9118416512, -9126803584, 9135188096, 9143581312, 9151969664, 9160356224, -9168747136, 9177134464, 9185525632, 9193910144, 9202302848, -9210690688, 9219079552, 9227465344, 9235854464, 9244244864, -9252633472, 9261021824, 9269411456, 9277799296, 9286188928, -9294574208, 9302965888, 9311351936, 9319740032, 9328131968, -9336516736, 9344907392, 9353296768, 9361685888, 9370074752, -9378463616, 9386849408, 9395239808, 9403629184, 9412016512, -9420405376, 9428795008, 9437181568, 9445570688, 9453960832, -9462346624, 9470738048, 9479121536, 9487515008, 9495903616, -9504289664, 9512678528, 9521067904, 9529456256, 9537843584, -9546233728, 9554621312, 9563011456, 9571398784, 9579788672, -9588178304, 9596567168, 9604954496, 9613343104, 9621732992, -9630121856, 9638508416, 9646898816, 9655283584, 9663675776, -9672061312, 9680449664, 9688840064, 9697230464, 9705617536, -9714003584, 9722393984, 9730772608, 9739172224, 9747561088, -9755945344, 9764338816, 9772726144, 9781116544, 9789503872, -9797892992, 9806282624, 9814670464, 9823056512, 9831439232, -9839833984, 9848224384, 9856613504, 9865000576, 9873391232, -9881772416, 9890162816, 9898556288, 9906940544, 9915333248, -9923721088, 9932108672, 9940496512, 9948888448, 9957276544, -9965666176, 9974048384, 9982441088, 9990830464, 9999219584, -10007602816, 10015996544, 10024385152, 10032774016, 10041163648, -10049548928, 10057940096, 10066329472, 10074717824, 10083105152, -10091495296, 10099878784, 10108272256, 10116660608, 10125049216, -10133437312, 10141825664, 10150213504, 10158601088, 10166991232, -10175378816, 10183766144, 10192157312, 10200545408, 10208935552, -10217322112, 10225712768, 10234099328, 10242489472, 10250876032, -10259264896, 10267656064, 10276042624, 10284429184, 10292820352, -10301209472, 10309598848, 10317987712, 10326375296, 10334763392, -10343153536, 10351541632, 10359930752, 10368318592, 10376707456, -10385096576, 10393484672, 10401867136, 10410262144, 10418647424, -10427039104, 10435425664, 10443810176, 10452203648, 10460589952, -10468982144, 10477369472, 10485759104, 10494147712, 10502533504, -10510923392, 10519313536, 10527702656, 10536091264, 10544478592, -10552867712, 10561255808, 10569642368, 10578032768, 10586423168, -10594805632, 10603200128, 10611588992, 10619976064, 10628361344, -10636754048, 10645143424, 10653531776, 10661920384, 10670307968, -10678696832, 10687086464, 10695475072, 10703863168, 10712246144, -10720639616, 10729026688, 10737414784, 10745806208, 10754190976, -10762581376, 10770971264, 10779356288, 10787747456, 10796135552, -10804525184, 10812915584, 10821301888, 10829692288, 10838078336, -10846469248, 10854858368, 10863247232, 10871631488, 10880023424, -10888412032, 10896799616, 10905188992, 10913574016, 10921964672, -10930352768, 10938742912, 10947132544, 10955518592, 10963909504, -10972298368, 10980687488, 10989074816, 10997462912, 11005851776, -11014241152, 11022627712, 11031017344, 11039403904, 11047793024, -11056184704, 11064570752, 11072960896, 11081343872, 11089737856, -11098128256, 11106514816, 11114904448, 11123293568, 11131680128, -11140065152, 11148458368, 11156845696, 11165236864, 11173624192, -11182013824, 11190402688, 11198790784, 11207179136, 11215568768, -11223957376, 11232345728, 11240734592, 11249122688, 11257511296, -11265899648, 11274285952, 11282675584, 11291065472, 11299452544, -11307842432, 11316231296, 11324616832, 11333009024, 11341395584, -11349782656, 11358172288, 11366560384, 11374950016, 11383339648, -11391721856, 11400117376, 11408504192, 11416893568, 11425283456, -11433671552, 11442061184, 11450444672, 11458837888, 11467226752, -11475611776, 11484003968, 11492392064, 11500780672, 11509169024, -11517550976, 11525944448, 11534335616, 11542724224, 11551111808, -11559500672, 11567890304, 11576277376, 11584667008, 11593056128, -11601443456, 11609830016, 11618221952, 11626607488, 11634995072, -11643387776, 11651775104, 11660161664, 11668552576, 11676940928, -11685330304, 11693718656, 11702106496, 11710496128, 11718882688, -11727273088, 11735660416, 11744050048, 11752437376, 11760824704, -11769216128, 11777604736, 11785991296, 11794381952, 11802770048, -11811157888, 11819548544, 11827932544, 11836324736, 11844713344, -11853100928, 11861486464, 11869879936, 11878268032, 11886656896, -11895044992, 11903433088, 11911822976, 11920210816, 11928600448, -11936987264, 11945375872, 11953761152, 11962151296, 11970543488, -11978928512, 11987320448, 11995708288, 12004095104, 12012486272, -12020875136, 12029255552, 12037652096, 12046039168, 12054429568, -12062813824, 12071206528, 12079594624, 12087983744, 12096371072, -12104759936, 12113147264, 12121534592, 12129924992, 12138314624, -12146703232, 12155091584, 12163481216, 12171864704, 12180255872, -12188643968, 12197034112, 12205424512, 12213811328, 12222199424, -12230590336, 12238977664, 12247365248, 12255755392, 12264143488, -12272531584, 12280920448, 12289309568, 12297694592, 12306086528, -12314475392, 12322865024, 12331253632, 12339640448, 12348029312, -12356418944, 12364805248, 12373196672, 12381580928, 12389969024, -12398357632, 12406750592, 12415138432, 12423527552, 12431916416, -12440304512, 12448692352, 12457081216, 12465467776, 12473859968, -12482245504, 12490636672, 12499025536, 12507411584, 12515801728, -12524190592, 12532577152, 12540966272, 12549354368, 12557743232, -12566129536, 12574523264, 12582911872, 12591299456, 12599688064, -12608074624, 12616463488, 12624845696, 12633239936, 12641631616, -12650019968, 12658407296, 12666795136, 12675183232, 12683574656, -12691960192, 12700350592, 12708740224, 12717128576, 12725515904, -12733906816, 12742295168, 12750680192, 12759071872, 12767460736, -12775848832, 12784236928, 12792626816, 12801014656, 12809404288, -12817789312, 12826181504, 12834568832, 12842954624, 12851345792, -12859732352, 12868122496, 12876512128, 12884901248, 12893289088, -12901672832, 12910067584, 12918455168, 12926842496, 12935232896, -12943620736, 12952009856, 12960396928, 12968786816, 12977176192, -12985563776, 12993951104, 13002341504, 13010730368, 13019115392, -13027506304, 13035895168, 13044272512, 13052673152, 13061062528, -13069446272, 13077838976, 13086227072, 13094613632, 13103000192, -13111393664, 13119782528, 13128157568, 13136559232, 13144945024, -13153329536, 13161724288, 13170111872, 13178502784, 13186884736, -13195279744, 13203667072, 13212057472, 13220445824, 13228832128, -13237221248, 13245610624, 13254000512, 13262388352, 13270777472, -13279166336, 13287553408, 13295943296, 13304331904, 13312719488, -13321108096, 13329494656, 13337885824, 13346274944, 13354663808, -13363051136, 13371439232, 13379825024, 13388210816, 13396605056, -13404995456, 13413380224, 13421771392, 13430159744, 13438546048, -13446937216, 13455326848, 13463708288, 13472103808, 13480492672, -13488875648, 13497269888, 13505657728, 13514045312, 13522435712, -13530824576, 13539210112, 13547599232, 13555989376, 13564379008, -13572766336, 13581154432, 13589544832, 13597932928, 13606320512, -13614710656, 13623097472, 13631477632, 13639874944, 13648264064, -13656652928, 13665041792, 13673430656, 13681818496, 13690207616, -13698595712, 13706982272, 13715373184, 13723762048, 13732150144, -13740536704, 13748926592, 13757316224, 13765700992, 13774090112, -13782477952, 13790869376, 13799259008, 13807647872, 13816036736, -13824425344, 13832814208, 13841202304, 13849591424, 13857978752, -13866368896, 13874754688, 13883145344, 13891533184, 13899919232, -13908311168, 13916692096, 13925085056, 13933473152, 13941866368, -13950253696, 13958643584, 13967032192, 13975417216, 13983807616, -13992197504, 14000582272, 14008973696, 14017363072, 14025752192, -14034137984, 14042528384, 14050918016, 14059301504, 14067691648, -14076083584, 14084470144, 14092852352, 14101249664, 14109635968, -14118024832, 14126407552, 14134804352, 14143188608, 14151577984, -14159968384, 14168357248, 14176741504, 14185127296, 14193521024, -14201911424, 14210301824, 14218685056, 14227067264, 14235467392, -14243855488, 14252243072, 14260630144, 14269021568, 14277409408, -14285799296, 14294187904, 14302571392, 14310961792, 14319353728, -14327738752, 14336130944, 14344518784, 14352906368, 14361296512, -14369685376, 14378071424, 14386462592, 14394848128, 14403230848, -14411627392, 14420013952, 14428402304, 14436793472, 14445181568, -14453569664, 14461959808, 14470347904, 14478737024, 14487122816, -14495511424, 14503901824, 14512291712, 14520677504, 14529064832, -14537456768, 14545845632, 14554234496, 14562618496, 14571011456, -14579398784, 14587789184, 14596172672, 14604564608, 14612953984, -14621341312, 14629724288, 14638120832, 14646503296, 14654897536, -14663284864, 14671675264, 14680061056, 14688447616, 14696835968, -14705228416, 14713616768, 14722003328, 14730392192, 14738784128, -14747172736, 14755561088, 14763947648, 14772336512, 14780725376, -14789110144, 14797499776, 14805892736, 14814276992, 14822670208, -14831056256, 14839444352, 14847836032, 14856222848, 14864612992, -14872997504, 14881388672, 14889775744, 14898165376, 14906553472, -14914944896, 14923329664, 14931721856, 14940109696, 14948497024, -14956887424, 14965276544, 14973663616, 14982053248, 14990439808, -14998830976, 15007216768, 15015605888, 15023995264, 15032385152, -15040768384, 15049154944, 15057549184, 15065939072, 15074328448, -15082715008, 15091104128, 15099493504, 15107879296, 15116269184, -15124659584, 15133042304, 15141431936, 15149824384, 15158214272, -15166602368, 15174991232, 15183378304, 15191760512, 15200154496, -15208542592, 15216931712, 15225323392, 15233708416, 15242098048, -15250489216, 15258875264, 15267265408, 15275654528, 15284043136, -15292431488, 15300819584, 15309208192, 15317596544, 15325986176, -15334374784, 15342763648, 15351151744, 15359540608, 15367929728, -15376318336, 15384706432, 15393092992, 15401481856, 15409869952, -15418258816, 15426649984, 15435037568, 15443425664, 15451815296, -15460203392, 15468589184, 15476979328, 15485369216, 15493755776, -15502146944, 15510534272, 15518924416, 15527311232, 15535699072, -15544089472, 15552478336, 15560866688, 15569254528, 15577642624, -15586031488, 15594419072, 15602809472, 15611199104, 15619586432, -15627975296, 15636364928, 15644753792, 15653141888, 15661529216, -15669918848, 15678305152, 15686696576, 15695083136, 15703474048, -15711861632, 15720251264, 15728636288, 15737027456, 15745417088, -15753804928, 15762194048, 15770582656, 15778971008, 15787358336, -15795747712, 15804132224, 15812523392, 15820909696, 15829300096, -15837691264, 15846071936, 15854466944, 15862855808, 15871244672, -15879634816, 15888020608, 15896409728, 15904799104, 15913185152, -15921577088, 15929966464, 15938354816, 15946743424, 15955129472, -15963519872, 15971907968, 15980296064, 15988684928, 15997073024, -16005460864, 16013851264, 16022241152, 16030629248, 16039012736, -16047406976, 16055794816, 16064181376, 16072571264, 16080957824, -16089346688, 16097737856, 16106125184, 16114514816, 16122904192, -16131292544, 16139678848, 16148066944, 16156453504, 16164839552, -16173236096, 16181623424, 16190012032, 16198401152, 16206790528, -16215177344, 16223567744, 16231956352, 16240344704, 16248731008, -16257117824, 16265504384, 16273898624, 16282281856, 16290668672, -16299064192, 16307449216, 16315842176, 16324230016, 16332613504, -16341006464, 16349394304, 16357783168, 16366172288, 16374561664, -16382951296, 16391337856, 16399726208, 16408116352, 16416505472, -16424892032, 16433282176, 16441668224, 16450058624, 16458448768, -16466836864, 16475224448, 16483613056, 16492001408, 16500391808, -16508779648, 16517166976, 16525555328, 16533944192, 16542330752, -16550719616, 16559110528, 16567497088, 16575888512, 16584274816, -16592665472, 16601051008, 16609442944, 16617832064, 16626218624, -16634607488, 16642996096, 16651385728, 16659773824, 16668163712, -16676552576, 16684938112, 16693328768, 16701718144, 16710095488, -16718492288, 16726883968, 16735272832, 16743661184, 16752049792, -16760436608, 16768827008, 16777214336, 16785599104, 16793992832, -16802381696, 16810768768, 16819151744, 16827542656, 16835934848, -16844323712, 16852711552, 16861101952, 16869489536, 16877876864, -16886265728, 16894653056, 16903044736, 16911431296, 16919821696, -16928207488, 16936592768, 16944987776, 16953375616, 16961763968, -16970152832, 16978540928, 16986929536, 16995319168, 17003704448, -17012096896, 17020481152, 17028870784, 17037262208, 17045649536, -17054039936, 17062426496, 17070814336, 17079205504, 17087592064, -17095978112, 17104369024, 17112759424, 17121147776, 17129536384, -17137926016, 17146314368, 17154700928, 17163089792, 17171480192, -17179864192, 17188256896, 17196644992, 17205033856, 17213423488, -17221811072, 17230198912, 17238588032, 17246976896, 17255360384, -17263754624, 17272143232, 17280530048, 17288918912, 17297309312, -17305696384, 17314085504, 17322475136, 17330863744, 17339252096, -17347640192, 17356026496, 17364413824, 17372796544, 17381190016, -17389583488, 17397972608, 17406360704, 17414748544, 17423135872, -17431527296, 17439915904, 17448303232, 17456691584, 17465081728, -17473468288, 17481857408, 17490247552, 17498635904, 17507022464, -17515409024, 17523801728, 17532189824, 17540577664, 17548966016, -17557353344, 17565741184, 17574131584, 17582519168, 17590907008, -17599296128, 17607687808, 17616076672, 17624455808, 17632852352, -17641238656, 17649630848, 17658018944, 17666403968, 17674794112, -17683178368, 17691573376, 17699962496, 17708350592, 17716739968, -17725126528, 17733517184, 17741898112, 17750293888, 17758673024, -17767070336, 17775458432, 17783848832, 17792236928, 17800625536, -17809012352, 17817402752, 17825785984, 17834178944, 17842563968, -17850955648, 17859344512, 17867732864, 17876119424, 17884511872, -17892900224, 17901287296, 17909677696, 17918058112, 17926451072, -17934843776, 17943230848, 17951609216, 17960008576, 17968397696, -17976784256, 17985175424, 17993564032, 18001952128, 18010339712, -18018728576, 18027116672, 18035503232, 18043894144, 18052283264, -18060672128, 18069056384, 18077449856, 18085837184, 18094225792, -18102613376, 18111004544, 18119388544, 18127781248, 18136170368, -18144558976, 18152947328, 18161336192, 18169724288, 18178108544, -18186498944, 18194886784, 18203275648, 18211666048, 18220048768, -18228444544, 18236833408, 18245220736] - -cache_sizes = [ -16776896, 16907456, 17039296, 17170112, 17301056, 17432512, 17563072, -17693888, 17824192, 17955904, 18087488, 18218176, 18349504, 18481088, -18611392, 18742336, 18874304, 19004224, 19135936, 19267264, 19398208, -19529408, 19660096, 19791424, 19922752, 20053952, 20184896, 20315968, -20446912, 20576576, 20709184, 20840384, 20971072, 21102272, 21233216, -21364544, 21494848, 21626816, 21757376, 21887552, 22019392, 22151104, -22281536, 22412224, 22543936, 22675264, 22806464, 22935872, 23068096, -23198272, 23330752, 23459008, 23592512, 23723968, 23854912, 23986112, -24116672, 24247616, 24378688, 24509504, 24640832, 24772544, 24903488, -25034432, 25165376, 25296704, 25427392, 25558592, 25690048, 25820096, -25951936, 26081728, 26214208, 26345024, 26476096, 26606656, 26737472, -26869184, 26998208, 27131584, 27262528, 27393728, 27523904, 27655744, -27786688, 27917888, 28049344, 28179904, 28311488, 28441792, 28573504, -28700864, 28835648, 28966208, 29096768, 29228608, 29359808, 29490752, -29621824, 29752256, 29882816, 30014912, 30144448, 30273728, 30406976, -30538432, 30670784, 30799936, 30932672, 31063744, 31195072, 31325248, -31456192, 31588288, 31719232, 31850432, 31981504, 32110784, 32243392, -32372672, 32505664, 32636608, 32767808, 32897344, 33029824, 33160768, -33289664, 33423296, 33554368, 33683648, 33816512, 33947456, 34076992, -34208704, 34340032, 34471744, 34600256, 34734016, 34864576, 34993984, -35127104, 35258176, 35386688, 35518528, 35650624, 35782336, 35910976, -36044608, 36175808, 36305728, 36436672, 36568384, 36699968, 36830656, -36961984, 37093312, 37223488, 37355072, 37486528, 37617472, 37747904, -37879232, 38009792, 38141888, 38272448, 38403392, 38535104, 38660672, -38795584, 38925632, 39059264, 39190336, 39320768, 39452096, 39581632, -39713984, 39844928, 39974848, 40107968, 40238144, 40367168, 40500032, -40631744, 40762816, 40894144, 41023552, 41155904, 41286208, 41418304, -41547712, 41680448, 41811904, 41942848, 42073792, 42204992, 42334912, -42467008, 42597824, 42729152, 42860096, 42991552, 43122368, 43253696, -43382848, 43515712, 43646912, 43777088, 43907648, 44039104, 44170432, -44302144, 44433344, 44564288, 44694976, 44825152, 44956864, 45088448, -45219008, 45350464, 45481024, 45612608, 45744064, 45874496, 46006208, -46136768, 46267712, 46399424, 46529344, 46660672, 46791488, 46923328, -47053504, 47185856, 47316928, 47447872, 47579072, 47710144, 47839936, -47971648, 48103232, 48234176, 48365248, 48496192, 48627136, 48757312, -48889664, 49020736, 49149248, 49283008, 49413824, 49545152, 49675712, -49807168, 49938368, 50069056, 50200256, 50331584, 50462656, 50593472, -50724032, 50853952, 50986048, 51117632, 51248576, 51379904, 51510848, -51641792, 51773248, 51903296, 52035136, 52164032, 52297664, 52427968, -52557376, 52690112, 52821952, 52952896, 53081536, 53213504, 53344576, -53475776, 53608384, 53738816, 53870528, 54000832, 54131776, 54263744, -54394688, 54525248, 54655936, 54787904, 54918592, 55049152, 55181248, -55312064, 55442752, 55574336, 55705024, 55836224, 55967168, 56097856, -56228672, 56358592, 56490176, 56621888, 56753728, 56884928, 57015488, -57146816, 57278272, 57409216, 57540416, 57671104, 57802432, 57933632, -58064576, 58195264, 58326976, 58457408, 58588864, 58720192, 58849984, -58981696, 59113024, 59243456, 59375552, 59506624, 59637568, 59768512, -59897792, 60030016, 60161984, 60293056, 60423872, 60554432, 60683968, -60817216, 60948032, 61079488, 61209664, 61341376, 61471936, 61602752, -61733696, 61865792, 61996736, 62127808, 62259136, 62389568, 62520512, -62651584, 62781632, 62910784, 63045056, 63176128, 63307072, 63438656, -63569216, 63700928, 63831616, 63960896, 64093888, 64225088, 64355392, -64486976, 64617664, 64748608, 64879424, 65009216, 65142464, 65273792, -65402816, 65535424, 65666752, 65797696, 65927744, 66060224, 66191296, -66321344, 66453056, 66584384, 66715328, 66846656, 66977728, 67108672, -67239104, 67370432, 67501888, 67631296, 67763776, 67895104, 68026304, -68157248, 68287936, 68419264, 68548288, 68681408, 68811968, 68942912, -69074624, 69205568, 69337024, 69467584, 69599168, 69729472, 69861184, -69989824, 70122944, 70253888, 70385344, 70515904, 70647232, 70778816, -70907968, 71040832, 71171648, 71303104, 71432512, 71564992, 71695168, -71826368, 71958464, 72089536, 72219712, 72350144, 72482624, 72613568, -72744512, 72875584, 73006144, 73138112, 73268672, 73400128, 73530944, -73662272, 73793344, 73924544, 74055104, 74185792, 74316992, 74448832, -74579392, 74710976, 74841664, 74972864, 75102784, 75233344, 75364544, -75497024, 75627584, 75759296, 75890624, 76021696, 76152256, 76283072, -76414144, 76545856, 76676672, 76806976, 76937792, 77070016, 77200832, -77331392, 77462464, 77593664, 77725376, 77856448, 77987776, 78118336, -78249664, 78380992, 78511424, 78642496, 78773056, 78905152, 79033664, -79166656, 79297472, 79429568, 79560512, 79690816, 79822784, 79953472, -80084672, 80214208, 80346944, 80477632, 80608576, 80740288, 80870848, -81002048, 81133504, 81264448, 81395648, 81525952, 81657536, 81786304, -81919808, 82050112, 82181312, 82311616, 82443968, 82573376, 82705984, -82835776, 82967744, 83096768, 83230528, 83359552, 83491264, 83622464, -83753536, 83886016, 84015296, 84147776, 84277184, 84409792, 84540608, -84672064, 84803008, 84934336, 85065152, 85193792, 85326784, 85458496, -85589312, 85721024, 85851968, 85982656, 86112448, 86244416, 86370112, -86506688, 86637632, 86769344, 86900672, 87031744, 87162304, 87293632, -87424576, 87555392, 87687104, 87816896, 87947968, 88079168, 88211264, -88341824, 88473152, 88603712, 88735424, 88862912, 88996672, 89128384, -89259712, 89390272, 89521984, 89652544, 89783872, 89914816, 90045376, -90177088, 90307904, 90438848, 90569152, 90700096, 90832832, 90963776, -91093696, 91223744, 91356992, 91486784, 91618496, 91749824, 91880384, -92012224, 92143552, 92273344, 92405696, 92536768, 92666432, 92798912, -92926016, 93060544, 93192128, 93322816, 93453632, 93583936, 93715136, -93845056, 93977792, 94109504, 94240448, 94371776, 94501184, 94632896, -94764224, 94895552, 95023424, 95158208, 95287744, 95420224, 95550016, -95681216, 95811904, 95943872, 96075328, 96203584, 96337856, 96468544, -96599744, 96731072, 96860992, 96992576, 97124288, 97254848, 97385536, -97517248, 97647808, 97779392, 97910464, 98041408, 98172608, 98303168, -98434496, 98565568, 98696768, 98827328, 98958784, 99089728, 99220928, -99352384, 99482816, 99614272, 99745472, 99876416, 100007104, -100138048, 100267072, 100401088, 100529984, 100662592, 100791872, -100925248, 101056064, 101187392, 101317952, 101449408, 101580608, -101711296, 101841728, 101973824, 102104896, 102235712, 102366016, -102498112, 102628672, 102760384, 102890432, 103021888, 103153472, -103284032, 103415744, 103545152, 103677248, 103808576, 103939648, -104070976, 104201792, 104332736, 104462528, 104594752, 104725952, -104854592, 104988608, 105118912, 105247808, 105381184, 105511232, -105643072, 105774784, 105903296, 106037056, 106167872, 106298944, -106429504, 106561472, 106691392, 106822592, 106954304, 107085376, -107216576, 107346368, 107478464, 107609792, 107739712, 107872192, -108003136, 108131392, 108265408, 108396224, 108527168, 108657344, -108789568, 108920384, 109049792, 109182272, 109312576, 109444928, -109572928, 109706944, 109837888, 109969088, 110099648, 110230976, -110362432, 110492992, 110624704, 110755264, 110886208, 111017408, -111148864, 111279296, 111410752, 111541952, 111673024, 111803456, -111933632, 112066496, 112196416, 112328512, 112457792, 112590784, -112715968, 112852672, 112983616, 113114944, 113244224, 113376448, -113505472, 113639104, 113770304, 113901376, 114031552, 114163264, -114294592, 114425536, 114556864, 114687424, 114818624, 114948544, -115080512, 115212224, 115343296, 115473472, 115605184, 115736128, -115867072, 115997248, 116128576, 116260288, 116391488, 116522944, -116652992, 116784704, 116915648, 117046208, 117178304, 117308608, -117440192, 117569728, 117701824, 117833024, 117964096, 118094656, -118225984, 118357312, 118489024, 118617536, 118749632, 118882112, -119012416, 119144384, 119275328, 119406016, 119537344, 119668672, -119798464, 119928896, 120061376, 120192832, 120321728, 120454336, -120584512, 120716608, 120848192, 120979136, 121109056, 121241408, -121372352, 121502912, 121634752, 121764416, 121895744, 122027072, -122157632, 122289088, 122421184, 122550592, 122682944, 122813888, -122945344, 123075776, 123207488, 123338048, 123468736, 123600704, -123731264, 123861952, 123993664, 124124608, 124256192, 124386368, -124518208, 124649024, 124778048, 124911296, 125041088, 125173696, -125303744, 125432896, 125566912, 125696576, 125829056, 125958592, -126090304, 126221248, 126352832, 126483776, 126615232, 126746432, -126876608, 127008704, 127139392, 127270336, 127401152, 127532224, -127663552, 127794752, 127925696, 128055232, 128188096, 128319424, -128449856, 128581312, 128712256, 128843584, 128973632, 129103808, -129236288, 129365696, 129498944, 129629888, 129760832, 129892288, -130023104, 130154048, 130283968, 130416448, 130547008, 130678336, -130807616, 130939456, 131071552, 131202112, 131331776, 131464384, -131594048, 131727296, 131858368, 131987392, 132120256, 132250816, -132382528, 132513728, 132644672, 132774976, 132905792, 133038016, -133168832, 133299392, 133429312, 133562048, 133692992, 133823296, -133954624, 134086336, 134217152, 134348608, 134479808, 134607296, -134741056, 134872384, 135002944, 135134144, 135265472, 135396544, -135527872, 135659072, 135787712, 135921472, 136052416, 136182848, -136313792, 136444864, 136576448, 136707904, 136837952, 136970048, -137099584, 137232064, 137363392, 137494208, 137625536, 137755712, -137887424, 138018368, 138149824, 138280256, 138411584, 138539584, -138672832, 138804928, 138936128, 139066688, 139196864, 139328704, -139460032, 139590208, 139721024, 139852864, 139984576, 140115776, -140245696, 140376512, 140508352, 140640064, 140769856, 140902336, -141032768, 141162688, 141294016, 141426496, 141556544, 141687488, -141819584, 141949888, 142080448, 142212544, 142342336, 142474432, -142606144, 142736192, 142868288, 142997824, 143129408, 143258944, -143392448, 143523136, 143653696, 143785024, 143916992, 144045632, -144177856, 144309184, 144440768, 144570688, 144701888, 144832448, -144965056, 145096384, 145227584, 145358656, 145489856, 145620928, -145751488, 145883072, 146011456, 146144704, 146275264, 146407232, -146538176, 146668736, 146800448, 146931392, 147062336, 147193664, -147324224, 147455936, 147586624, 147717056, 147848768, 147979456, -148110784, 148242368, 148373312, 148503232, 148635584, 148766144, -148897088, 149028416, 149159488, 149290688, 149420224, 149551552, -149683136, 149814976, 149943616, 150076352, 150208064, 150338624, -150470464, 150600256, 150732224, 150862784, 150993088, 151125952, -151254976, 151388096, 151519168, 151649728, 151778752, 151911104, -152042944, 152174144, 152304704, 152435648, 152567488, 152698816, -152828992, 152960576, 153091648, 153222976, 153353792, 153484096, -153616192, 153747008, 153878336, 154008256, 154139968, 154270912, -154402624, 154533824, 154663616, 154795712, 154926272, 155057984, -155188928, 155319872, 155450816, 155580608, 155712064, 155843392, -155971136, 156106688, 156237376, 156367424, 156499264, 156630976, -156761536, 156892352, 157024064, 157155008, 157284416, 157415872, -157545536, 157677248, 157810496, 157938112, 158071744, 158203328, -158334656, 158464832, 158596288, 158727616, 158858048, 158988992, -159121216, 159252416, 159381568, 159513152, 159645632, 159776192, -159906496, 160038464, 160169536, 160300352, 160430656, 160563008, -160693952, 160822208, 160956352, 161086784, 161217344, 161349184, -161480512, 161611456, 161742272, 161873216, 162002752, 162135872, -162266432, 162397888, 162529216, 162660032, 162790976, 162922048, -163052096, 163184576, 163314752, 163446592, 163577408, 163707968, -163839296, 163969984, 164100928, 164233024, 164364224, 164494912, -164625856, 164756672, 164887616, 165019072, 165150016, 165280064, -165412672, 165543104, 165674944, 165805888, 165936832, 166067648, -166198336, 166330048, 166461248, 166591552, 166722496, 166854208, -166985408, 167116736, 167246656, 167378368, 167508416, 167641024, -167771584, 167903168, 168034112, 168164032, 168295744, 168427456, -168557632, 168688448, 168819136, 168951616, 169082176, 169213504, -169344832, 169475648, 169605952, 169738048, 169866304, 169999552, -170131264, 170262464, 170393536, 170524352, 170655424, 170782016, -170917696, 171048896, 171179072, 171310784, 171439936, 171573184, -171702976, 171835072, 171966272, 172097216, 172228288, 172359232, -172489664, 172621376, 172747712, 172883264, 173014208, 173144512, -173275072, 173407424, 173539136, 173669696, 173800768, 173931712, -174063424, 174193472, 174325696, 174455744, 174586816, 174718912, -174849728, 174977728, 175109696, 175242688, 175374272, 175504832, -175636288, 175765696, 175898432, 176028992, 176159936, 176291264, -176422592, 176552512, 176684864, 176815424, 176946496, 177076544, -177209152, 177340096, 177470528, 177600704, 177731648, 177864256, -177994816, 178126528, 178257472, 178387648, 178518464, 178650176, -178781888, 178912064, 179044288, 179174848, 179305024, 179436736, -179568448, 179698496, 179830208, 179960512, 180092608, 180223808, -180354752, 180485696, 180617152, 180748096, 180877504, 181009984, -181139264, 181272512, 181402688, 181532608, 181663168, 181795136, -181926592, 182057536, 182190016, 182320192, 182451904, 182582336, -182713792, 182843072, 182976064, 183107264, 183237056, 183368384, -183494848, 183631424, 183762752, 183893824, 184024768, 184154816, -184286656, 184417984, 184548928, 184680128, 184810816, 184941248, -185072704, 185203904, 185335616, 185465408, 185596352, 185727296, -185859904, 185989696, 186121664, 186252992, 186383552, 186514112, -186645952, 186777152, 186907328, 187037504, 187170112, 187301824, -187429184, 187562048, 187693504, 187825472, 187957184, 188087104, -188218304, 188349376, 188481344, 188609728, 188743616, 188874304, -189005248, 189136448, 189265088, 189396544, 189528128, 189660992, -189791936, 189923264, 190054208, 190182848, 190315072, 190447424, -190577984, 190709312, 190840768, 190971328, 191102656, 191233472, -191364032, 191495872, 191626816, 191758016, 191888192, 192020288, -192148928, 192282176, 192413504, 192542528, 192674752, 192805952, -192937792, 193068608, 193198912, 193330496, 193462208, 193592384, -193723456, 193854272, 193985984, 194116672, 194247232, 194379712, -194508352, 194641856, 194772544, 194900672, 195035072, 195166016, -195296704, 195428032, 195558592, 195690304, 195818176, 195952576, -196083392, 196214336, 196345792, 196476736, 196607552, 196739008, -196869952, 197000768, 197130688, 197262784, 197394368, 197523904, -197656384, 197787584, 197916608, 198049472, 198180544, 198310208, -198442432, 198573632, 198705088, 198834368, 198967232, 199097792, -199228352, 199360192, 199491392, 199621696, 199751744, 199883968, -200014016, 200146624, 200276672, 200408128, 200540096, 200671168, -200801984, 200933312, 201062464, 201194944, 201326144, 201457472, -201588544, 201719744, 201850816, 201981632, 202111552, 202244032, -202374464, 202505152, 202636352, 202767808, 202898368, 203030336, -203159872, 203292608, 203423296, 203553472, 203685824, 203816896, -203947712, 204078272, 204208192, 204341056, 204472256, 204603328, -204733888, 204864448, 204996544, 205125568, 205258304, 205388864, -205517632, 205650112, 205782208, 205913536, 206044736, 206176192, -206307008, 206434496, 206569024, 206700224, 206831168, 206961856, -207093056, 207223616, 207355328, 207486784, 207616832, 207749056, -207879104, 208010048, 208141888, 208273216, 208404032, 208534336, -208666048, 208796864, 208927424, 209059264, 209189824, 209321792, -209451584, 209582656, 209715136, 209845568, 209976896, 210106432, -210239296, 210370112, 210501568, 210630976, 210763712, 210894272, -211024832, 211156672, 211287616, 211418176, 211549376, 211679296, -211812032, 211942592, 212074432, 212204864, 212334016, 212467648, -212597824, 212727616, 212860352, 212991424, 213120832, 213253952, -213385024, 213515584, 213645632, 213777728, 213909184, 214040128, -214170688, 214302656, 214433728, 214564544, 214695232, 214826048, -214956992, 215089088, 215219776, 215350592, 215482304, 215613248, -215743552, 215874752, 216005312, 216137024, 216267328, 216399296, -216530752, 216661696, 216790592, 216923968, 217054528, 217183168, -217316672, 217448128, 217579072, 217709504, 217838912, 217972672, -218102848, 218233024, 218364736, 218496832, 218627776, 218759104, -218888896, 219021248, 219151936, 219281728, 219413056, 219545024, -219675968, 219807296, 219938624, 220069312, 220200128, 220331456, -220461632, 220592704, 220725184, 220855744, 220987072, 221117888, -221249216, 221378368, 221510336, 221642048, 221772736, 221904832, -222031808, 222166976, 222297536, 222428992, 222559936, 222690368, -222820672, 222953152, 223083968, 223213376, 223345984, 223476928, -223608512, 223738688, 223869376, 224001472, 224132672, 224262848, -224394944, 224524864, 224657344, 224788288, 224919488, 225050432, -225181504, 225312704, 225443776, 225574592, 225704768, 225834176, -225966784, 226097216, 226229824, 226360384, 226491712, 226623424, -226754368, 226885312, 227015104, 227147456, 227278528, 227409472, -227539904, 227669696, 227802944, 227932352, 228065216, 228196288, -228326464, 228457792, 228588736, 228720064, 228850112, 228981056, -229113152, 229243328, 229375936, 229505344, 229636928, 229769152, -229894976, 230030272, 230162368, 230292416, 230424512, 230553152, -230684864, 230816704, 230948416, 231079616, 231210944, 231342016, -231472448, 231603776, 231733952, 231866176, 231996736, 232127296, -232259392, 232388672, 232521664, 232652608, 232782272, 232914496, -233043904, 233175616, 233306816, 233438528, 233569984, 233699776, -233830592, 233962688, 234092224, 234221888, 234353984, 234485312, -234618304, 234749888, 234880832, 235011776, 235142464, 235274048, -235403456, 235535936, 235667392, 235797568, 235928768, 236057152, -236190272, 236322752, 236453312, 236583616, 236715712, 236846528, -236976448, 237108544, 237239104, 237371072, 237501632, 237630784, -237764416, 237895232, 238026688, 238157632, 238286912, 238419392, -238548032, 238681024, 238812608, 238941632, 239075008, 239206336, -239335232, 239466944, 239599168, 239730496, 239861312, 239992384, -240122816, 240254656, 240385856, 240516928, 240647872, 240779072, -240909632, 241040704, 241171904, 241302848, 241433408, 241565248, -241696192, 241825984, 241958848, 242088256, 242220224, 242352064, -242481856, 242611648, 242744896, 242876224, 243005632, 243138496, -243268672, 243400384, 243531712, 243662656, 243793856, 243924544, -244054592, 244187072, 244316608, 244448704, 244580032, 244710976, -244841536, 244972864, 245104448, 245233984, 245365312, 245497792, -245628736, 245759936, 245889856, 246021056, 246152512, 246284224, -246415168, 246545344, 246675904, 246808384, 246939584, 247070144, -247199552, 247331648, 247463872, 247593536, 247726016, 247857088, -247987648, 248116928, 248249536, 248380736, 248512064, 248643008, -248773312, 248901056, 249036608, 249167552, 249298624, 249429184, -249560512, 249692096, 249822784, 249954112, 250085312, 250215488, -250345792, 250478528, 250608704, 250739264, 250870976, 251002816, -251133632, 251263552, 251395136, 251523904, 251657792, 251789248, -251919424, 252051392, 252182464, 252313408, 252444224, 252575552, -252706624, 252836032, 252968512, 253099712, 253227584, 253361728, -253493056, 253623488, 253754432, 253885504, 254017216, 254148032, -254279488, 254410432, 254541376, 254672576, 254803264, 254933824, -255065792, 255196736, 255326528, 255458752, 255589952, 255721408, -255851072, 255983296, 256114624, 256244416, 256374208, 256507712, -256636096, 256768832, 256900544, 257031616, 257162176, 257294272, -257424448, 257555776, 257686976, 257818432, 257949632, 258079552, -258211136, 258342464, 258473408, 258603712, 258734656, 258867008, -258996544, 259127744, 259260224, 259391296, 259522112, 259651904, -259784384, 259915328, 260045888, 260175424, 260308544, 260438336, -260570944, 260700992, 260832448, 260963776, 261092672, 261226304, -261356864, 261487936, 261619648, 261750592, 261879872, 262011968, -262143424, 262274752, 262404416, 262537024, 262667968, 262799296, -262928704, 263061184, 263191744, 263322944, 263454656, 263585216, -263716672, 263847872, 263978944, 264108608, 264241088, 264371648, -264501184, 264632768, 264764096, 264895936, 265024576, 265158464, -265287488, 265418432, 265550528, 265681216, 265813312, 265943488, -266075968, 266206144, 266337728, 266468032, 266600384, 266731072, -266862272, 266993344, 267124288, 267255616, 267386432, 267516992, -267648704, 267777728, 267910592, 268040512, 268172096, 268302784, -268435264, 268566208, 268696256, 268828096, 268959296, 269090368, -269221312, 269352256, 269482688, 269614784, 269745856, 269876416, -270007616, 270139328, 270270272, 270401216, 270531904, 270663616, -270791744, 270924736, 271056832, 271186112, 271317184, 271449536, -271580992, 271711936, 271843136, 271973056, 272105408, 272236352, -272367296, 272498368, 272629568, 272759488, 272891456, 273022784, -273153856, 273284672, 273415616, 273547072, 273677632, 273808448, -273937088, 274071488, 274200896, 274332992, 274463296, 274595392, -274726208, 274857536, 274988992, 275118656, 275250496, 275382208, -275513024, 275643968, 275775296, 275906368, 276037184, 276167872, -276297664, 276429376, 276560576, 276692672, 276822976, 276955072, -277085632, 277216832, 277347008, 277478848, 277609664, 277740992, -277868608, 278002624, 278134336, 278265536, 278395328, 278526784, -278657728, 278789824, 278921152, 279052096, 279182912, 279313088, -279443776, 279576256, 279706048, 279838528, 279969728, 280099648, -280230976, 280361408, 280493632, 280622528, 280755392, 280887104, -281018176, 281147968, 281278912, 281411392, 281542592, 281673152, -281803712, 281935552, 282066496, 282197312, 282329024, 282458816, -282590272, 282720832, 282853184, 282983744, 283115072, 283246144, -283377344, 283508416, 283639744, 283770304, 283901504, 284032576, -284163136, 284294848, 284426176, 284556992, 284687296, 284819264, -284950208, 285081536] -``` \ No newline at end of file diff --git a/pages/ethash-dagger-hashimoto/Ethash_revision_11.md b/pages/ethash-dagger-hashimoto/Ethash_revision_11.md deleted file mode 100644 index aa82ee5bb..000000000 --- a/pages/ethash-dagger-hashimoto/Ethash_revision_11.md +++ /dev/null @@ -1,249 +0,0 @@ ---- -name: Ethash Revision 11 -category: ---- - -**This spec is REVISION 11. Whenever you substantively (ie. not clarifications) update the algorithm, please update the revision number in this sentence. Also, in all implementations please include a spec revision number** - -Ethash is the planned PoW algorithm for Ethereum 1.0. It is the latest version of Dagger-Hashimoto, although it can no longer appropriately be called that since many of the original features of both algorithms have been drastically changed in the last month of research and development. See [https://github.com/ethereum/wiki/wiki/Dagger-Hashimoto](https://github.com/ethereum/wiki/wiki/Dagger-Hashimoto) for the original version. - -The specification for the algorithm is written in python to give a balance between clarity and exactness. If you are interested in actually running the spec as code, then you can; you simply need to install the `python_sha3` and `pyethereum` libraries, and add the following lines to your top of the file: - -```python -import sha3 - -# Assumes little endian bit ordering (same as Intel architectures) -def decode_int(s): - return int(s[::-1].encode('hex'), 16) if s else 0 - -def encode_int(s): - a = "%x" % s - return '' if s == 0 else ('0' * (len(a) % 2) + a).decode('hex')[::-1] - -def zpad(s, length): - return s + '\x00' * max(0, length - len(s)) - -# sha3 hash function, outputs 64 bytes -def sha3_512(x): - return sha3.sha3_512(x).digest() - -def sha3_256(x): - return sha3.sha3_256(x).digest() -``` - -### Goals - -Ethash is intended to satisfy the following goals: - -1. **IO saturation**: the algorithm should consume nearly the entire available memory access bandwidth (this is a strategy toward achieving ASIC resistance) -2. **Light client verifiability**: a light client should be able to verify a round of mining in under 0.01 seconds on a desktop in C, and under 1 second in Python or Javascript, with at most 32 MB of memory -3. **Light client slowdown**: the process of running the algorithm with a light client should be much slower than the process with a full client, to the point that the light client algorithm is not an economically viable route toward making an ASIC implementation. -4. **Light client fast startup**: a light client should be able to become fully operational and able to verify blocks within 40 seconds in Python or Javascript. - -The general route that the algorithm takes is as follows: - -1. There exists a `seed` which can be computed for each block by scanning through the block headers up until that point. -2. From the seed, one can compute a 32 MB pseudorandom `cache` -3. From the seed and cache, there exists a function `calc_dag_item(seed, cache, i)` which calculates the value of any element in a larger 1 GB dataset. The function for computing each element involves many elements in the cache. Miners are meant to store the 1 GB dataset in memory. -4. The actual algorithm is a loop that involves combining together many items from the DAG and taking a hash of the output. Each individual read from the DAG is 4KB wide in order to fetch a full page from memory. - -The large dataset is updated once every 1000 blocks, so the vast majority of a miner's effort will be reading the dataset, not making changes to it. The dataset also grows over time; it starts off at 1 GB and grows by about 345 MB per year. - -First, we define the parameters: - -```python -params = { - "cache_bytes": 33554432, # bytes in cache - "dag_bytes_init": 1073741824, # bytes in dag - "dag_bytes_growth": 131072, # growth per epoch (~345 MB per year) - "epoch_length": 1000, # blocks per epoch - "dag_parents": 64, # number of parents of each dag element - "cache_rounds": 2, # number of processing rounds in cache production - "mix_bytes": 4096, # width of mix - "accesses": 32, # number of accesses in hashimoto loop - "hash_bytes": 64 # hash length in bytes -} -``` - -### Cache Generation - -Now, we specify the function for producing a cache: - -```python -def mkcache(params, seed): - n = params["cache_bytes"] / params["hash_bytes"] - - # Sequentially produce the initial dataset - o = [sha3_512(seed)] - for i in range(1, n): - o.append(sha3_512(o[-1])) - - for _ in range(params["cache_rounds"]): - for i in range(n): - v = (decode_int(o[i]) % 2**64) % n - o[i] = sha3_512(o[(i-1+n)%n] + o[v]) - - return o -``` - -[Sergio2014]: http://www.hashcash.org/papers/memohash.pdf - -The cache production process involves first sequentially filling up 32 MB of memory, then performing two passes of Sergio Demian Lerner's *RandMemoHash* algorithm from [*Strict Memory Hard Hashing Functions* (2014)](http://www.hashcash.org/papers/memohash.pdf). The output is a set of 524288 64-byte values. - -### Pseudo Random Number Generation - -Now, we specify some auxiliary methods for running a variant of the [Blum Blum Shub](https://en.wikipedia.org/wiki/Blum_Blum_Shub) pseudorandom number generator on a 32-bit prime modulus; this is a very quick way of generating pseudorandom data. - -```python -# two safe primes approximately equal to 2**32 -P1 = 4294967087 -P2 = 4294963787 - -# Clamp a value to between the specified minimum and maximum -def clamp(minimum, x, maximum): - return max(minimum, min(maximum, x)) - -# Many steps of the BBS RNG in logtime -def quick_bbs(seed, i, P): - return pow(seed, pow(3, i, P-1), P) - -# One step of the BBS RNG -def step_bbs(n, P): - return (n * n * n) % P -``` - -When choosing a safe prime *p* for our random number generator, we wish to find ones where the [multiplicative order](http://en.wikipedia.org/wiki/Multiplicative_order) of 3 in ℤ/(*p* - 1) is *high*, since this determines the cycle length of the corresponding random number generator. The multiplicative order of 3 in ℤ/(4294967086) is 1073741771. Note that cryptographic security is NOT required of the RNG here; we only need it to provide values which are roughly even across the entire output space `[0 ... 2**32 - 1]` and can be relied on to pass the [Diehard Tests](http://en.wikipedia.org/wiki/Diehard_tests). - -This particular pseudo random number generator may exhibit bias when taking its output modulo a value which is not a prime, so we will choose our memory sizes in terms of primes in order to remove any bias. - -### Data aggregation function - -We use an algorithm inspired by the [FNV hash](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function) in order to combine large blocks of data together. This is essentially meant to be a non-associative substitute for XOR. - -```python -FNV_PRIME = 0x01000193 - -def fnv(a, b): - o = '' - for pos in range(0, len(a), 4): - v1 = decode_int(a[pos:pos+4]) - v2 = decode_int(b[pos:pos+4]) - o += zpad(encode_int((v1 * FNV_PRIME ^ v2) % 2**32), 4) - return o -``` - -### Full dataset calculation - -Each 64-byte item in the full 1 GB dataset is computed as follows: - -```python -def calc_dag_item(params, cache, i): - n = params["cache_bytes"] / params["hash_bytes"] - L = params["hash_bytes"] - rand_seed = clamp(2, decode_int(cache[0][:4]), P1 - 2) - rand = clamp(2, quick_bbs(rand_seed, i, P1), P2 - 2) - mix = cache[i % n] - for j in range(params["dag_parents"]): - mix_value = decode_int(mix[(j*4)%L: (j*4+3)%L]) - mix = fnv(mix, cache[(rand ^ mix_value) % n]) - rand = step_bbs(rand, P2) - return mix -``` - -Essentially, we use our RNG to generate a seed for the specific item, and use that as the seed for another RNG which picks 64 indices from the cache. We initialize a mix to equal the 512-bit big-endian representation of the index (the purpose of this is to make sure all of the entropy from the index, and not just the first 32 bytes as does the RNG, in computing the final DAG value), and then repeatedly run through random parts of the cache and use our aggregation function to combine the data together. - -### Main Loop - -Now, we specify the main "hashimoto"-like loop, where we aggregate data from the full dataset in order to produce our final value for a particular header and nonce: - -```python -def hashimoto(params, header, nonce, dagsize, dag_lookup): - L = params["mix_bytes"] - w = params["mix_bytes"] / params["hash_bytes"] - n = dagsize / params["hash_bytes"] - s = sha3_512(header + nonce) - mix = [s for _ in range(w)] - rand = clamp(2, decode_int(s[-4:]), P2 - 2) - for i in range(params["accesses"]): - mix_value = decode_int(mix[0][(i*4) % L: (i*4+3) % L]) - p = (rand ^ mix_value) % (n // w) * w - for j in range(w): - mix[j] = fnv(mix[j], dag_lookup(p + j)) - rand = step_bbs(rand, P2) - return sha3_256(s+sha3_256(s + ''.join(mix))) - -def hashimoto_light(params, cache, header, nonce, dagsize): - return hashimoto(params, header, nonce, dagsize, lambda x: calc_dag_item(params, cache, x)) - -def hashimoto_full(params, dag, header, nonce): - return hashimoto(params, cache, header, nonce, len(dag), lambda x: dag[x]) -``` - -Essentially, we maintain a "mix" 4096 bytes wide, and repeatedly sequentially fetch 4096 bytes from the full dataset and use the `fnv` function to combine it with the mix. 4096 bytes of sequential access are used so that each round of the algorithm always fetches a full page from RAM, minimizing translation lookaside buffer misses which ASICs would theoretically be able to avoid. - -If the output of this algorithm is below the desired target, then the nonce is valid. Note that the double application of `sha3_256` ensures that there exists an intermediate nonce which can be provided to prove that at least a small amount of work was done; this quick outer PoW verification can be used for anti-DDoS purposes. It also serves to provide statistical assurance that the result is an unbiased, 256 bit number. - -### Mining - -The mining algorithm is defined as follows: - -```python -def mine(params, dag, header, difficulty): - from random import randint - nonce = randint(0,2**64) - while decode_int(hashimoto_full(params, dag, header, nonce)) < difficulty: - nonce += 1 - nonce %= 2**64 - return nonce -``` - -### Defining the seed - -In order to compute the seed for a given block, we use the following algorithm: - -```python - def get_seedset(params, block): - if block.number == 0: - return ('\x42' * 32, '\x43' * 32) - elif (block.number % params["epoch_length"] == 0): - x, y = get_seedset(params, block.parent) - if (block.number // params["epoch_length"]) % 2: - y = sha3_256(y + block.prevhash) - else: - x = sha3_256(x + block.prevhash) - return (x, y) - else: - return get_seedset(params, block.parent) -``` - -Note the this function outputs two seeds. During even-numbered epochs, the PoW uses the first seed, and during odd-numbered epochs the PoW uses the second seed; this allows a miner to rebuild one DAG while simultaneously still using the other DAG, ensuring a smooth transition as the dataset gets updated. - -In order to compute the size of the dataset and the cache at a given block number, we use the following function: - -```python -def get_datasize(params, block): - datasize_in_bytes = params["dag_bytes_init"] + \ - params["dag_bytes_growth"] * (block.number // params["epoch_length"]) - while not isprime(datasize_in_bytes // params["mix_bytes"]): - datasize_in_bytes -= params["mix_bytes"] - return datasize_in_bytes - -def get_cachesize(params, block): - datasize_in_bytes = get_datasize(params, block) - cachesize_in_bytes = (datasize_in_bytes // 32) - while not isprime(cachesize_in_bytes // params["hash_bytes"]): - cachesize_in_bytes -= params["hash_bytes"] - return cachesize_in_bytes -``` - -Where `isprime` is of course: - -```python - def isprime(n): - for i in range(2, int(n ** 0.5 + 1)): - if n % i == 0: - return False - return True -``` - -For an optimization, one can add the line `if pow(2, n, n) != 2: return False` as an initial check, or use the Sieve of Erasthothenes to precompute the list of primes that the dataset will increase to all at once. Essentially, we are keeping the size of the dataset to always be equal to the highest prime below a linearly growing function, so on average in the long term the dataset will grow roughly linearly. \ No newline at end of file diff --git a/pages/ethereum-and-blockchain-technologies-and-research/Bad-Block-Reporting.md b/pages/ethereum-and-blockchain-technologies-and-research/Bad-Block-Reporting.md deleted file mode 100644 index 82750d998..000000000 --- a/pages/ethereum-and-blockchain-technologies-and-research/Bad-Block-Reporting.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -name: Bad Block Reporting -category: ---- - -Send a JSONRPC request to `https://badblocks.ethdev.com`: - -Call `eth_badBlock(BADBLOCK)`, with `BADBLOCK` the object described below: - -## BADBLOCK Object Format - -NOTE: All hex is lower-case. - -#### Types -- `DATA`: freeform byte array as a string of hex, *no 0x prefix*. -- `DATA_20`: like DATA, always of length 40. -- `HEX`: string of hex-encoded big-endian integer, used for VM stack/memory/storage items, *no 0x prefix*, *no leading zeroes*. -- `INT`: simple JS integer. -- `BIGINT`: string of decimal-encoded integer, used for potentially bigints. -- `TAG_ERROR`: described later. -- `TAG_INST`: string of an EVM instruction mnemonic, uppercase e.g. `"PUSH4"` or `"STOP"`. -- `VMTRACE`: described later. - -#### Type modifiers -- `SOMETIMES`: field is omitted under certain circumstances. -- `NONSTANDARD`: field may safely be omitted. - -#### BADBLOCKS object - -```json -{ - "block": DATA - "errortype": TAG_ERROR - "hints": { (all items OPTIONAL) - "receipts": [ DATA, ... ], OPTIONAL - "vmtrace": VMTRACE, OPTIONAL - }, OPTIONAL -} -``` - -Where: - -`receipts` is simply the array of RLP-encoded receipts. - -`TAG_ERROR` is a string containing one of (specified roughly in order of ability to detect): - -#### Generic: -- `RLPError`: One of the following: - - `BadRLP`: Generally invalid RLP (e.g. 0x8100). - - `BadCast`: Given RLP is of an incorrect type (e.g. 0x00 being interpreted as an integer). - - `OversizeRLP`: Additional bytes trailing an otherwise valid RLP fragment (e.g. 0x8000). - - `UndersizeRLP`: Bytes missing from the end of an otherwise valid RLP fragment (e.g. 0x81). - -#### Block-specific: -- `InvalidBlock`: One of the following: - - `InvalidBlockFormat`: Block format is wrong (!= array, != 3 items &c.). - - `TooManyUncles`: More than 2 uncles mentioned. - - `InvalidTransactionsRoot`: Transactions root is different to that derived from transactions given in block. - - `InvalidUnclesHash`: Uncles hash is different to that derived from uncles given in block. - - `InvalidGasUsed`: Gas used is not equal to the gasUsed in the last receipt (or previous block if no transactions). - - `InvalidStateRoot`: State root mentioned is different to that calculated (i.e. reward application is incorrect). - - `InvalidReceiptsRoot`: Receipts root mentioned is different to that calculated (i.e. appliaction of a transaction resulted in different logs, gas-used or state-root). "receipts" and "vmtrace" should be hinted. - -#### Block-header-specific -- `InvalidHeader`: One of the following: - - `InvalidBlockHeaderItemCount`: Wrong item count in header. - - `TooMuchGasUsed`: Header states gas used as bigger than gas limit. - - `ExtraDataTooBig`: Header's extra data is greater than limit. - - `InvalidDifficulty`: Difficulty is incorrect given previous block's difficulty and timestamp. - - `InvalidGasLimit`: Gas limit does not fall within bounds given previous block's gas limit. - - `InvalidBlockNonce`: Nonce does not result in a proof of work which satisfies the given difficulty. - - `InvalidNumber`: Number is not equal to parent number + 1. - - `InvalidTimestamp`: Timestamp is not greater than parent's. - - `InvalidLogBloom`: LogBloom is not equal to the bitwise-OR of all receipts' LogBlooms. - -#### Transaction-specific -- `InvalidTransaction`: One of the following: - - `OutOfGasIntrinsic`: GAS below amount required for any transaction. - - `BlockGasLimitReached`: Too much gas being used for the transaction within this block. - - `InvalidSignature`: Transaction's signature is invalid. - - `OutOfGasBase`: GAS below amount required for this transaction. - - `NotEnoughCash`: Balance of sender too low. - - `InvalidNonce`: Transaction nonce is wrong. - -#### Uncle-specific -- `InvalidUncle`: One of the following: - - `UncleInChain`: Uncle has already been included in the current chain (either as a direct ancestor or one of its included uncles). - - `UncleTooOld`: Uncle is older than the 6th generation uncle. - - `UncleIsBrother`: Uncle is newer than the 1st generation uncle. - - -and `VMTRACE` is the object: - -```json -[ - { - "stack": [ HEX, ... ] - "memory": HEX, SOMETIMES - "sha3memory": DATA_32, SOMETIMES - "storage": { HEX: HEX }, SOMETIMES - "gas": BIGINT - "pc": BIGINT - "inst": INT - "depth": INT, OPTIONAL - "steps": INT - "address": DATA_20, SOMETIMES - "memexpand": BIGINT, NONSTANDARD - "gascost": BIGINT, NONSTANDARD - "instname": STRING, NONSTANDARD - }, - ... -] -``` - -- `stack`: The stack, prior to execution. -- `memory`: The memory, prior to execution. Omitted when previous operation was not memory-dependent (MLOAD/MSTORE/MSTORE8/SHA3/CALL/CALLCODE/CREATE/CALLDATACOPY/CODECOPY/EXTCODECOPY), not first operation of CALL/CREATE context or when memory >= 1024 bytes large. -- `sha3memory`: The Keccak hash of the memory, prior to execution. Omitted when previous operation was not memory-dependent (MLOAD/MSTORE/MSTORE8/SHA3/CALL/CALLCODE/CREATE/CALLDATACOPY/CODECOPY/EXTCODECOPY), not first operation of CALL/CREATE context or when memory < 1024 bytes large. -- `storage`: The contents of storage that SSTOREs operate on (RE-READ THAT!), prior to execution. Omitted when previous operation is not storage-dependent (SLOAD/SSTORE) and not first operation of CALL/CREATE context. -- `gas`: The amount of gas available prior to this instruction. -- `pc`: The program counter, immediately prior to execution. -- `inst`: The instruction opcode index that is to be executed (e.g. STOP would be 0). -- `depth`: The depth of in present context in CALL/CREATE stack. Omitted when no change since previous operation and not first operation of CALL/CREATE context. -- `steps`: The number of steps taken so far in present CALL/CREATE context prior to executing the current instruction. -- `address`: The address of account that would be returned by `MYADDRESS` opcode. Omitted when no change since previous operation and not first operation of CALL/CREATE context. -- `memexpand`: The size that memory is to be expanded by in words for this operation. Omitted when zero. -- `gascost`: The total cost of gas for executing this instruction (technically the /maximum/ total cost of gas - CALL/CREATE may return gas). \ No newline at end of file diff --git a/pages/ethereum-and-blockchain-technologies-and-research/Bad-Chain-Canary.md b/pages/ethereum-and-blockchain-technologies-and-research/Bad-Chain-Canary.md deleted file mode 100644 index 22ca3949f..000000000 --- a/pages/ethereum-and-blockchain-technologies-and-research/Bad-Chain-Canary.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -name: Bad Chain Canary -category: ---- - -There will be a canary contract to notify that a given chain is bad. It's very easy to use; check storage location 0 of contract at the given address (see below). If non-zero, client should not mine (at least without a non-default option being given to ignore the canary and mine on a known-bad chain). - -Specifically there are three modes it can be in: - -- `0` All fine. Carry on. -- `1` Bad chain. Client should not mine on it. Client upgrade not yet available. -- `2` Update required. Just as for `1`; additionally, an update to your client is available and would be prudent. - -Clients implementing this protocol should display a message to the user to make any non-zero status clear. For a status of 2, the user should be notified than an immediate upgrade is required, regardless of whether mining is enabled. - -#### Addresses - -- For Olympic: `0x6879392ee114f8a4e133f0ff3dc4bc1717fe9344` -- For Frontier: TBC diff --git a/pages/ethereum-and-blockchain-technologies-and-research/Block-Protocol-2.0.md b/pages/ethereum-and-blockchain-technologies-and-research/Block-Protocol-2.0.md deleted file mode 100644 index f60f0fb7d..000000000 --- a/pages/ethereum-and-blockchain-technologies-and-research/Block-Protocol-2.0.md +++ /dev/null @@ -1,255 +0,0 @@ ---- -name: Block Protocol 2.0 -category: ---- - -One of the main criticisms that has been made of Ethereum, and Bitcoin-like blockchain protocols in general, is the issue of scalability. Although Bitcoin's core developers, and other platforms such as Ripple, have continued to make iterative improvements to the way that the blockchain is stored, including innovations such as separating the state ("ledger" or "UTXO set") from the transaction list or using separate data structures to store the two on disk/memory, fundamentally no one has successfully implemented any way to improve upon the fundamental limitation that every full node must process every transaction. At this point, Ethereum also does not solve this problem. However, the block protocol described here, and specifically the stack trace mechanism, allows for secure "light nodes" to exist, which download only the headers of every block and not the full transaction set but maintain the same security level for their users as full nodes under the much weaker assumption that at least one node with non-negligible (ie. >0.01%) mining power or ether inside the system is honest. - -### Data definitions - -A full block is stored as: - - [ - block_header, - transaction_list, - uncle_list, - stack_trace - ] - -Where: - - transaction_list = [ - transaction 0, - transaction 1, - ... - ] - - uncle list = [ - uncle_block_header_1, - uncle_block_header_2, - ... - ] - - block_header = [ - parent hash, - number, - TRIEHASH(transaction_list), - TRIEHASH(uncle_list), - TRIEHASH(stack_trace), - coinbase address, - state_root, - difficulty, - timestamp, - extra_data, - nonce - ] - - stack_trace = [ - [ medhash 0, stkhash 0 ], - [ medhash 1, stkhash 1 ], - ... - ] - -Each transaction and uncle block header is itself provided directly in the form of a list, not in a serialized form. `uncle_list` and `transaction_list` are the lists of the uncle block headers and transactions in the block, respectively. Note that the block number, difficulty and timestamp are integers, and therefore cannot have leading zeroes; `extra_data` and `nonce` can be byte arrays of at most 32 bytes, NOT lists, although this particular check should not be performed for the genesis block where the `extra_data` field will take up many kilobytes. - -The `state_root` is the root of a [Patricia Tree](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree) containing (key, value) pairs for all accounts where each address is represented as a 20-byte binary string. At the address of each account, the value stored in the Merkle Patricia tree is a string which is the RLP-serialized form of an object of the form: - - [ balance, nonce, contract_root ] - -The `nonce` is the number of transactions made from the account, and is incremented every time a transaction is made. The purpose of this is to (1) make each transaction valid only once to prevent replay attacks, and (2) to make it impossible (more precisely, cryptographically infeasible) to construct a contract with the same hash as a pre-existing contract. `balance` refers to the account's balance, denominated in wei. `contract_root` is the root of yet another Patricia tree, containing the contract's memory, if that account is controlled by a contract. If an account is not controlled by a contract, the contract root will simply be the empty string. - -In order to understand all of what is above, we also need a few function definitions: - - def H(x): - if len(rlp.encode(x)) < 32: return x - else: return sha3(rlp.encode(x)) - - def H20(x): - if len(rlp.encode(x)) < 20: return x - else: return sha3(rlp.encode(x))[:12] - - def adjust_difficulty(pdiff,ptime,ntime): - if ntime > ptime + 42: return pdiff - int(pdiff / 1024) - else: return pdiff + int(pdiff / 1024) - - def int_to_bin(n,bytes): - return '' if bytes == 0 else int_to_bin(int(n / 256),bytes - 1) + chr(n % 256) - - def TRIE(objs): - t = Trie() - for i in range(len(objs)): - t.insert(int_to_bin(i,32),rlp.encode(objs[i])) - return t - - def TRIEHASH(objs): - return TRIE(objs).root - - -We also want a few methods for dealing with tries as stacks: - - def TRIELEN(trie): - i = 0 - while trie.get(int_to_bin(i,32)): i += 1 - return i - - def TRIETOP(trie): - return trie.get(int_to_bin(TRIELEN(trie)-1,32)) - - def TRIEPOP(trie): - trie.update(int_to_bin(TRIELEN(trie)-1,32),'') - - def TRIEPUSH(trie,node): - trie.update(int_to_bin(TRIELEN(trie),3),node) - -The mining function is tentative, and will be replaced once we know that we have better alternatives: - - def compute_valid_nonce(header): - header[10] = 0 - while not verify_pow(header): - header[10] += 1 - return header[10] - - def verify_pow(header): - return sha3(sha3(header[:10]) + header[10]) * header[7] <= 2**256 - - -### Mining Process - -![Mining Process](https://www.ethereum.org/gh_wiki/500px-Minerchart3.png) - - -When mining a block, a miner goes through the following process: - -1- Take as inputs: - -* `uncle_headers` to be the list of known unused valid uncle headers -* `timestamp` to be the current timestamp -* `parent` to be the parent block -* `extra_data` to be the extra data desired to be added to the block -* `coinbase` to be the desired coinbase address -* `txlist` to be the list of transactions to be added - -2- Set: - -* `difficulty = adjust_difficulty(parent.difficulty,timestamp,parent.timestamp)` -* `reward = 15 * 10^18` (tentatively) -* `block_header = [ parent.hash, parent.number + 1, TRIEHASH(txlist), TRIEHASH(uncle_headers), 0, coinbase, 0, difficulty, timestamp, extra_data, 0 ]` - -3- Initialize: - -* `state` to be the parent block state -* `txstack = TRIE(txlist)` -* `stacktrace = TRIE([])` - -4- While `stacktrace.root != ''`: - -* `TRIEPUSH(stacktrace,[state.root,txstack.root])` -* Apply the transaction `TRIETOP(txstack)` to `state`. -* `TRIEPOP(txstack)` -* Let `L[0] ... L[m-1]` be the list of new transactions spawned by that transaction via `MKTX`, in the order that they were produced during script execution. -* Initialize `j = m-1`. While `j >= 0`, `TRIEPUSH(txstack,L[j])` and `j -= 1` - -5- Make the following modifications to the state tree: - -* Increase the balance of `coinbase` by `reward` -* For each uncle `u` in `uncle_headers`, increase the balance of `u.coinbase` by `reward * 13/16` and increase the balance of `coinbase` by `reward * 1/16` - -6- Fill in the first two zeroes in `block_header` with `state.root` and `TRIEHASH(stack_trace)` - -7- Set `nonce = compute_valid_nonce(block_header)`, and fill in the remaining zero in the block header with this value - -### Block Validation Algorithm - -![Mining Process](https://www.ethereum.org/gh_wiki/500px-Minerchart2.png) - -1- Take as inputs: - -* `block` to be the block header -* `uncle_list` to be the block's uncle list -* `transaction_list` to be the block's transaction list -* `stacktrace` to be the block's stack trace -* `now` to be the current time as measured by the miner's CPU - -2- Check the following: - -* Is there an object, which is a block, in the database with `block.prevhash` as its hash? Let `parent` be that block. -* Is the proof of work on the block valid? -* Is the proof of work on all uncle headers valid? -* Are all uncles unique and actually uncles (ie. children of the parent of the parent, but not the parent)? -* Is `block.timestamp <= now + 900` and is `block.timestamp >= parent.timestamp`? -* Is `block.number == parent.number + 1`? -* Is `block.difficulty == adjust_difficulty(parent.difficulty,timestamp,parent.timestamp)`? -* Is `block.transaction_hash = TRIEHASH(transaction_list)`? -* Is `block.stacktrace_hash = TRIEHASH(stacktrace)`? -* Is `block.uncle_hash = H(uncle_list)`? - -3- Initialize: - -* `state` to be block parent block's state -* `txstack = TRIE(transaction_list)` -* `i = 0` - -4- Let `stacktrace[k] = [ M[k], H[k] ]`, defaulting to '' if `k` is out of bounds. While `i < len(stacktrace)`: - -* Check that `state.root == M[i]` and `txstack.root == H[i]` -* Apply `transaction_list[i]` to `state`. -* Apply the transaction `TRIETOP(txstack)` to `state`. -* `TRIEPOP(txstack)` -* Let `L[0] ... L[m-1]` be the list of new transactions spawned by that transaction via `MKTX`, in the order that they were produced during script execution. -* Initialize `j = m-1`. While `j >= 0`, `TRIEPUSH(txstack,L[j])` and `j -= 1` -* Set `i += 1` - -5- Make the following modifications to `state`: - -* Increase the balance of `coinbase` by `reward` -* For each uncle `u` in `uncle_headers`, increase the balance of `u.coinbase` by `reward * 13/16` and increase the balance of `coinbase` by `reward * 1/16` - -6- Check that `txstack.root == ''` - -7- Check that `state.root == block.state_root` - -8- If any check failed, return FALSE. Otherwise, return TRUE. - -If a block is valid, determine TD(block) ("total difficulty") for the new block. TD is defined recursively by `TD(genesis_block) = 0` and `TD(B) = TD(B.parent) + sum([u.difficulty for u in B.uncles]) + B.difficulty`. If the new block has higher TD than the current block, set the current block to the new block and continue to the next step. Otherwise, exit. - -### Semi-collaborative Block Validation Via Challenge-Response Protocol - -In Ethereum, a ''light node'' can be defined as a node that accepts block headers, and performs the verifications in (2) with the exception of the transaction and stacktrace trie hash verifications but does not perform the verifications in (4) and (6), similar to the headers-only verification that light nodes do in Bitcoin. Light nodes would thus store the state roots, and perhaps some portion of the state, but not the entire state. If a light node wants to know the balance or contract state of a given account, it can request the value from other nodes in the network alongside the minimal subset of Patricia tree nodes that prove that the given key/value pair is actually in the state. - -Although Ethereum cannot run without at least some full nodes processing and verifying every transaction that takes place in the network, this block protocol is designed to provide a somewhat weaker assurance: as long as at least one honest full node exists, light clients can be just as secure and provide the same incentives toward decentralization that full nodes do. The mechanism relies on a challenge-response protocol in which a full node can, subject to certain conditions, submit a challenge that a certain part of a block is invalid, and it would be up to the miner (or another good samaritan node) to provide a response which light nodes can then efficiently verify. If a challenge goes uncontested, then light nodes would distrust the block. - -In the validation algorithm described in the previous section, note that there are a few specific places where a block can fail: - -1. One of the checks in (2), aside from the transaction list trie hash or stack trace trie hash check, fails. -2. The transaction list trie hash check fails. -3. The stack trace trie hash check fails. -4. One of the checks in (4) fails for `i=0` -5. One of the checks in (4) succeeds for all `i= k`, everything must be blank. - -A challenge of invalidity consists of either (1) an index `i` pointing to a potential invalid transaction, or (2) an index `i` pointing to a blank space and an index `j > i` pointing to a transaction. A response should contain (1) `i`, (2) `j` if applicable, (3) the subset of Patricia tree nodes needed to verify the values at `i` and `j` in the trie. - -For (5), a challenge of invalidity consists of an index `k` such that everything up to index `k` is valid but index `k` is not. A response consists of (1) `k`, (2) the stack trace entries at `k-1` and `k` along with a subset of Patricia tree nodes to verify them, (3) a subset of Patricia tree nodes from the state tree needed to verify the computation. For (4), a response consists simply of a subset of Patricia tree nodes to prove the stack trace entry at index 0, from which the two components can be checked against the transaction list hash in the block header and the parent block state. For (6), a response functions in the same way as in (4), except verifying the response requires both processing the last transaction and giving the block rewards to the coinbase and the uncles. - -### Economics - -There is one flaw in the protocol as described above: it is vulnerable to denial of service attacks. Specifically, because challenges are much easier to produce than responses are to produce or verify, it is possible for nodes to pollute the network with false challenges, forcing light nodes to reject every block as other nodes are unable to catch up with verification. To remedy this, we introduce a simple fix: a challenge must be signed by a node that either (1) mined one of the last 10000 blocks, or (2) owns at least 0.01% of all ether. Light nodes would then keep quality scores for all peers, and downgrade peers if they submit a challenge that is successfully countered. Because this method is not anonymous, requiring nodes to submit proof of ownership of an identity tied to the blockchain, it cannot be countered by reconnecting under a new IP address or other such mechanisms. - -The protocol altogether can be shown to be incentive-compatible as follows: - -1. Miners have the incentive to submit challenges to blocks mined by other nodes because if a challenge is successful and then they mine the next block they will have the opportunity to gain an extra 0.0625X reward by including the header of the invalid block as an uncle. -2. The miner of a block, and all uncles inside the block, at the very least have the incentive to respond to challenges. -3. Light nodes have the incentive to respect the block validity rules because everyone else does, an argument advanced in http://themonetaryfuture.blogspot.ca/2011/07/bitcoin-decentralization-and-nash.html. Without the challenge-response protocol, this argument does not apply because the cost of determining whether or not a block is valid is prohibitively high; with the protocol, this reasoning no longer applies. -4. Substantial stakeholders have the incentive to promote the perceived integrity of the system to maximize the value of their currency units, and thus may want to help actively submit both challenges and responses where possible. -5. Statistically speaking, far more than 0.01% of agents inside of real-world economic agents, whether or not weighted by economic power, tend to be motivated by altruistic/ideological considerations. The market share of charities around the world is sufficient evidence of this. - -### Comparison with Bitcoin - -In Bitcoin, one can create a challenge-response protocol to achieve similar functionality along very similar principles, but there is one key way in which such a protocol in Bitcoin would be inadequate: miner fees. Because Bitcoin does not include a Merkle-tree mechanism for adding up transaction fees, the only way to prove that a block has a certain quantity of transaction fees is to process every transaction. Furthermore, in Bitcoin transaction fees all go to the miner. Thus, in Bitcoin a light node has no way of knowing if a given block is valid or if it gives its creator excessive fees, and can only rely on the computational majority as a source of information for this. In Ethereum, all changes to the state are incorporated into the stacktrace, so this weakness does not exist and, given the weak security assumption that at least one full node with at least 0.01% mining power or stake is honest, have 100% of the security properties that full nodes have. diff --git a/pages/ethereum-and-blockchain-technologies-and-research/Blockchain-import-and-export-instructions.md b/pages/ethereum-and-blockchain-technologies-and-research/Blockchain-import-and-export-instructions.md deleted file mode 100644 index ef530c0d4..000000000 --- a/pages/ethereum-and-blockchain-technologies-and-research/Blockchain-import-and-export-instructions.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -name: Blockchain Import/Export -category: ---- - -_**Note:** Binary format is concatenated RLP-encoded blocks_ - -## C++ -### Import: -``` -eth --import -``` -_Formats supported: binary_ - -### Export: -``` -eth --export Myfile --format binary --from 45 --to latest -``` -_Formats supported: hex (newlines separating), binary or JSON_ -`--from` and `--to` also support blockhashes - -## Go -### Import -``` -geth import -``` -_Formats supported: binary_ - -### Genesis block: -``` -geth --genesis --genesisnonce -``` -_Formats supported: json_ -### Export -``` -geth export -``` -_Formats supported: binary_ -## Python \ No newline at end of file diff --git a/pages/ethereum-and-blockchain-technologies-and-research/Distributed-Preimage-Archive.md b/pages/ethereum-and-blockchain-technologies-and-research/Distributed-Preimage-Archive.md deleted file mode 100644 index a9bb673d2..000000000 --- a/pages/ethereum-and-blockchain-technologies-and-research/Distributed-Preimage-Archive.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -name: Distributed Preimage Archive -category: ---- - -# Purpose - -DPA stores small pieces of information (preimage objects, arbitrary strings of bytes of limited length) retrievable by their (cryptographic) hash value. Thus, preimage objects stored in DPA have implicit integrity protection. The hash function used for key assignment is assumed to be collision-free, meaning that colliding keys for different preimage objects are assumed to be practically impossible. - -DPA serves as a fast, redundant store optimized for speedy retrieval and long-term reliability. Its most frequent use within Ethereum is to cache objects that can be retrieved and/or re-constructed by other means at significant cost. Since the key is derived from the preimage, there is no sense in which we can talk about multiple or alternative values for keys, the store is immutable. - -# High-level design - -DPA is organized as a DHT (Distributed Hash Table): each participating node has an address (resolved into a network address by the p2p layer) coming from the same value set as the range of the hash function. In particular it is the hash of the public key (NodeID field of the DEVP2P handshake). - -There is a distance measure defined over this value set that is a proper metric satisfying the triangle inequality. It is always possible to tell how far another node or another preimage object is from a given address or hash value. The distance from self is zero. - -Each node is interested in being able to find preimages to hash values as fast as possible and therefore stores as many preimages as it can itself. Whenever it must decide which preimage object to store and which to discard, preference is given to objects with an address that is closer. In practical terms, it is always the farthest preimage object that is discarded when a node runs short of storage capacity. Thus, each node ends up storing preimage objects within a given radius limited by available storage capacity. The cryptographic hash function takes care of randomization and fair load balancing. - -Nodes provide the following services through a public network API: - -1. Inserting new preimages into DPA -1. Retrieving preimages from their own storage, if they have it. -1. Sharing routing information to a given node address - -Locally, in addition to the above, nodes also provide the service of storing and retrieving large chunks of data. When storing, the data is disassembled into a tree of blocks according to a scheme resulting in the key corresponding to the root block. Given the key of the root block the data can then can be reassembled with the help of recursively retrieving the blocks in the tree. - -## Queries - -### Insert - -When receiving a preimage that is not already present in its local storage, the node stores it locally. If the storage allocated by the node for the archive is full, the object accessed the longest time ago is discarded. Note that this policy implicitly results in storing the objects closer to the node's address, as - all else being equal - those are the ones which are most likely to get queried from this particular node, due to the lookup strategy detailed below. - -After storing the preimage, the insert request is also forwarded to all the nodes in the corresponding row of the routing table. Note that the kademlia routing makes sure that the row in the close proximity of a node actually contains nodes further out than self thereby taking care of storage redundancy. -However, in order to mitigate against node drop out preimages, especially those with hashes in the node's proximity, need to be re-broadcast, albeit with a very low frequency. - -When a node received a store request, it remembers it for a while and does not forward the same request. This is needed to avoid redundant network traffic. - -### Retrieve - -Retrieval requests have the following parameters: - -1. The hash of the queried pre-image -1. Timeout value for routed retrieval, zero if routing is not required - -If the node has the pre-image, it is returned, called a delivery. Otherwise, the following happens: - -1. The entire row in the Kademlia table corresponding to the queried hash is returned. -1. If routing is deemed not worth the effort (timeout is too short), this fact is also communicated. -1. Otherwise, the same query is recursively done and if it succeeds within the specified timeout, the result is sent to the querying node. - -Successfully found pre-images are automatically re-inserted into DPA. - -A default time estimate for retrieval is calculated in proportion to the expected hop-distance from the node closest to the queried preimage. If this time is outside of the timeout parameter in the request, the request is not routed. - -Each node in the row corresponding to the queried preimage is sequentially queried in order of increasing distance from the target hash. The query is forwarded with a timeout value set to the maximum of the above estimate and the total timeout divided by the number of nodes in the row. If the preimage is found or the time elapsed is in excess of the received timeout value, processing of the query is aborted with timeout. - -From the set up of the first forward onwards, all retrieval requests of the same target are remembered in a request pool. If the data results in successful retrieval and the preimage is stored, the requests are answered by returning the preimage object to each requesting node whether forwarding or originator. The pool of requesting nodes then can be forgotten, since all further queries can be responded with the object delivery. - -## BZZ protocol spec - -**Handshake** - -`[0x01, protocolVersion: B_32, strategy: B_32, capacity: B_64, peers: B_8]` - -**Storing** - -`[+0x02, key: B_256, metadata: [], data: B_4k]`: the data chunk to be stored, preceded by its key. - -**Retrieving** - -`[0x03, key: B_256, timeout: B_64, metadata: []]`: key of the data chunk to be retrieved, timeout in milliseconds. Note that zero timeout retrievals serve also as messages to retrieve peers. - -**Peers** - -`[0x04, key: B_256, timeout: B_64, peers: [[peer], [peer], .... ]]` the encoding of a peer is identical to that in the devp2p base protocol peers messages: `[IP, Port, NodeID]` note that a node's DPA address is not the NodeID but the hash of the NodeID. Timeout serves to indicate whether the responder is forwarding the query within the timeout or not. - -**Delivery** - -`[0x05, key: B_256, metadata: [], data: B_4k]`: the delivery response to retrieval queries. - -## Routing - -It is based on Kademlia's routing. [details](https://github.com/ethereum/wiki/wiki/Cademlia-Peer-Selection) - -_to be continued..._ \ No newline at end of file diff --git a/pages/ethereum-and-blockchain-technologies-and-research/EVM-Subtleties.md b/pages/ethereum-and-blockchain-technologies-and-research/EVM-Subtleties.md deleted file mode 100644 index 8c3cb7e52..000000000 --- a/pages/ethereum-and-blockchain-technologies-and-research/EVM-Subtleties.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -name: Subtleties -category: ---- - -## Memory - -* Storage is a key/value store where keys and values are both 32 bytes -* Values on the stack are 32 bytes -* Memory is a byte-array. Memory starts off zero-size, but can be expanded in 32-byte chunks by simply accessing or storing memory at indices greater than its current size. -* The fee for expanding memory is determined via a subtract-the-integrals method. Specifically, `TOTALFEE(SZ) = SZ * 3 + floor(SZ**2 / 512)` is the total fee for expanding the memory to `SZ` 32-byte chunks (note: partially filled chunks are counted, so 33 bytes = 2 chunks), and if a particular operation expands memory from size `x` to `y`, the additional gas cost is `TOTALFEE(y) - TOTALFEE(x)` -* If an operation writes a slice of data zero bytes wide to memory, even if the start index of the slice exceeds the current memory size, memory is NOT expanded. - -## Nonces - -* If an externally-owned account sends a transaction, its nonce is incremented before execution -* If an externally-owned account creates a contract, its nonce is incremented before execution -* If a contract sends a message, no nonce increments happen -* If a contract creates a contract, the nonce is incremented before the rest of the sub-execution -* The pre-increment nonce is used to determine the contract address -* Nonce increments are never reverted - -## Exceptional conditions - -* The following count as exceptions: - * Execution running out of gas - * An operation trying to take more slots off the stack than are available on the stack - * Jumping to a bad jump destination - * An invalid opcode (note: the code of an account is assumed to be followed by an infinite tail of STOP instructions, so the program counter "walking off" the end of the code is not an invalid opcode exception. However, jumping outside the code is an exception, because STOP is not a valid jump destination) -* If a transaction triggers an exception, then: - * The value transfer from sender to recipient still takes place - * The fee transfer from sender to miner still takes place - * The entire `STARTGAS` is added to `gas_used` - * All other execution is reverted -* If a contract-producing transaction triggers an exception, then: - * The fee transfer from sender to miner still takes place - * The endowment is subtracted from the sender's account - * The account that would have been created gets created anyway, keeps its original endowment, but has the empty string as its code - * The entire `STARTGAS` is added to `gas_used` - * All other execution is reverted -* If a `CALL` operation's sub-execution triggers an exception, then: - * Ether value is still sent - * All gas is consumed - * `0` is appended onto the stack - * All other execution is reverted -* If a `CREATE` operation's sub-execution triggers an exception, then: - * Ether value is lost - * All gas is consumed - * All other execution is reverted - * The current implementations add `0` onto the stack, but it does not matter, since with 0 gas remaining the parent execution will instaquit anyway -* After a successful `CREATE` operation's sub-execution, if the operation returns `x`, `5 * len(x)` gas is subtracted from the remaining gas before the contract is created. If the remaining gas is less than `5 * len(x)`, then no gas is subtracted, the code of the created contract becomes the empty string, but this is not treated as an exceptional condition - no reverts happen. -* If a contract tries to `CALL` or `CREATE` a contract with either (i) insufficient balance, or (ii) stack depth already at maximum (1024), the sub-execution and transfer do not occur at all, no gas gets consumed, and 0 is added to the stack. -* Because of the depth limit, a contract may not be aware that a call that it is about to make is going to fail. Contract programmers should be very careful about this, and either use the 0 pushed to the stack to catch errors or use, eg, the identity contract to "test the waters" before making a substantial number of calls. - -## Arithmetic - -* All arithmetic is modulo 2256. For division, modulo and comparison, both signed and unsigned operators exist (eg. `(0 - 27) / 3` returns -9 if `SDIV` is used, but `38597363079105398474523661669562635951089994888546854679819194669304376546636` if `DIV` is used. -* Truncation and modulo operations with negative operators in the `SDIV`/`SMOD` case are handled as in Python (eg. , ) -* `DIV`, `SDIV`, `MOD` and `SMOD` with dividend (second argument) equal to 0 push 0 to the stack. - -### Other operations - -* The `CREATE` opcode takes three values: endowment (ie. initial amount of ether), memory start and memory length, and pushes onto the stack the address of the new contract. `CREATE` gives the initializing sub-execution all the gas that you have (and if gas remains then it gets refunded back to the parent execution) -* The `CALL` opcode takes seven values: gas, recipient, ether value, memory location of start of input data, length of input data, memory location to put start of output data, length of output data. It puts onto the stack either 1 for success (ie. did not run out of gas) or 0 for failure. -* When a contract calls `SUICIDE`, its ether is immediately sent to the desired address, but the contract continues existing until the end of transaction execution. Note that this leads to the interesting effect that, unlike Bitcoin where funds can be locked away forever but never destroyed, if a contract either SUICIDEs into itself or receives ether in the context of the same transaction execution after it has SUICIDED that ether is actually destroyed. -* If contract A calls contract B calls contract A, then the inner execution of A will have its own, fresh, memory, stack and PC, but it will modify and read the same balance and storage. -* If contract initialization returns an empty array, then no contract will be created. This allows you to "abuse" contract initialization as an atomic multi-operation, which might be useful in some protocols where you want to do multiple things but you don't want some of them to be able to process without others. -* `JUMP` and `JUMPI` instructions are only allowed to jump onto destinations that are (1) occupied by a `JUMPDEST` opcode, and (2) are not inside `PUSH` data. Note that properly processing these conditions requires preprocessing the code; a particularly pathological use case is `PUSH2 JUMPDEST PUSH1 PUSH2 JUMPDEST PUSH1 PUSH2 JUMPDEST PUSH1 ...`, as this code has all `JUMPDEST`s invalid but an alternative piece of code equivalent to this but only with the leading `PUSH2` replaced with another op (eg. `BALANCE`) will have all `JUMPDESTS`s valid. -* `CALL` has a multi-part gas cost: - * 40 base - * 9000 additional if the value is nonzero - * 25000 additional if the destination account does not yet exist (note: there is a difference between zero-balance and nonexistent!) -* `CALLCODE` operates similarly to call, except without the potential for a 25000 gas surcharge. -* The child message of a nonzero-value `CALL` operation (NOT the top-level message arising from a transaction!) gains an additional 2300 gas on top of the gas supplied by the calling account; this stipend can be considered to be paid out of the 9000 mandatory additional fee for nonzero-value calls. This ensures that a call recipient will always have enough gas to log that it received funds. \ No newline at end of file diff --git a/pages/ethereum-and-blockchain-technologies-and-research/Ethereum-Natural-Specification-Format.md b/pages/ethereum-and-blockchain-technologies-and-research/Ethereum-Natural-Specification-Format.md deleted file mode 100644 index 6409728eb..000000000 --- a/pages/ethereum-and-blockchain-technologies-and-research/Ethereum-Natural-Specification-Format.md +++ /dev/null @@ -1,138 +0,0 @@ ---- -name: Ethereum Natural Specification Format -category: ---- - -Solidity contracts can have a special form of comments that form the basis of the Ethereum Natural Specification Format. For a usage example please check [here](https://github.com/ethereum/wiki/wiki/Natspec-Example/). - -# Documentation Example - -Documentation is inserted above the function following the doxygen notation of either one or multiple lines starting with `///` or a multiline comment starting with `/**` and ending with `*/`. - -As an example consider the documentation of the following function: - -``` - /// @notice Send `(valueInmGAV / 1000).fixed(0,3)` GAV from the account of - /// `message.caller.address()`, to an account accessible only by `to.address() - /// @dev This should be the documentation of the function for the developer docs - /// @param to The address of the recipient of the GavCoin - /// @param valueInmGav The GavCoin value to send - function send(address to, uint256 valueInmGAV) { - if (balances[message.caller] >= valueInmGAV) { - balances[to] += valueInmGAV; - balances[message.caller] -= valueInmGAV; - } -``` - -There are a few things to note about the above example. -- Natspec format uses doxygen tags with some special meaning. These are: - + @title: This is a title that should describe the contract and go above the contract definition - + @author: The name of the author of the contract. Should also go above the contract definition. - + @notice: Represents user documentation. This is the text that will appear to the user to notify him - of what the function he is about to execute is doing - + @dev: Represents developer documentation. This is documentation that would only be visible to the - developer. - + @param: Documents a parameter just like in doxygen. Has to be followed by the parameter name. - + @return: Documents the return type of a contract's function. - -- If any of the above are missing they are simply considered as blank, and it's not illegal to omit any of them. - -- `(valueInmGAV / 1000).fixed(0,3)` A dynamic expression. This should be a valid Javascript/Paperscript expression, which when evaluated in an EVM Javascript environment initialised with various system values (such as parameters). - - -# Documentation Output - -When parsed, documentation such as the one from the above example will produce 2 different json files. One is meant to be consumed by the user as a notice when a function is executed and the other to be used by the developer. - -Let us see a more full contract example. - -``` -/// @title This is the contract title. -/// @author Homer Simpson -contract GavCoin -{ - /// @notice Send `(valueInmGAV / 1000).fixed(0,3)` GAV from the account of - /// `message.caller.address()`, to an account accessible only by `to.address() - /// @dev This should be the documentation of the function for the developer docs - /// @param to The address of the recipient of the GavCoin - /// @param valueInmGav The GavCoin value to send - function send(address to, uint256 valueInmGAV) { - if (balances[message.caller] >= valueInmGAV) { - balances[to] += valueInmGAV; - balances[message.caller] -= valueInmGAV; - } - } - - /// @notice `(balanceInmGAV / 1000).fixed(0,3)` GAV is the total funds available to `who.address()`. - /// @param who The address of the person whose balance we check - /// @return The balance of the user provided as argument - function balance(address who) constant returns (uint256 balanceInmGAV) { - balanceInmGAV = balances[who]; - } - -invariants: - /// @notice The sum total amount of GAV in the system is 1 million. - /// @dev This is the invariant development documentation - reduce(0, add, map(valueOf, balances)) == 100000000000; - -construction: - /// @notice Endows `message.caller.address()` with 1m GAV. - balances[message.caller] = 100000000000; - -state: - mapping balances(address) returns uint256 with function(address a) returns uint256 { return a; }; -}; -``` - -## User Documentation - -The above documentation will produce the following user documentation json file as output: - -``` -{ - "source": "...", - "language": "Solidity", - "languageVersion": 1, - "methods": { - "send(address,uint256)": { "notice": "Send `(valueInmGAV / 1000).fixed(0,3)` GAV from the account of `message.caller.address()`, to an account accessible only by `to.address()`." }, - "balance(address)": { "notice": "`(balanceInmGAV / 1000).fixed(0,3)` GAV is the total funds available to `who.address()`." } - }, - "invariants": [ - { "notice": "The sum total amount of GAV in the system is 1 million." } - ], - "construction": [ - { "notice": "Endows `message.caller.address()` with 1m GAV." } - ] -} -``` - -Note that the key by which to find the methods is the function's canonical signature as defined in the [Contract ABI](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI#signature) and not simply the function's name. - -## Developer Documentation - -Apart from the user documentation file, a developer documentation json file should also be produced and should look like this: - -``` -{ - "author": "Homer Simpson", - "title": "This is the contract title.", - "methods": { - "send(uint256)": { - "details": "This should be the documentation of the function for the developer docs" - }, - "balance": { - "details": "" - } - }, - "invariants": [ - { "details": "This is the invariant development documentation"} - ], - "construction": { - "details": "" - } -} -``` - -## Example usage - -There is a detailed example of using the Natspec feature with the cpp client [here](https://github.com/ethereum/wiki/wiki/Natspec-Example/). \ No newline at end of file diff --git a/pages/ethereum-and-blockchain-technologies-and-research/Ethereum-Wire-Protocol.md b/pages/ethereum-and-blockchain-technologies-and-research/Ethereum-Wire-Protocol.md deleted file mode 100644 index 51f8df916..000000000 --- a/pages/ethereum-and-blockchain-technologies-and-research/Ethereum-Wire-Protocol.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -name: Ethereum Wire Protocol -category: ---- - -Peer-to-peer communications between nodes running Ethereum clients run using the underlying [ÐΞVp2p Wire Protocol](https://github.com/ethereum/wiki/wiki/%C3%90%CE%9EVp2p-Wire-Protocol). - -### Basic Chain Syncing -- Two peers connect & say Hello and send their Status message. Status includes the Total Difficulty(TD) & hash of their best block. -- The client with the worst TD asks peer for full chain of just block hashes. -- Chain of hashes is stored in space shared by all peer connections, and used as a "work pool". -- While there are hashes in the chain of hashes that we don't have in our chain: - - Ask for N blocks from our peer using the hashes. Mark them as on their way so we don't get them from another peer. - -### Ethereum Sub-protocol - -**Status** -[`+0x00`: `P`, `protocolVersion`: `P`, `networkId`: `P`, `td`: `P`, `bestHash`: `B_32`, `genesisHash`: `B_32`] Inform a peer of its current **ethereum** state. This message should be sent _after_ the initial handshake and _prior_ to any **ethereum** related messages. -* `protocolVersion` is one of: - * `0x00` for PoC-1; - * `0x01` for PoC-2; - * `0x07` for PoC-3; - * `0x09` for PoC-4. - * `0x17` for PoC-5. - * `0x1c` for PoC-6. -* `networkId` should be 0 for testnet, 1 for mainnet. -* `td`: Total Difficulty of the best chain. Integer, as found in block header. -* `bestHash`: The hash of the best (i.e. highest TD) known block. -* `genesisHash`: The hash of the Genesis block. - -**NewBlockHashes** -[`+0x01`: `P`, `hash1`: `B_32`, `hash2`: `B_32`, `...`] Specify one or more new blocks which have appeared on the network. The list may contain 256 hashes at most. To be maximally helpful, nodes should inform peers of all blocks that they may not be aware of. Including hashes that the sending peer could reasonably be considered to know (due to the fact they were previously informed of because that node has itself advertised knowledge of the hashes through `NewBlockHashes`) is considered Bad Form, and may reduce the reputation of the sending node. Including hashes that the sending node later refuses to honour with a proceeding `GetBlocks` message is considered Bad Form, and may reduce the reputation of the sending node. - -**Transactions** -[`+0x02`: `P`, [`nonce`: `P`, `receivingAddress`: `B_20`, `value`: `P`, `...`], `...`] Specify (a) transaction(s) that the peer should make sure is included on its transaction queue. The items in the list (following the first item `0x12`) are transactions in the format described in the main Ethereum specification. Nodes must not resend the same transaction to a peer in the same session. This packet must contain at least one (new) transaction. - -**GetBlockHashes** -[`+0x03`: `P`, `hash` : `B_32`, `maxBlocks`: `P`] Requests a `BlockHashes` message of at most `maxBlocks` entries, of block hashes from the blockchain, starting at the parent of block `hash`. Does not _require_ the peer to give `maxBlocks` hashes - they could give somewhat fewer. - -**BlockHashes** -[`+0x04`: `P`, `hash_0`: `B_32`, `hash_1`: `B_32`, `...`] Gives a series of hashes of blocks (each the child of the next). This implies that the blocks are ordered from youngest to oldest. - -**GetBlocks** -[`+0x05`: `P`, `hash_0`: `B_32`, `hash_1`: `B_32`, `...`] Requests a `Blocks` message detailing a number of blocks to be sent, each referred to by a hash. Note: Don't expect that the peer necessarily give you all these blocks in a single message - you might have to re-request them. - -**Blocks** -[`+0x06`, [`blockHeader`, `transactionList`, `uncleList`], `...`] Specify (a) block(s) as an answer to `GetBlocks`. The items in the list (following the message ID) are blocks in the format described in the main Ethereum specification. This may validly contain no blocks if no blocks were able to be returned for the `GetBlocks` query. - -**NewBlock** -[`+0x07`, [`blockHeader`, `transactionList`, `uncleList`], `totalDifficulty`] Specify a single block that the peer should know about. The composite item in the list (following the message ID) is a block in the format described in the main Ethereum specification. -- `totalDifficulty` is the total difficulty of the block (aka score). - -### PV61 specific - -**BlockHashesFromNumber** -[`+0x08`: `P`, `number`: `P`, `maxBlocks`: `P`] -Requires peer to reply with a `BlockHashes` message. Message should contain block with that of number `number` on the canonical chain. Should also be followed by subsequent blocks, on the same chain, detailing a number of the first block hash and a total of hashes to be sent. Returned hash list must be ordered by block number in ascending order. - -### Proposed messages for New Model syncing (PV62) - -**NewBlockHashes** -[`+0x01`: `P`, [`hash_0`: `B_32`, `number_0`: `P`], [`hash_1`: `B_32`, `number_1`: `P`], ...] Specify one or more new blocks which have appeared on the network. To be maximally helpful, nodes should inform peers of all blocks that they may not be aware of. Including hashes that the sending peer could reasonably be considered to know (due to the fact they were previously informed of because that node has itself advertised knowledge of the hashes through `NewBlockHashes`) is considered Bad Form, and may reduce the reputation of the sending node. Including hashes that the sending node later refuses to honour with a proceeding `GetBlockHeaders` message is considered Bad Form, and may reduce the reputation of the sending node. - -**GetBlockHeaders** -[`+0x03`: `P`, `block`: { `P` , `B_32` }, `maxHeaders`: `P`, `skip`: `P`, `reverse`: `P` in { `0` , `1` } ] Require peer to return a `BlockHeaders` message. Reply must contain a number of block headers, of rising number when `reverse` is `0`, falling when `1`, `skip` blocks apart, beginning at block `block` (denoted by either number or hash) in the canonical chain, and with at most `maxHeaders` items. - -**BlockHeaders** -[`+0x04`, `blockHeader_0`, `blockHeader_1`, `...`] Reply to `GetBlockHeaders`. The items in the list (following the message ID) are block headers in the format described in the main Ethereum specification, previously asked for in a `GetBlockHeaders` message. This may validly contain no block headers if no block headers were able to be returned for the `GetBlockHeaders` query. - -**GetBlockBodies** -[`+0x05`, `hash_0`: `B_32`, `hash_1`: `B_32`, `...`] Require peer to return a `BlockBodies` message. Specify the set of blocks that we're interested in with the hashes. - -**BlockBodies** -[`+0x06`, [`transactions_0`, `uncles_0`] , `...`] Reply to `GetBlockBodies`. The items in the list (following the message ID) are some of the blocks, minus the header, in the format described in the main Ethereum specification, previously asked for in a `GetBlockBodies` message. This may validly contain no items if no blocks were able to be returned for the `GetBlockBodies` query. - -ELIMINATED: `GetBlockHashes`, `BlockHashes`, `GetBlocks`, `Blocks`, `BlockHashesFromNumber` - -### Proposed messages for fast synchronization (PV63) - -**GetNodeData** -[`+0x0d`, `hash_0`: `B_32`, `hash_1`: `B_32`, `...`] Require peer to return a `NodeData` message. Hint that useful values in it are those which correspond to given hashes. - -**NodeData** -[`+0x0e`, `value_0`: `B`, `value_1`: `B`, `...`] Provide a set of values which correspond to previously asked node data hashes from `GetNodeData`. Does not need to contain all; best effort is fine. If it contains none, then has no information for previous `GetNodeData` hashes. - -**GetReceipts** -[`+0x0f`, `hash_0`: `B_32`, `hash_1`: `B_32`, `...`] Require peer to return a `Receipts` message. Hint that useful values in it are those which correspond to blocks of the given hashes. - -**Receipts** -[`+0x10`, [`receipt_0`, `receipt_1`], `...`] Provide a set of receipts which correspond to previously asked in `GetReceipts`. - -### Proposal for light clients (PV64) - deprecated in favor of LES (the Light Ethereum sub-protocol) - -**GetAcctProof** -[`+0x11`, [`blknum`, `address`]] Require peer to return a `Proof` message, containing a Merkle-tree proof of the account data (nonce, balance, code hash, storage root) at `address` from the state root of block `blknum` - -**GetStorageDataProof** -[`+0x12`, [`blknum`, `address`, `key`]] Require peer to return a `Proof` message, containing a Merkle-tree proof of the storage value of index `key` in `address` from the state root of block `blknum` - -**Proof** -[`+0x13`, [`node_1`, `node_2`...]] Return a Merkle-tree proof consisting of a set of nodes that must be processed in order to access the piece of account data or storage value requested in `GetAcctProof` or `GetStorageDataProof` - -### Session Management - -For the Ethereum sub-protocol, upon an active session, a `Status` message must be sent. Following the reception of the peer's `Status` message, the Ethereum session is active and any other messages may be sent. All transactions should initially be sent with one or more Transactions messages. - -Transactions messages should also be sent periodically as the node has new transactions to disseminate. A node should never send a transaction back to the peer that it can determine already knows of it (either because it was previously sent or because it was informed from this peer originally). - -### Upcoming changes -- [Light Client Protocol](https://github.com/ethereum/wiki/wiki/Light-client-protocol) - -### Changes (PoC-7) -- [NewBlock Message](https://github.com/ethereum/wiki/wiki/NewBlock-Message) - -### Changed (PoC-6) -- [Parallel Block Downloads](https://github.com/ethereum/wiki/wiki/Parallel-Block-Downloads) \ No newline at end of file diff --git a/pages/ethereum-and-blockchain-technologies-and-research/Light-client-protocol.md b/pages/ethereum-and-blockchain-technologies-and-research/Light-client-protocol.md deleted file mode 100644 index f6fc9c06e..000000000 --- a/pages/ethereum-and-blockchain-technologies-and-research/Light-client-protocol.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -name: Light Client Protocol -category: ---- - -The purpose of the light client protocol is to allow users in low-capacity environments (embedded smart property environments, smartphones, browser extensions, some desktops, etc) to maintain a high-security assurance about the current state of some particular part of the Ethereum state or verify the execution of a transaction. Although full security is only possible for a full node, the light client protocol allows light nodes processing about 1KB of data per 2 minutes to receive data from the network about the parts of the state that are of concern to them, and be sure that the data is correct provided that the majority of miners are correctly following the protocol, and perhaps even only provided that at least one honest verifying full node exists. - -### Background: Patricia Merkle Trees - -All substantial quantities of data in Ethereum are stored in a data structure known as the [Patricia Merkle tree](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree), a tree structure where each node in the tree is the hash of its children. Each set of key/value pairs maps to a unique root hash, and only a small subset of nodes is needed to prove that a particular key/value combination is in the tree corresponding to a particular root hash. - -![](http://vitalik.ca/files/spv.png) - -The size complexity of a Merkle proof scales linearly with the height of a tree; because each child in a tree has a particular number of children (in our case, up to 17), this means that the size complexity of a Merkle proof is logarithmic in the quantity of data stored. This means that, even if the entire state tree is a few gigabytes in size, if a node receives a state root from a trusted source that node has the ability to know with full certainty the validity of any information with the tree by only downloading a few kilobytes of data in a proof. - -An SPV proof of a node in a Patricia tree simply consists of the complete subset of tree nodes that were processed in order to access it (or, more specifically, the tree nodes that needed to be looked up in a reverse-hash-lookup database). In a simple implementation of a Patricia tree, retrieving the value associated with a particular key requires descending the hash tree, constantly looking up nodes in the database by their hashes, until you eventually reach the final leaf node; a simple algorithm for producing an SPV proof is to simply run this naive algorithm, and record all of the database lookups that were made. SPV verification consists of running the naive lookup algorithm but pointing it to a custom database populated only with the nodes in the SPV proof; if there is a "node not found" error, then the proof is invalid. - -## Principles - -In Ethereum, a light client can be viewed as a client that downloads block headers by default, and verifies only a small portion of what needs to be verified, using a distributed hash table as a database for trie nodes in place of its local hard drive. For a "partially light client", which processes everything but is constrained by hard drive space and so stores almost nothing, swapping out a database read with a DHT get request is by itself sufficient to meet the requirements. Indeed, all "full clients" except for archive nodes (intended to be run by businesses, block explorers, etc) will eventually be set up as "partially light clients" with respect to all history older than a few thousand blocks. However, what we are also interested in supporting is _fully_ light clients, which never even process most transactions. Formally, we can say that _all_ measures of a full light client are bounded by a sublinear function of the number of transactions in a block - in most cases, the protocols below work for a bound of O(log(n)), though one particular mechanism works only for ~O(sqrt(n)). - -Some use cases for a fully light client, and how the light client meets those use cases, include: - -* A light client wants to know the state of an account (nonce, balance, code or storage index) at a particular time. The light client can simply recursively download trie nodes from the state root until it gets to the desired value. -* A light client wants to check that a transaction was confirmed. The light client can simply ask the network for the index and block number of that transaction, and recursively download transaction trie nodes to check for availability. -* Light clients want to collectively validate a block. Each light client `C[i]` chooses one transaction index `i` with transaction `T[i]` (with corresponding receipt `R[i]`) and does the following: - * Initiate the state with state root `R[i-1].medstate` and `R[i-1].gas_used` (if `i = 0` use the parent endstate and 0 `gas_used`) - * Process transaction `T[i]` - * Check that the resulting state root is `R[i].medstate` and the gas_used is `R[i].gas_used` - * Check that the set of logs and bloom produced matches `R[i].logs` and `R[i].logbloom` - * Checks that the bloom is a subset of the block header-level bloom (this detects block header-level blooms with false negatives); then pick a few random indices of the block header-level bloom where that bloom contains a 1 and ask other nodes for a transaction-level bloom that contains a 1 at that index, rejecting the block if no response is given (this detects block header-level blooms with false positives) -* Light clients want to "watch" for events that are logged. The protocol here is the following: - * A light client gets all block headers, checks for block headers that contain bloom filters that match one of a desired list of addresses or topics that the light client is interested in - * Upon finding a potentially matching block header, the light client downloads all transaction receipts, checks them for transactions whose bloom filters match - * Upon finding a potentially matching transaction, the light client checks its actual log RLP, and sees if it actually matches - -The first three light client protocols require a logarithmic amount of data access and computation; the fourth requires ~O(sqrt(N)) since bloom filters are only a two-level structure, although this can be improved to O(log(N)) if the light client is willing to rely on multiple providers to point to "interesting" transaction indices and decommission providers if they are revealed to have missed a transaction. The first protocol is useful to simply check up on state, and the second in consumer-merchant scenarios to check that a transaction was validated. The third protocol allows Ethereum light clients to collectively validate blocks with a very low degree of trust. In Bitcoin, for example, a miner can create a block that gives the miner an excessive amount of transaction fees, and there would be no way for light nodes to detect this themselves, or upon seeing an honest full node detect it verify a proof of invalidity. In Ethereum, if a block is invalid, it must contain an invalid state transition at some index, and so a light client that happens to be verifying that index can see that something is wrong, either because the proof step does not check out, or because data is unavailable, and that client can then raise the alarm. - -The fourth protocol is useful in cases where a dapp wants to keep track of some kind of events that need to be efficiently verifiable, but which do not need to be part of the permanent state; an example is a decentralized exchange logging trades or a wallet logging transactions (note that the light client protocol will need to be augmented with header-level coinbase and uncle checks for this to work fully with mining accounts). In Bitcoin terminology, `LOG` can be viewed as a pure "proof of publication" opcode. \ No newline at end of file diff --git a/pages/ethereum-and-blockchain-technologies-and-research/Morden.md b/pages/ethereum-and-blockchain-technologies-and-research/Morden.md deleted file mode 100644 index f3e912ea6..000000000 --- a/pages/ethereum-and-blockchain-technologies-and-research/Morden.md +++ /dev/null @@ -1,61 +0,0 @@ -Morden is the first Ethereum alternative testnet. It is expected to continue throughout the Frontier and Homestead era. - -### Usage - -#### TurboEthereum (C++) - -This is supported natively on 0.9.93 and above. Pass the `--morden` argument in when starting any of the clients. e.g.: - -``` -> eth --morden -``` - -Or, for AlethZero - -``` -> alethzero --morden -``` - -#### PyEthApp (Python client) - -PyEthApp supports the morden network from v1.0.5 onwards: - -``` -> pyethapp --profile morden run -``` - -### Details - -- Network Identity: **2** -- All parameters same as Frontier except: - - genesis.json (given below); - - Initial Account Nonce (`IAN`) is 2^20 (instead of 0 in all previous networks). - - All accounts in the state trie have nonce >= `IAN`. - - Whenever an account is inserted into the state trie it is initialised with nonce = `IAN`. -- Genesis block hash: `0cd786a2425d16f152c658316c423e6ce1181e15c3295826d7c9904cba9ce303` -- Genesis state root: `f3f4696bbf3b3b07775128eb7a3763279a394e382130f27c21e70233e04946a9` - -### Seed Nodes -- `enode://e58d5e26b3b630496ec640f2530f3e7fa8a8c7dfe79d9e9c4aac80e3730132b869c852d3125204ab35bb1b1951f6f2d40996c1034fd8c5a69b383ee337f02ddc@92.51.165.126:30303` - -### genesis.json - -```json -{ - "nonce": "0x00006d6f7264656e", - "difficulty": "0x20000", - "mixhash": "0x00000000000000000000000000000000000000647572616c65787365646c6578", - "coinbase": "0x0000000000000000000000000000000000000000", - "timestamp": "0x00", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData": "0x", - "gasLimit": "0x2FEFD8", - "alloc": { - "0000000000000000000000000000000000000001": { "balance": "1" }, - "0000000000000000000000000000000000000002": { "balance": "1" }, - "0000000000000000000000000000000000000003": { "balance": "1" }, - "0000000000000000000000000000000000000004": { "balance": "1" }, - "102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c": { "balance": "1606938044258990275541962092341162602522202993782792835301376" } - } -} -``` \ No newline at end of file diff --git a/pages/ethereum-and-blockchain-technologies-and-research/[english]-patricia-tree.md b/pages/ethereum-and-blockchain-technologies-and-research/[english]-patricia-tree.md deleted file mode 100644 index 824c7ea5e..000000000 --- a/pages/ethereum-and-blockchain-technologies-and-research/[english]-patricia-tree.md +++ /dev/null @@ -1,141 +0,0 @@ ---- -name: Patricia Tree -category: ---- - -### Merkle Patricia Tree Specification - -Merkle Patricia trees provide a cryptographically authenticated data structure that can be used to store all (key, value) bindings, although for the scope of this paper we are restricting keys and values to strings (to remove this restriction, just use any serialization format for other data types). They are fully deterministic, meaning that a Patricia tree with the same (key,value) bindings is guaranteed to be exactly the same down to the last byte and therefore have the same root hash, provide the holy grail of O(log(n)) efficiency for inserts, lookups and deletes, and are much easier to understand and code than more complex comparison-based alternatives like red-black trees. - -### Preamble: Basic Radix Trees - -In a basic radix tree, every node looks as follows: - - [ value, i0, i1 ... in] - -Where i0 ... in represent the symbols of the alphabet (often binary or hex). value is the terminal value at the node, and the values in the i0 ... in slots are either NULL or pointers to (in our case, hashes of) other nodes. This forms a basic (key, value) store; for example, if you are interested in the value that is currently mapped to dog in the tree, you would first convert dog into the alphabet (giving 646f67 if we're using hex), and then descend down the tree following that path until at the end of the path you read the value. That is, you would first look up the root hash in a key/value store to get the root node, then look up node 6 of the root node to get the node one level down, then look up node 4 of that, then look up node 6 of that, and so on, until, once you followed the path root -> 6 -> 4 -> 6 -> f -> 6 -> 7, you look up the value of the node that you have and return the result. - -The update and delete operations for radix trees are simple, and can be defined roughly as follows: - - def update(node,key,value): - if key == '': - curnode = db.get(node) if node else [ NULL ] * 17 - newnode = curnode.copy() - newnode['value'] = value - else: - curnode = db.get(node) if node else [ NULL ] * 17 - newnode = curnode.copy() - newindex = update(curnode[key[0]],key[1:],value) - newnode[key[0]] = newindex - db.put(hash(newnode),newnode) - return hash(newnode) - - def delete(node,key): - if key == '' or node is NULL: - return NULL - else: - curnode = db.get(node) - newnode = curnode.copy() - newindex = delete(curnode[key[0]],key[1:]) - newnode[key[0]] = newindex - if len(filter(x -> x is not NULL, newnode)) == 0: - return NULL - else: - db.put(hash(newnode),newnode) - return hash(newnode) - -The "Merkle" part of the radix tree arises in the fact that a deterministic cryptographic hash of a node is used as the pointer to the node, rather than some 32-bit or 64-bit memory location as might happen in a more traditional tree implemented in C. This provides a form of cryptographic authentication to the data structrure; if the root hash of a given trie is publicly known, then anyone can provide a proof that the trie has a given value at a specific key by providing the nodes going up each step of the way. it is impossible for an attacker to provide a proof of a (key, value) pair that does not exist since the root hash is ultimately based on all hashes below it, so any modification would change the root hash. - -However, radix trees have one major limitation: their inefficiency. If you want to store just one (key,value) binding where the key is a few hundred characters long, you will need over a kilobyte of extra space to store one level per character, and each lookup or delete will take hundreds of steps. The Patricia tree introduced here solves this issue. - -### Specification: Compact encoding of hex sequence with optional terminator - -The traditional compact way of encoding a hex string is to convert it into binary - that is, a string like 0f1248 would become three bytes \[15, 18, 72\] (or in string representation \x0f\x18H). However, this approach has one slight problem: what if the length of the hex string is odd? In that case, there is no way to distinguish between, say, 0f1248 and f1248. Additionally, our application in the Merkle Patricia tree requires the additional feature that a hex string can also have a special "terminator symbol" at the end (denoted by the 'T'). A terminator symbol can occur only once, and only at the end. An alternative way of thinking about this to not think of there being a terminator symbol, but instead treat bit specifying the existence of the terminator symbol as a bit specifying that the given node encodes a final node, where the value is an actual value, rather than the hash of yet another node. - -To solve both of these issues, we force the first nibble of the final bytestream to encode two flags, specifying oddness of length (ignoring the 'T' symbol) and terminator status; these are placed, respectively, into the two lowest significant bits of the first nibble. In the case of an even-length hex string, we must introduce a second nibble (of value zero) to ensure the hex-string is even in length and thus is representable by a whole number of bytes. Thus we construct the following encoding: - - def compact_encode(hexarray): - term = 1 if hexarray[-1] == 16 else 0 - if term: hexarray = hexarray[:-1] - oddlen = len(hexarray) % 2 - flags = 2 * term + oddlen - if oddlen: - hexarray = [flags] + hexarray - else: - hexarray = [flags] + [0] + hexarray - // hexarray now has an even length whose first nibble is the flags. - o = '' - for i in range(0,len(hexarray),2): - o += chr(16 * hexarray[i] + hexarray[i+1]) - return o - -Examples: - - > [ 1, 2, 3, 4, 5 ] - '\x11\x23\x45' - > [ 0, 1, 2, 3, 4, 5 ] - '\x00\x01\x23\x45' - > [ 0, 15, 1, 12, 11, 8, T ] - '\x20\x0f\x1c\xb8' - > [ 15, 1, 12, 11, 8, T ] - '\x3f\x1c\xb8' - -### Main specification: Merkle Patricia Tree - -Merkle Patricia trees solve the inefficiency issue by adding some extra complexity to the data structure. A node in a Merkle Patricia tree is one of the following: - -1. NULL (represented as the empty string) -2. A two-item array `[ key, v ]` (aka kv node) -3. A 17-item array `[ v0 ... v15, vt ]` (aka diverge node) - -The idea is that in the event that there is a long path of nodes each with only one element, we shortcut the descent by setting up a kv node `[ key, value ]`, where the key gives the hexadecimal path to descend, in the compact encoding described above, and the value is just the hash of the node like in the standard radix tree. Also, we add another conceptual change: internal nodes can no longer have values, only leaves with no children of their own can; however, since to be fully generic we want the key/value store to be able to store keys like 'dog' and 'doge' at the same time, we simply add a terminator symbol (16) to the alphabet so there is never a value "en-route" to another value. - -For a kv node, a two-item array `[ key, v ]`, `v` can be a value or a node. -* When `v` is a value, key must be the result of compact encoding a nibbles list **with** terminator. -* When `v` is a node, key must be the result of compact encoding a nibbles list **without** terminator. - -For a diverge node, a 17-item array `[ v0 ... v15, vt ]`, each item in v0...v15 should always be a node or blank, and vt should always be a value or blank. So to store a value in one item of v0...v15, we should instead store a kv node, where k is the result of compact encoding an empty nibbles list **with** terminator. - -Here is the extended code for getting a node in the Merkle Patricia tree: - - def get_helper(node,key): - if key == []: return node - if node = '': return '' - curnode = rlp.decode(node if len(node) < 32 else db.get(node)) - if len(curnode) == 2: - (k2, v2) = curnode - k2 = compact_decode(k2) - if k2 == key[:len(k2)]: - return get(v2, key[len(k2):]) - else: - return '' - elif len(curnode) == 17: - return get_helper(curnode[key[0]],key[1:]) - - def get(node,key): - key2 = [] - for i in range(len(key)): - key2.push(int(ord(key) / 16)) - key2.push(ord(key) % 16) - key2.push(16) - return get_helper(node,key2) - -Example: suppose we had a tree containing the pairs ('dog', 'puppy'), ('horse', 'stallion'), ('do', 'verb'), ('doge', 'coin'). First, we convert the keys over to hex format: - - [ 6, 4, 6, 15, 16 ] : 'verb' - [ 6, 4, 6, 15, 6, 7, 16 ] : 'puppy' - [ 6, 4, 6, 15, 6, 7, 6, 5, 16 ] : 'coin' - [ 6, 8, 6, 15, 7, 2, 7, 3, 6, 5, 16 ] : 'stallion' - -Now, we build the tree: - - ROOT: [ '\x16', A ] - A: [ '', '', '', '', B, '', '', '', C, '', '', '', '', '', '', '', '' ] - B: [ '\x00\x6f', D ] - D: [ '', '', '', '', '', '', E, '', '', '', '', '', '', '', '', '', 'verb' ] - E: [ '\x17', F ] - F: [ '', '', '', '', '', '', G, '', '', '', '', '', '', '', '', '', 'puppy' ] - G: [ '\x35', 'coin' ] - C: [ '\x20\x6f\x72\x73\x65', 'stallion' ] - -Where a node is referenced inside a node, what is included is H(rlp.encode(x)) where H(x) = sha3(x) if len(x) >= 32 else x and rlp.encode is the [RLP](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP) encoding function. Note that when updating a trie, you will need to store the key/value pair (sha3(x), x) in a persistent lookup table when you create a node with length >= 32, but if the node is shorter than that then you do not need to store anything when length < 32 for the obvious reason that the function f(x) = x is reversible. \ No newline at end of file diff --git a/pages/ethereum-and-blockchain-technologies-and-research/[english]-rlp.md b/pages/ethereum-and-blockchain-technologies-and-research/[english]-rlp.md deleted file mode 100644 index 4575949f8..000000000 --- a/pages/ethereum-and-blockchain-technologies-and-research/[english]-rlp.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -name: RLP -category: ---- - -The purpose of RLP (Recursive Length Prefix) is to encode arbitrarily nested arrays of binary data, and RLP is the main encoding method used to serialize objects in Ethereum. The only purpose of RLP is to encode structure; encoding specific atomic data types (eg. strings, ints, floats) is left up to higher-order protocols; in Ethereum integers must be represented in big endian binary form with no leading zeroes (thus making the integer value zero be equivalent to the empty byte array). - -If one wishes to use RLP to encode a dictionary, the two suggested canonical forms are to either use `[[k1,v1],[k2,v2]...]` with keys in lexicographic order or to use the higher-level [Patricia Tree](https://github.com/ethereum/wiki/wiki/Patricia-Tree) encoding as Ethereum does. - -### Definition - -The RLP encoding function takes in an item. An item is defined as follows: - -* A string (ie. byte array) is an item -* A list of items is an item - -For example, an empty string is an item, as is the string containing the word "cat", a list containing any number of strings, as well as more complex data structures like `["cat",["puppy","cow"],"horse",[[]],"pig",[""],"sheep"]`. Note that in the context of the rest of this article, "string" will be used as a synonym for "a certain number of bytes of binary data"; no special encodings are used and no knowledge about the content of the strings is implied. - -RLP encoding is defined as follows: - -* For a single byte whose value is in the `[0x00, 0x7f]` range, that byte is its own RLP encoding. -* Otherwise, if a string is 0-55 bytes long, the RLP encoding consists of a single byte with value **0x80** plus the length of the string followed by the string. The range of the first byte is thus `[0x80, 0xb7]`. -* If a string is more than 55 bytes long, the RLP encoding consists of a single byte with value **0xb7** plus the length of the length of the string in binary form, followed by the length of the string, followed by the string. For example, a length-1024 string would be encoded as `\xb9\x04\x00` followed by the string. The range of the first byte is thus `[0xb8, 0xbf]`. -* If the total payload of a list (i.e. the combined length of all its items) is 0-55 bytes long, the RLP encoding consists of a single byte with value **0xc0** plus the length of the list followed by the concatenation of the RLP encodings of the items. The range of the first byte is thus `[0xc0, 0xf7]`. -* If the total payload of a list is more than 55 bytes long, the RLP encoding consists of a single byte with value **0xf7** plus the length of the length of the payload in binary form, followed by the length of the payload, followed by the concatenation of the RLP encodings of the items. The range of the first byte is thus `[0xf8, 0xff]`. - -In code, this is: - -```python -def rlp_encode(input): - if isinstance(input,str): - if len(input) == 1 and chr(input) < 128: return input - else: return encode_length(len(input),128) + input - elif isinstance(input,list): - output = '' - for item in input: output += rlp_encode(item) - return encode_length(len(output),192) + output - -def encode_length(L,offset): - if L < 56: - return chr(L + offset) - elif L < 256**8: - BL = to_binary(L) - return chr(len(BL) + offset + 55) + BL - else: - raise Exception("input too long") - -def to_binary(x): - return '' if x == 0 else to_binary(int(x / 256)) + chr(x % 256) -``` - -### Examples - -The string "dog" = [ 0x83, 'd', 'o', 'g' ] - -The list [ "cat", "dog" ] = `[ 0xc8, 0x83, 'c', 'a', 't', 0x83, 'd', 'o', 'g' ]` - -The empty string ('null') = `[ 0x80 ]` - -The empty list = `[ 0xc0 ]` - -The encoded integer 15 ('\x0f') = `[ 0x0f ]` - -The encoded integer 1024 ('\x04\x00') = `[ 0x82, 0x04, 0x00 ]` - -The [set theoretical representation](http://en.wikipedia.org/wiki/Set-theoretic_definition_of_natural_numbers) of two, `[ [], [[]], [ [], [[]] ] ] = [ 0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc1, 0xc0 ]` - -The string "Lorem ipsum dolor sit amet, consectetur adipisicing elit" = `[ 0xb8, 0x38, 'L', 'o', 'r', 'e', 'm', ' ', ... , 'e', 'l', 'i', 't' ]` diff --git a/pages/ethereum-and-blockchain-technologies-and-research/research/CLL.md b/pages/ethereum-and-blockchain-technologies-and-research/research/CLL.md deleted file mode 100644 index c0e4dfb8f..000000000 --- a/pages/ethereum-and-blockchain-technologies-and-research/research/CLL.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -name: CLL -category: ---- - -### ECLL: Ethereum C-Like Language - -The purpose of ECLL is to provide a language that will be simple and friendly for users to write contracts in, but at the same time easily and efficiently compile into Ethereum script code. ECLL abstracts away concepts like pointers, direct memory access and jumping in favor of a more traditional syntax of conditionals, loops, arrays and variables. Function support, including first-class-function support, will be left to a future more powerful, but less efficient, language that will be denoted EHLL ("Ethereum High Level Language") - -The specification will be in three parts. The first part will define the language as an abstract syntax tree, formalized using LISP-style S-expression syntax, the second part will provide specifications for what each operation does, and the third will show how the AST is to be rendered in text. - -### Abstract Syntax Tree - -An **expression** is defined as follows: - -* A number is an expression -* A variable name is an expression -* `("arr" a b)` is an expression, where `a` and `b` are expressions. This is the equivalent of C's `a[b]`. -* `(OP a b)` is an expression, where `OP` is in the set `(+ - * / % s/ s% ^ < > <= >= ==)` -* `(OP a)` is an expression, where `a` is in the set `(- !)` -* The special values `tx.datan`, `tx.value`, `tx.sender`, `contract.address`, `block.number`, `block.difficulty`, `block.timestamp`, `block.parenthash` and `block.basefee` are expressions -* `("pseudo" a b)` is an expression, where `a` is a pseudoarray and `b` is an expression -* `("fun" a b...)` is an expression, where `a` is a returning function and `b...` contains the valid number of arguments - -A **pseudofunction** is defined as follows: - -* `block.contract_storage` is a pseudofunction - -A **pseudoarray** is defined as follows: - -* `tx.data` and `contract.storage` are pseudoarrays -* `("pfun" a b...)` where `a` is a pseudofunction and `b...` contains the valid number of arguments is a pseudoarray - -`contract.storage` is a **mutable pseudoarray**, and the other two are **immutable pseudoarrays**. - -A **returning function** is defined as follows: - -* `block.account_balance`, `sha256`, `sha3`, `ripemd160`, `ecvalid` are returning functions -* `array` is a returning function - -A **multireturning function** is defined as follows: - -* `ecsign` and `ecrecover` are multireturning functions - -A **multiexpression** is defined as follows: - -* `("mfun" a b...)` where `a` is a multireturning function and `b...` contains the valid number of arguments is a multiexpression - -An **acting function** is defined as follows: - -* `mktx` is an acting function - -A **left-hand-side expression** is defined as follows: - -* A variable is a left-hand-side expression. -* `("arr" a b)` is a left-hand-side expression, where `a` is a left-hand-side expression and `b` is an expression. -* `("pseudo" a b)` is a left-hand-side expression, where `a` is a mutable pseudoarray and `b` is an expression. - -A **statement** is defined as follows: - -* `("afun" a b...)` where `a` is an acting function and `b...` contains the valid number of arguments is a statement -* `("set" a b)` where `a` is a left-hand-side expression and `b` is an expression is a statement -* `("mset" a... b)` where `a...` is a list of left-hand-side expressions with the valid number of arguments and `b` is a multiexpression is a statement -* `("seq" a...)` where `a...` are statements -* `("if" a b)` where `a` is an expression and `b` is a statement -* `("if" a1 b1 "elif" a2 b2 "elif" a3 b3 ...)` where `ak` are expressions and `bk` are statements -* `("if" a1 b1 "elif" a2 b2 "elif" a3 b3 ... "else" c)` where `ak` are expressions and `bk` and `c` are statements -* `("while" a b)` where `a` is an expression and `b` is a statement -* `"exit"` - -### Definitions - -Pre-compilation, if there are `n` variables, each variable will be assigned an index in `[0,n-1]`. Let `ind(x)` be the index of variable `x`, and let `M[x]` be the contract memory at index `x` - -In the context of a right-hand-side expression: - -* Arithmetic works in the obvious way. `(* (+ 3 5) (+ 4 8))`, for example, returns 96. -* `a && b` is a shortcut for `!(!(a) + !(b))` -* `a || b` is a shortcut for `!(!(a + b))` -* A variable `x` should become `M[ind(x)]` -* `("arr" a b)` returns `M[M[ind(a)]+b]` -* `tx.datan` returns the number of data fields in the transaction -* `("pseudo" "tx.data" i)` returns the ith data field in the transaction or zero if `i >= tx.datan` -* `tx.sender`, `tx.value`, `block.basefee`, `block.difficulty`, `block.timestamp`, `block.parenthash` and `contract.address` return the obvious values. -* `("pseudo "contract.storage" i)` returns the contract storage at index `i`. -* `("fun" "block.account_balance" a)` returns the balance of address `a` -* `("pseudo" ("pfun" "block.contract_storage" a) b)` returns the contract storage of account `a` at index `b` -* `("mfun" "ecsign" hash key)` returns the `v,r,s` triple from the signature -* `("mfun" "ecrcover" h v r s)` returns the `x,y` public key -* `("mfun" "sha256" len arr)` returns the SHA256 hash of the string of length `len` starting from `M[ind(arr)]`. `sha3` and `ripemd160` work similarly -* `("fun" "array")` returns `2^160 + M[2^256 - 1]` and sets `M[2^256 - 1] <- 2^160 + M[2^256 - 1]` - -In the context of a left-hand-side expression: - -* A variable `x` returns `ind(x)` -* `("arr" a b)` returns `a + b` where `a` and `b` have already been evaluated -* `("pseudo" a b)` returns an object which, if set, modifies the value of the pseudoarray referent at index `a` to `b` instead of doing a memory set - -In the context of a statement: - -* `("afun" "mktx" dest value dn ds)` creates a transaction sending `value` ether to `dest` with `dn` data fields starting from `M[ind(ds)]` -* `("set" a b)` sets `M[a] <- b` where `a` and `b` have already been evaluated -* `("mset" a... b)` sequentially sets the memory index at each of the values in `a...` to a value from the multiexpression `b` -* `("if" a b)`, `("while" a b)` and derivatives will work as they do in other languages - -### Syntax - -* Arithmetic is done using infix notation using the [C++ operator precedence](http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B#Operator_precedence ): `^` then `* / % s/ s%` then `+ -` then `< <= > >=` then `==` then `&&` then `||`. That is to say, arithmetic formulas will behave as they normally do; for example, `(+ (* 3 5) (* x y))` would be (3 * 5 + x * y) and `(* (+ 3 5) (+ x y))` would be `((3 + 5) * (x + y))` -* `("arr" a b)` and `("pseudo" a b)` will both be represented as `a[b]` -* `("fun" a b...)`, `("mfun" a b...)`, `("afun" a b...)` and `("pfun" a...)` will all be represented as `a(b1,b2, ... ,bn)` -* Multiexpressions will be represented as `a1, a2, ... an` -* `("set" a b)` and `("mset a... b)` will be represented as `a = b` and `a1, a2 ... ,an = b`, respectively. -* `("seq" a...)` consists of each of the statements on their own separate line -* `("if" a b)` and `("while" a b)` will be represented as in Python, using the keyword directly followed by the expression for `a` and the indented statement for `b` -* Values can be represented either as integers or inside string quotes, in which case they will be treated as hexadecimal -* `exit` exits. - -**Examples:** - -Factorial: - - x = 1 - n = 1 - while x < 10: - n = n * x - x = x + 1 - -Fibonacci sequence: - - a = array() - a[0] = 1 - a[1] = 1 - i = 2 - while i < 70: - a[i] = a[i-1] + a[i-2] - i = i + 1 - mktx("0676d13c8d2cf5e9e988cc3b5f6dfb5a6a3938fa",a[69],70,a) - -A real example - simple forwarding contract to create a transferable account: - - if tx.value < tx.basefee * 200: - exit - else: - a = contract.storage[2^256 - 1] - if !(tx.sender == a) && (tx.sender > 0): - exit - if tx.data[0] == 2^160: - contract.storage[2^256 - 1] = tx.data[1] - else: - if a == 0: - contract.storage[2^256 - 1] = tx.sender - o = array() - i = 0 - while i < tx.datan - 1: - o[i] = tx.data[i+1] - i = i + 1 - mktx(tx.data[0],tx.value - tx.basefee * 250,i,o) - -### Alternative Syntax: C++ style - -* `("seq" a...)` is implemented by separating the statements with semicolons. Newlines are ignored. -* `("if" a b)` and `("while" a b)` will be represented as in C++, storing `a` inside brackets and `b` inside curly brackets - -### Alternative Syntax: Lisp style - -The AST is used as the code directly, with the minor modification that `("fun" a b...)`, `("pfun" a b...)` and `("mfun" a b...)` are replaced with `(a b...)`. diff --git a/pages/ethereum-and-blockchain-technologies-and-research/research/Chain-Fibers-Redux.md b/pages/ethereum-and-blockchain-technologies-and-research/research/Chain-Fibers-Redux.md deleted file mode 100644 index 75b067fbc..000000000 --- a/pages/ethereum-and-blockchain-technologies-and-research/research/Chain-Fibers-Redux.md +++ /dev/null @@ -1,121 +0,0 @@ ---- -name: Chain Fibers Redux -category: ---- - -# Blockchain Scalability: Chain-Fibers Redux - -## History - -I came up with the first seed of this idea while chatting to Janislav Malahov in Berlin in Spring 2014. Unfortunately, the original article I wrote was lost along with my laptop when it was stolen in Vienna. After chatting over the principles with Vitalik more recently, we made a number of alterations and formalisations, mainly to the validation and the sub-state cutting mechanisms. What follows is a fairly complete picture of one particular possible plan for block chain scalability in a later version of Ethereum. - - -## Overview - -The basic idea of Chain-Fibers is unchanged from a year ago; split the state-space up into strata and have separate transaction collators specialising in one or a number of state sub-spaces. Transactions requiring interactions from many a subspace would be accordingly more expensive (since collators would have to maintain presence on multiple chains) and take longer to execute (since there is a lesser chance that any given block would contain a superset of the transaction's subspaces). Validity of a transaction is verifiable in isolation through the provision of comprehensive Merkle proofs to its inputs alongside it in the block in which it is included. - -The subtleties lie in precisely what governs the division of subspaces (my original proposal included the automated splitting, merging and rotation of subspace-divisions in order to best deliver internal coherency), how security is maintained within comparatively worthless subspaces and how this can play well with Proof-of-Stake (the original was based upon a master PoW chain, feeding off an idea put forward by Max Kaye in early 2014 to disassociate block chain archival from transition semantics). - -Basic idea is to have a number of chains (e.g. N), each detailing the state-transitions for only a strata of the entire system state (i.e. a state subspace). Following from programming terminology, these might be termed "fibers". Accounts thus belong to a subspace and as such a single fiber; the fiber to which they belong can be determined simply from the first log2(N) bits of the address. N can increase or decrease, and is a value maintained within the housekeeping information on the "Master Chain". - -The Master Chain in maintained by a set of bonded Validators V, with the number of validators proportional to N. A random selection of validators validate each block produced, and validators ultimately vote to form consensus over the Master Chain. Each block of the Master Chain maintains a reference to the header of each fiber. - -Transaction collators produce blocks (accepting fees from transactors), and pay Validators some of the fees collected to include the hash of their block in the main chain. Blocks are produced across a particular "home set" of fibers; this is basically just the set of fibers of which they maintain the State Trie. Their blocks may involve transactions over one or many of these fibers, though none outside their "home set". - -"Fishermen" is a term given to freelance checkers. Since block validation and availability are both important, and since it is possible that sets of validators may be contractually bribed, it is important to have a mechanism to involve additional rational individuals in acting as "whistle-blowers" to avoid bogging the other validators needlessly checking all blocks. The fishermen basically pay to attempt to convince a quorum of validators that a previously validated block is invalid (or unavailable, which we assume is equivalent). If a fisherman demonstrates a validator (or, more likely, set of validators) acted in a dishonourable fashion, then they get to claim all of their bonds. To avoid DoSing the validators with spurious challenges, a fee is payable. - - -## Schematic - -Sorry for the not-quite ASCII-art. I'm not quite as 1337 at Inkscape as Vitalik. - -``` -Transactors ==TX+FEE==> Collators ==BLOCK+FEE==> Validators -make transaction validate transaction, random selection chosen to audit - produce Comprehensive Merkle TX/PSR/CMP contents & availability, - Proof and Post State Root, all placed in PoS-consensus master block - collate into X-fiber Block - - Fishermen ==CHALLENGE+FEE==> Validators - search for invalid or a selection adjudicate challenge - unavailable X-fiber blocks -``` - - -## Transactors - -Transactors are pretty much exactly the same as in Ethereum 1.0 - they are the users of the system. - -### Transactors: make transaction - -Transactors make a transaction much like they do in the existing Ethereum system. One or two minor differences - addresses can be used as a distance metric; those sharing the same number of initial bits are considered "closer", which means a greater certainty into the future that they will continue to be contained in the same state subspace. Contracts are naturally created in the same state subspace as the creator. - -Transactions, like Collators, operate over a number of fibers; perhaps one perhaps all, probably somewhere in between. Submission to collators may be directed through fiber sub-network overlays. - -Submission and payment to the collators happens much as existing transaction submission to miners happens in Ethereum 1.0. - - -## Collators - -Collators maintain presence on at least two peer sub-network overlays; the Validators overlay, and one or more fiber overlays. The fiber overlays may provide directed transaction propogation. Collators "collate" on a set of fibers. They maintain a full fiber-chain for each fiber they collate over, and can accept all transactions that involve any combination of their fiber set. The greater this combination, then the greater their "transaction net", but the greater their overall disk/memory footprint. - -### Collators: validate transaction - -On receipt of a transaction, they go through the usual Ethereum 1.0 rites of checking payment is enough, initial balances &c. Once basic validation is done, they attempt to execute it, throwing it out if it touches any fiber that is not part of collator's fiber set. - -### Collators: produce Comprehensive Merkle Proof and Post State Root - -Collators provide each post-state-root (as is found in the transaction receipt of Ethereum 1.0) and append to the block Merkle proofs and associated hints (e.g. contract code) for all inputs (balance, nonce, state, code) from all subspaces that are required for the evaluation of each transaction from a previously known post-state-root. - -This allows an auditor to, without anything other than the previous post-state-root for each fiber, determine the validity of the block. - -### Collators: collate into X-fiber Block - -A Cross Fiber Block is created from the total information collated. This includes transactions, transaction receipts (post-state-roots), Comprehensive Merkle-Proofs and associated hash-hints. This block does not include any consensus-specific information such as timestamping, uncles &c. - - -## Validators - -Validators (who might be better named auditors) are bonded particpants, chosen regularly from the highest bidders, who take a small fee for the ultimate maintenence of the network. Their job, as a whole, is to form a judiciary and ultimate authority over the validity and transaction contents of the chain. We generally assume that they are mostly benevolent and cannot all be bribed. Being bonded, validators may also be called to audit and stake their bond on an opinion over validity or information-availability. - -### Validators: all placed in PoS-consensus master block - -They maintain signing control over the Master Chain. The Master Chain (MC) encodes all PoS/consensus stuff like timestamping and includes its own little state root for recording validator's bond balances, ongoing challenges, fiber block header-hashes and any other housekeeping information. - -Each master block (MB), a set of collated X-Fiber Blocks (XBs) are taken; these must be non-overlapping, so that each fiber belongs to only a single XB. - -### Validators: random selection chosen to audit TX/PSR/CMP contents & availability - -For each MB we have a number of XSBs referenced from the MB's Trie. Each fiber is assigned a randomly selected set of validators, and the validators must review whatever XB contains their assigned fiber. Validation includes attaining the XB, finding the previous PSRs for each of the fibers (placed in the MB) and checking that the proofs in its CMP, cover all required inputs to the transactions collated within and that the PSR is indeed the final state root when all are executed. - -The block is considered valid iff all assigned validators sign it. Signing it is considered an assertion that the block contents are both valid and available for a probabilistically long "challenge period" in which a Fisherman may challenge. Any challenge to the block's validity which is ultimately upheld by a full consensus of a randomly selected set of validators (ultimately ending with a majority vote, should it be doggedly contested) will mean the instant loss of the bond. - - -## Fishermen - -Fishermen (who might be called bounty hunters) are the freelance error-checkers of the system. The watch the validators in the hope that they can find wrong-doing. To help guarantee presence, payouts are designed to be huge. The costs of challenging are small but not insignificant. - -### Fishermen: search for invalid or unavailable X-fiber blocks - -They check the X-fiber blocks looking for validity errors and/or inavailability of data. When they find an invalid block or unavailable data, they launch a challenge (for a small fee, paid to validators) in the hope that a sufficiently large portion of validators will concur. If they succeed and validators ultimately uphold the challenge, then they receive the bonds of all validators who had previously asserted validity/availability of the information. - -### Fishermen's Challenge: - -1. Fisherman finds an invalid/unavailable block not yet outside its "challenge period" (10-30 blocks); pays a fee, submits a challenge transaction into the master chain; -2. A randomly selected set of validators (e.g. of order e.g. sqrt(N)) ++ any validators that self-select (through doubling their bond), check the block that was challenged; each votes Y or N to the block's validity; - - If N, the validator receives a small payment Pn. - - If Y, the validator stakes their bond, though receives a larger payment Py (perhaps Py = 2Pn). -3. The outcome of the challenge (probably accumulated into the following block) is: - - If more than 66% of validators vote Y (valid), then the challenge ends. The Fisherman loses their fee, but may reinitiate a challenge. - - If at least one validator votes Y (valid), then the challenge continues with a second, larger set of randomly selected validators. All bonds are staked. - - If all validators vote N (invalid), then the block is recorded as invalid and the Fishermen receives the bond of all validators that have asserted the blocks validity. This is a very large payoff. - - NOTE: If the set includes all validators, then it's a simple majority-carries rule. - - -## Other differences - -- All addresses are contained in a lookup table unique to each state subspace; this means they can be referenced through a small number of bits and avoid large amounts of wasted entropy in the RLP for proofs &c. - -## Notes - -- Once a block is out of the challenge period, it is considered unassailable. If it does turn out to be bad, then it must be fixed in the same way as a protocol upgrade. As such it is likely that validators and other large stakeholder would act as Fishermen to protect their investment. diff --git a/pages/ethereum-and-blockchain-technologies-and-research/research/Generalized_Merkle_DHT.md b/pages/ethereum-and-blockchain-technologies-and-research/research/Generalized_Merkle_DHT.md deleted file mode 100644 index 2bfd4a8df..000000000 --- a/pages/ethereum-and-blockchain-technologies-and-research/research/Generalized_Merkle_DHT.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -name: Generalized Merkle DHT -category: ---- - -As blockchain technologies move beyond the "1.0" model of every node processing every transaction, and a more diverse ecosystem including "light clients" that achieve security by downloading only a small portion of the blockchain and extracting the rest of the data on-demand through hash-based authentication comes into play, and particularly in the long term as scalability models essentially turn _every_ node into a light client, there arises the need to develop a strong, robust and effective networking infrastructure to handle the load. Ideally, the core technology should be built to be maximally generalized, so that the same core code and network can be used for multiple blockchain, as well as non-blockchain, applications. - -The kernel of the work is the distributed hash table, as pioneered by projects such as [Kademlia](http://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf) and implemented in BitTorrent and now IPFS. The distributed hash table uses a network where nodes are organized to point to other nodes in such a way that, given a value `v` with a key `k`, a node knowing `k` can quickly discover the location of the node that stores `v`; usually we say `k = H(v)` for some hash function (eg. SHA256, SHA3). Theoretically, such a DHT can be used to very easily enable light client support for _any_ blockchain protocol with sufficiently high degrees of Merkle tree support, and even use one codebase for light and full clients, the only difference being that light clients would use the DHT as a "hard drive" in place of their actual computer disks. - -However, this model has an important flaw: it requires `log(n)` lookups in order to receive a proof. Hence, if the network latency is 500ms, and a tree has a depth of 10 nodes, then the total lookup and verification will take at least five seconds. Simpler light client protocols tend to avoid this obstacle by simply having a "request-response" model: light node A wants a proof for X, full node B provides _all_ relevant Merkle nodes, and light node A verifies. The DHT approach has the benefit of extreme generality; the dedicated Merkle proof approach has the benefit of higher speed. However, we can arguably combine the benefits of both. - -The protocol at base level is as follows: suppose there exists a program `P` with an initial state `S_0`, run in a virtual machine which has access to an `INVHASH` ("inverse hash") opcode. `P` may be a simple iterative descent script to fetch a Merkle tree node, or it may be a complete proof of transaction correctness, or even a search process. Suppose there exists a light client which wants `P(h)` given some "root hash" value `h`, together with a proof; we consider `h` part of `S_0`. The light client initializes `D <- {}`, `S <- S_0` and repeatedly undergoes the following process: - -1. Run `P` until it encounters either an end state (in which case exit) or an `INVHASH` opcode with argument `k`, such that the node does not know a value `v` such that `sha3(v) = k`. -2. Let `S_c` be the current state after this point. Set `S <- S_c` -3. Send a message `(P, S_c)` to another node on the network, using `k` as a pointer to finding that node (eg. via the Kademlia algorithm) -4. That node initializes `D' <- {}`, and runs `P` until it encounters an `INVHASH` opcode with argument `k`, such that the node does not know a value `v` such that `sha3(v) = k`. It immediately halts and replies back with `D'` -5. Merge `D'` into `D` (ie. set `D <- D U D'`), and go to step 1. - -Essentially, the light client repeatedly asks a node on the network "run this program as long as you can until you find a value you cannot resolve, then reply back to me with the values you did manage to resolve", and keeps on accumulating nodes in its hash until eventually it can locally run through the entire program. - -This process takes: - -* Linear time in the number of computational steps (as every step of execution, assuming honesty, is computed a maximum of exactly twice, once by the local node and once by the remote node) -* Anywhere from constant to linear time in the number of `INVHASH` executions, depending on what portion of all available key/value pairs every node has and how well they are clustered - -It can be viewed as a superset of a DHT and Bitcoin-style SPV protocols, and is adaptable to state get operations, transaction proofs, receipt lookups, search operations, trie next/prev operations, proofs of non-membership, and generally any kind of computation on blockchain data. If implemented correctly it can be used for both Ethereum, Bitcoin proposals such as tree chains, and even parts of a decentralized search engine. - -In order to prevent abuse, the program execution instance will naturally need to have a gas limit. There are two ways of doing this: - -1. Have a hard fixed limit (eg. 1 million), and rely on the same anti-DDoS techniques that are normally used for messages that have a bounded response time. -2. Require each `(P, S)` message to specify a gas limit, and require either proof of work or a micropayment in exchange. If there is not enough gas, then simply return just as if you have encountered an `INVHASH` you cannot resolve. However, this protocol may not be optimal when there is high uncertainty about when unresolvable `INVHASH` operations will pop up. -3. The sending party creates a ticket which says "I am willing to pay $X per step". The receiving party signs their reply message. The sender must then micro-pay after the fact. If the sender does not do so honestly, then the receiver can "go to blockchain court" and have the auditing contract verify the correct payment to be made, and if the correct payment was not in fact made force the sender to pay a fine. \ No newline at end of file diff --git a/pages/ethereum-and-blockchain-technologies-and-research/research/HPOC_2015.md b/pages/ethereum-and-blockchain-technologies-and-research/research/HPOC_2015.md deleted file mode 100644 index 5714df7b1..000000000 --- a/pages/ethereum-and-blockchain-technologies-and-research/research/HPOC_2015.md +++ /dev/null @@ -1,92 +0,0 @@ ---- -name: HPOC 2015 -category: ---- - -### HPoC 2015 - -Last year we released the "Hard Problems of Cryptocurrency" document, detailing what we thought were some of the harder technical and economic problems keeping cryptocurrency and cryptoeconomic technology from mainstream viability. The list included issues such as scalability, more efficient consensus algorithms, public goods incentivization, reputation systems, among a number of other challenges. Over the past year, a large portion of these problems have arguably been solved, or at least research has been brought forward to the point where additional progress is no longer a matter of zero-to-one fundamental breakthroughs, but rather tweaking and empirical testing through real-world implementation. At the same time, there are a substantial number of challenges that still remain, although the problems here are substantially more specific and less broadly reaching than previously. - -### Meta-consensus - -In order to remain relevant in a rapidly evolving technological landscape, software must update, and software that does not update has no alternative but to slowly fade away and die as it is replaced by superior technology. There is no reason why this principle should not apply to decentralized crypto-protocols as well. However, the need to make upgrades to decentralized crypto-systems leads to a natural question: who controls the updating process? As of the time of this writing, the Bitcoin community is going through the process of deciding whether or not to increase the maximum block size from 1 MB to 20 MB, and the lack of a deliberately instituted decision-making process has lead to the situation where the de-facto decision-making process essentially amounts to political debate among a small number of core developers. - -Is there a way of building _intra-protocol meta-consensus_ - that is, a mechanism inside the protocol that facilitates agreement on upgrades to the protocol, perhaps using some kind of consensus voting? Such a system would have a number of benefits, including greater flexibility, less reliance on political processes that end up being centralization risks, and can arguably ensure a greater voice to all participants in the protocol, not just those that are socially well-connected (see Jo Freeman's [The Tyranny of Structurelessness](http://www.jofreeman.com/joreen/tyranny.htm) for more on this). - -Desirable properties of meta-consensus include: - -* Incentives to agree on beneficial protocol changes -* Some kind of guarantee that applications built under the old protocol will remain maximally effective under the new protocol. Note that a part of this will likely be some kind of object-oriented encapsulation mechanisms in order to steer developers away from using features which are highly protocol-specific -* Resistance against the mechanism being corrupted in some sense and forced to lead to an undesirable protocol change -* The ability for users to automatically upgrade to a newly chosen protocol without having to download a new client - -Existing work on this includes [Arthur Breitman's Tezos](http://tezos.com/), Bitshares' [delegated proof of stake](https://bitshares.org/blog/delegated-proof-of-stake/), and the not-yet-released Ethereum 2.0 proposal. - -### Public Goods Preference Revelation and Incentivization - -The other major problem in crypto-protocol development is the analogous funding problem: how will protocol upgrades, and more generally public-good ecosystem middleware, be paid for? In the initial phase of development, the concept of "crowdsales" has proven to be absolutely invaluable, providing millions of dollars of funding for efforts which would have otherwise been relegated to being little more than volunteer side projects. However, crowdsales by themselves have a fundamental problem: they are front-loaded, creating heavy incentives for short-term marketing but less so for long-term performance, and they are limited one-time events from which the funds received eventually run out. And even if the funds could somehow be managed so as not to run out, crypto-protocol development would be permanently centralized in a single organization. What would be ideal is, once again, some kind of intra-protocol mechanism for incentivizing the development of public goods. - -Public goods incentivization has a long and established literature, including numerous [results](http://www.ebour.com.ar/pdfs/Yan%20Chen%20Incentive%20Compatible%20Mechanisms%20for%20Public%20Goods.pdf) [from](http://www.coll.mpg.de/book/ci21-mechanism-design-approach-public-good-provision) [mechanism](http://www.econ.ucsb.edu/~tedb/Courses/UCSBpf/pflectures/revelation.pdf) [design](http://people.hbs.edu/jgreen/Preferences_Public_Goods_1976.pdf) and [assurance contract theory](http://en.wikipedia.org/wiki/Assurance_contract) on the topic of both how to fund the development of public goods and on the equally important question of deciding which public goods are worth funding in the first place. In a blockchain context, the funding problem is somewhat easier than in a private-market context, because we have the ability to "tax" all currency holders via inflation and taking the excess of transaction fees minus consensus costs, but the preference revelation problem is much harder; a human government can try to use informal judgement to figure out which public goods are worth supporting and which ones are not, but a blockchain literally cannot tell the difference between a trustworthy development fund, an untrustworthy development fund, a tobacco lobbying company, the "zero address" from which coins can never be spent and a scammer. Hence, it must rely entirely on some kind of mechanism design to elicit this information from the community. - -The challenge here is applying these guarantees to a blockchain context. Particular challenges include: - -* Being incentive-compatible even given the assumption that users can securely and trustlessly bribe each other, eg. via contracts (cooperative game theory can help here) -* Being incentive-compatible even given the assumption that the attacker may have a superior ability to coordinate versus the individual participants (cf. P + epsilon attacks; cooperative game theory may be insufficient here as it generally assumes that collections of users can either coordinate totally or not coordinate at all) -* Avoiding Caplanian "rational irrationality" critiques, ie. providing sufficiently large incentives for users to learn about which funds are worth supporting and not simply immediately click on what looks nicer - -The general model can be thought of as follows: - -* There exist N public goods, represented by addresses owned by funds that promise to spend the money on particular public goods (eg. development). Anyone can register an address in this set, perhaps after paying some fee -* Users need to, using some mechanism, select how to split up funding pool D between these goods (D may be a maximum size; the mechanism may end up "burning" some of D) -* Attackers creating fake "public goods" that really just send money to themselves can be seen simply as being public goods with a payoff ratio of 1 that happens to be concentrated entirely in a single player. The reason why attackers winning is socially bad is that other "legitimate" public goods will have much higher payoff ratios -* If necessary, we can rely on the users having security deposits, eg. being validators - -### Coercion-proof Voting - -Ari Juels in 2001 came up with a [protocol](http://www.arijuels.com/wp-content/uploads/2013/09/JCJ10.pdf) for "coercion-resistant electronic elections" - a way of doing voting online such that not only is it possible for users to vote without revealing to others who they voted for, but it is in fact not possible to prove to anyone else who you voted for _even if you wanted to_ - making it impossible to coerce or bribe people to vote. One possible route to solving the preference revelation problem, as well as voting games in general, is to implement this kind of scheme, making it much harder to coordinate. It is by no means a complete solution, since a user that controls two identities can still have those two identities securely collude with each other, but combined with a wealth deconcentration assumption it would make systems substantially more robust. - -The challenge is, is it possible to implement some kind of coercion-resistant electronic election into a decentralized public blockchain context? The primary challenge here is the complete lack of any specific parties that have private keys and can be trusted not to collude with each other; the system would need to be completely public. - -Note: an alternative to making _cryptographically_ coercion-resistant electronic elections is making _cryptoeconomically_ coercion-resistant electronic elections: come up with some kind of mechanism such that if a voter proves to another party any nonzero quantity of information about who they voted for, that party can exploit them for an expected nonzero return at their expense (if this exploitation can be made to be _unprovable_, then even better, as it reduces the possibility of effective circumvention through reputation). - -### Anti-pre-revelation - -There are many protocols such as [Schellingcoin](https://blog.ethereum.org/2014/03/28/schellingcoin-a-minimal-trust-universal-data-feed/), [Augur](http://augur.net), N-of-N protocols in random number generation, etc, that rely on some notion of users first cryptographically "committing" to some value `x`, eg. by submitting `H(x)` for some hash function, and then in a later stage "revealing" the value for `x` that they submitted - with non-revelation or incorrect revelation being punishable by security deposit loss. However, many of these protocols only work effectively if users' answers during the first phase are private; if users can collude to share information, and particularly if they can _provably_ share information, then the mechanism's effectiveness decreases as collusion becomes easier. - -Suppose a commit-reveal protocol where all users must supply either 0 or 1, and they are "supposed to" randomly choose this value. In the first step, each user must pick a (irrelevant) salt `s`, and provide `H([s, v])` where `v` is either 0 or 1. In the second step, the user must supply their values of `s` and `v`, and have them be checked against the commitment. The sum of all values `v` mod 2 is then taken as a single bit of random output. Here, hypothetically all players can talk to each other and provably coordinate on voting either 0 or 1. However, we can design an anti-pre-revelation protocol as follows: any party can choose to register a bet against any other party that they will vote on some specific value with at last a 60% probability (ie. if A bets that B will bet 0, then if B ends up providing `v = 0` then B gets 2 units out of A's security deposit, and if B ends up providing `v = 1` then A gets 3 units out of B's security deposit). Hence, if party `P[i]` reveals to party `P[j]` their `v` value, or even a zero-knowledge proof of their `v` value with more than 60% probability, they can be exploited (note that the 60% margin can be cut down further to make _any nonzero revelation_ costly by using [scoring rule theory](http://en.wikipedia.org/wiki/Scoring_rule)). - -A challenge is to either take this path and try to expand it into an environment where the potential value space is much larger and probabilities of voting may not be known a priori, or find some other approach to make it cryptographically impossible or cryptoeconomically expensive to reveal one's hidden value before one is supposed to. Tailoring to specific applications (eg. linear Schellingcoin price voting) is suboptimal but acceptable. A particular problem is the existence of zero-knowledge proofs: one can use zk-SNARKs (or simply plain ZKPs) in order to reveal any information about `v` and prove that this information is correct by using the provided hash `H([s, v])` _without revealing anything about `s`_ or any information about `v` that is undesired; hence, a solution should be secure against _all_ kinds of partial information revelation that may be useful, and not simply revealing the exact value of `v`. - -### Random Number Generation - -A number of protocols, including consensus protocols, blockchain-based lotteries, scalable sampling schemes, etc, require some kind of random number generation in the protocol. Proof of work provides an answer easily, because one cannot compute ahead of time what the result will be, and once a result is found not revealing it carries a large opportunity cost. However, proof of work is extremely expensive, requiring constant expenditure equal to the security margin. - -An alternative is N-of-N commit-reveal, as exemplified in Tomlion's RANDAO protocol, works as follows: - -1. `n` players `P[1] ... P[n]` with security deposits of size `D` in the protocol choose random values `V[1] ... V[n]` with `0 <= v[i] < 2**256`, and `P[i]` submits `H(V[i])` during round one. -2. In round two, every player who submitting a value `H(V[i])` must submit `V[i]`. -3. If all players submit their value correctly, then `(V[1] + ... + V[n]) % 2**256` is taken as a random seed, and all players are rewarded with `D * i` where `i` is an interest rate (eg. 0.0001 per period). -4. If not all players submitted their value correctly, then all players who participated get `D * i`, all players who did not participate lose their entire deposit and are kicked out, and the remaining players repeat the game until eventually all N players cooperate and reveal their values. - -If you are the last player to participate, then you can manipulate the value at a very high cost, and even then only by replacing it with a random value next time around (ie. one can avoid unfavorable values, but one cannot target favorable values or even choose between two known values). However, the mechanism has the limitations that (i) it relies on a non-collusion assumption, (ii) the randomness that it provides is not nearly as fast as proof of work randomness, making it useless for some specific intra-block applications where proof of work shines, and (iii) it can lead to honest players losing large amounts of money from a network attack. Mitigating problem (iii) necessarily involves exacerbating problem (ii), and vice versa. - -The open-ended challenge is to come up with a mechanism inside of a cryptoeconomic context which provides random numbers as output with maximally relaxed security assumptions and maximal robustness and resilience to attackers - ideally, a mechanism with the same properties as proof of work but without (or with only a negligible fraction of) its cost. - -### Anti-censorship - -Public blockchains particularly have a strong need to be censorship-resistant, ie. to be able to get transactions into the chain even if powerful parties do not want them included. This is important not just for controversial Wikileaks-style applications; even ordinary financial applications, commit-reveal protocols, etc, could have their security threatened if there was a way of effectively preventing "challenge" messages from entering the blockchain. - -If the set of participants willing to collude to censor is smaller than 33%, then the problem is fairly trivial. If the set is greater than 33%, however, then we know that those participants have the power to shut down the network, albeit at very high cost to themselves. Hence, the problem becomes somewhat different: how do we make it impossible for colluding censors to censor specific transactions _without censoring everything else as well_? - -One possible route to take is some kind of commit-reveal protocol, where users submit a hash of a transaction plus proof that the transaction is available, and then the transaction sender is somehow bound to include the transaction itself once it is revealed (ie. blocks that do not include the transaction will be invalid). However, this has the problem that (i) proof of availability is very hard to implement, and (ii) colluding censors can simply require the submission of a transaction alongside its proof. In general, any protocol will likely be vulnerable to "colluding censors can simply require a zero-knowledge proof of X", but the challenge is making such a requirement maximally inconvenient for all parties to implement. - -### Privacy - -Blockchains are often hailed as an alternative to centralized networks that rely on trusting specific parties. However, one of the major areas in which people actually do strongly distrust centralized parties in real life is in the area of privacy, and blockchain protocols by themsleves are even more public than centralized systems. Hence, blockchain-based solutions to privacy will likely need to go a bit beyond simply creating a decentralized database and being done with it; effort must be made into creating protocols for maximally broad categories of applications (eg. payments, financial contracts, identity and reputation info publication) that combine blockchain-based data publication with protocols that preserve individual privacy, and allow individuals maximum freedom in what facts about themselves to expose to what parties. - -Sub-problems of this problem include: - -* Fully anonymous currency (for existing work see Zerocash; Zerocash's largest current flaw is arguably the long 90s transaction signing period arising from its usage of zkSNARKs) -* A privacy-preserving reputation system that allows users to create "zero-knowledge reputation certificates" proving that they have some reputation score according to the target's desired metric but revealing minimal other personal information -* A financial contract system that allows users to hide the code and contents of their contracts to a maximal possible extent -* A maximally privacy-preserving decentralized internet-of-things platform diff --git a/pages/ethereum-and-blockchain-technologies-and-research/research/Parallel-Block-Downloads.md b/pages/ethereum-and-blockchain-technologies-and-research/research/Parallel-Block-Downloads.md deleted file mode 100644 index 130d71ae9..000000000 --- a/pages/ethereum-and-blockchain-technologies-and-research/research/Parallel-Block-Downloads.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -name: Parallel Block Downloads -category: ---- - -New network protocol & strategy. - -### Goals -- Achieve parallel downloads of chain -- Introduce framework that can form basis of Swarm -- Minimise unnecessary block transfers - -### Basic Overview - -- Two peers connect & say Hello. Hello includes the TD & hash of their best block. -- The client with the worst TD asks peer for full chain of just block hashes. -- Chain of hashes is stored in space shared by all peer connections, and used as a "work pool". -- While there are hashes in the chain of hashes that we don't have in our chain: - - Ask for N blocks from our peer using the hashes. Mark them as on their way so we don't get them from another peer. - -### Required Changes - -Network protocol: 33 - -Additional parameters to Hello: -- `TD`: Total Difficulty of the best chain. Integer. -- `BestHash`: The hash of the best (i.e. highest TD) known block. -- `GenesisHash`: The hash of the Genesis block. - -Additional Message types: -- `0x17`: `GetBlockHashes` [ `hash` : `B_32`, `maxBlocks`: `P` ]: Requests a `BlockHashes` message of at most `maxBlocks` entries, of block hashes from the blockchain, starting at the parent of block `hash`. Does not _require_ the peer to give `maxBlocks` hashes - they could give somewhat fewer. -- `0x18`:`BlockHashes` [ `hash_0`: `B_32`, `hash_1`: `B_32`, .... ]: Gives a series of hashes of blocks (each the child of the next). This implies that the blocks are ordered from youngest to oldest. -- `0x19`:`GetBlocks` [ `hash_0`: `B_32`, `hash_1`: `B_32`, .... ]: Requests a `Blocks` message detailing a number of blocks to be sent, each referred to by a hash. Note: Don't expect that the peer necessarily give you all these blocks in a single message - you might have to re-request them. - -Remove Message types: -- `GetChain` -- `NotInChain` \ No newline at end of file diff --git a/pages/ethereum-and-blockchain-technologies-and-research/research/Problems.md b/pages/ethereum-and-blockchain-technologies-and-research/research/Problems.md deleted file mode 100644 index 7a013aad6..000000000 --- a/pages/ethereum-and-blockchain-technologies-and-research/research/Problems.md +++ /dev/null @@ -1,388 +0,0 @@ ---- -name: Problems -category: ---- - -The science of cryptography, which has existed to some degree for millennia but in a formal and systematized form for less than fifty years, can be most simply defined as the study of communication in an adversarial environment. In a similar vein, we can define cryptoeconomics as a field that goes one step further: the study of economic interaction in an adversarial environment. To distinguish itself from traditional economics, which certainly studies both economic interaction and adversaries, cryptoeconomics generally focuses on interactions that take place over network protocols. Particular domains of cryptoeconomics include: - -* Online trust and reputation systems -* Cryptographic tokens / cryptocurrencies, and more generally digital assets -* Self-executing "smart" contracts -* Consensus algorithms -* Anti-spam and anti-sybil attack algorithms -* Incentivized marketplaces for computational resources -* Decentralized systems for social welfare / mutual aid / basic income -* Decentralized governance (for both for-profit and non-profit entities) - -The increasing prominence of cryptoeconomics in the last five years is to a large extent the result of the growth of cryptocurrencies and digital tokens, and brings a new, and interesting, dimension to cryptography. While before cryptography was, by and large, a purely computational and information-theoretic science, with strong guarantees built on security assumptions that are close to absolute, once money enters the picture the perfect world of mathematics must interact with a much more messy reality of human social structures, economic incentives, partial guarantees and known vulnerabilities that can only be mitigated, and not outright removed. While a cryptographer is used to assumptions of the form "this algorithm is guaranteed to be unbreakable provided that these underlying math problems remain hard", the world of cryptoeconomics must contend with fuzzy empirical factors such as the difficulty of collusion attacks, the relative quantity of altruistic, profit-seeking and anti-altruistic parties, the level of concentration of different kinds of resources, and in some cases even sociocultural circumstances. - -In traditional applied cryptography, security assumptions tend to look something like this: - -1. No one can do more than 279 computational steps -2. Factoring is hard (ie. superpolynomial) -3. Taking nth roots modulo composites is hard -4. The elliptic curve discrete logarithm problem cannot be solved faster than in 2n/2 time - -In cryptoeconomics, on the other hand, the basic security assumptions that we depend on are, alongside the cryptographic assumptions, roughly the following: - -1. No set of individuals that control more than 25% of all computational resources is capable of colluding -2. No set of individuals that control more than 25% of all money is capable of colluding -3. The amount of computation of a certain proof of work function that can be accomplished with a given amount of money is not superlinear beyond a point which is reasonably low -4. There exist a non-negligible number of altruists and a non-negligible number of crazies or political opponents of the system, and the majority of users can be reasonably modeled as being close to economically rational -5. The number of users of a system is large, and users can appear or disappear at any time, although at least some users are persistent -6. Censorship is impossible, and any two nodes can send messages to each other relatively quickly. -7. It is trivial to generate a very large number of IP addresses, and one can purchase an unlimited amount of network bandwidth -8. Many users are anonymous, so negative reputations and debts are close to unenforceable - -There will also be additional security assumptions specific to certain problems. Thus, quite often it will not even be possible to definitively say that a certain protocol is secure or insecure or that a certain problem has been solved. Rather, it will be necessary to create solutions that are optimized for particular empirical and social realities, and continue further and further optimizing them over time. - -## Technology - -The decentralized consensus technology used in Bitcoin is impressive to a very large extent because of its simplicity. A 30-year-old problem in computer science was solved via a mechanism which is simple to implement, and so simple to understand that even some semi-technical teenagers can describe the entirety of how it works. However, at the same time the technology in its current form is very limited. The scalability in Bitcoin is very crude; the fact that every full node needs to process every transaction is a large roadblock to the future success of the platform, and a factor preventing its effective use in micropayments (arguably the one place where it is the most useful). Timestamping is flawed, and proof-of-computation algorithms are very limited in the types of computation that they can support. The fact that the original solution was so "easy", however, suggests that there is still a large opportunity to improve, and there are a number of directions in which improvement could be directed. - -### 1. Blockchain Scalability - -One of the largest problems facing the cryptocurrency space today is the issue of scalability. It is an often repeated claim that, while mainstream payment networks process something like 2000 transactions per second, in its current form the Bitcoin network can only process seven. On a fundamental level, this is not strictly true; simply by changing the block size limit parameter, Bitcoin can easily be made to support 70 or even 7000 transactions per second. However, if Bitcoin does get to that scale, we run into a problem: it becomes impossible for the average user to run a full node, and full nodes become relegated only to that small collection of businesses that can afford the resources. Because mining only requires the block header, even miners can (and in practice most do) mine without downloading the blockchain. - -The main concern with this is trust: if there are only a few entities capable of running full nodes, then those entities can conspire and agree to give themselves a large number of additional bitcoins, and there would be no way for other users to see for themselves that a block is invalid without processing an entire block themselves. Although such a fraud may potentially be discovered after the fact, power dynamics may create a situation where the default action is to simply go along with the fraudulent chain (and authorities can create a climate of fear to support such an action) and there is a coordination problem in switching back. Thus, at the extreme, Bitcoin with 7000 transactions per second has security properties that are essentially similar to a centralized system like Paypal, whereas what we want is a system that handles 7000 TPS with the same levels of decentralization that cryptocurrency originally promised to offer. - -Ideally, a blockchain design should exist that works, and has similar security properties to Bitcoin with regard to 51% attacks, that functions even if no single node processes more than `1/n` of all transactions where `n` can be scaled up to be as high as necessary, although perhaps at the cost of linearly or quadratically growing secondary inefficiencies and convergence concerns. This would allow the blockchain architecture to process an arbitrarily high number of TPS but at the same time retain the same level of decentralization that Satoshi envisioned. - -**Problem**: create a blockchain design that maintains Bitcoin-like security guarantees, but where the maximum size of the most powerful node that needs to exist for the network to keep functioning is substantially sublinear in the number of transactions. - -**Additional Assumptions and Requirements**: - -* There exist a large number of miners in the network -* Miners may be using specialized hardware or unspecialized hardware. Specialized hardware should be assumed to be more powerful than unspecialized hardware by a large (eg. 10000) constant factor at specific tasks. -* Ordinary users will be using unspecialized hardware -* Ideally, after some number of blocks (perhaps logarithmic in the total size of the network) every transaction should require 51% of network hashpower to reverse. However, solutions where transactions can pay very small fees for a lower "level" of security are acceptable, though one should take care to avoid situations where an attacker can profit by performing one attack to reverse very many small transactions at the same time -* Ideally, the solution should work for and maintain as many properties as possible of a generalized account-based blockchain (eg. Ethereum), though solutions specific to currency, domain registrations or other specialized use caes are acceptable - -### 2. Timestamping - -An important property that Bitcoin needs to keep is that there should be roughly one block generated every ten minutes; if a block is generated every day, the payment system becomes too slow, and if a block is generated every second there are serious centralization and network efficiency concerns that would make the consensus system essentially nonviable even assuming the absence of any attackers. To ensure this, the Bitcoin network adjusts difficulty so that if blocks are produced too quickly it becomes harder to mine a new block, and if blocks are produced too slowly it becomes easier. - -However, this solution requires an important ingredient: the blockchain must be aware of time. In order to solve this problem, Bitcoin requires miners to submit a timestamp in each block, and nodes reject a block if the block's timestamp is either (i) behind the median timestamp of the previous eleven blocks, or (ii) more than 2 hours into the future, from the point of view of the node's own internal clock. This algorithm is good enough for Bitcoin, because time serves only the very limited function of regulating the block creation rate over the long term, but there are potential vulnerabilities in this approach, issues which may compound in blockchains where time plays a more important role. - -**Problem**: create a distributed incentive-compatible system, whether it is an overlay on top of a blockchain or its own blockchain, which maintains the current time to high accuracy. - -**Additional Assumptions and Requirements** - -* All legitimate users have clocks in a normal distribution around some "real" time with standard deviation 20 seconds. -* No two nodes are more than 20 seconds apart in terms of the amount of time it takes for a message originating from one node to reach any other node. -* The solution is allowed to rely on an existing concept of "N nodes"; this would in practice be enforced with proof-of-stake or non-sybil tokens (see #9). -* The system should continuously provide a time which is within 120s (or less if possible) of the internal clock of >99% of honestly participating nodes. Note that this also implies that the system should be self-consistent to within about 190s. -* The system should exist without relying on any kind of proof-of-work. -* External systems may end up relying on this system; hence, it should remain secure against attackers controlling < 25% of nodes regardless of incentives. - -### 3. Arbitrary Proof of Computation - -Perhaps the holy grail of the study zero-knowledge proofs is the concept of an arbitrary proof of computation: given a program P with input I, the challenge is to create a zero-knowledge proof that you ran P with input I and received output O, such that the proof can be verified quickly (ie. in polylogarithmic or ideally constant time) even if the original computation took a very large number of steps to complete. In an ideal setup, the proof would even hide the value of I, just proving that you ran P with some output with result O, and if I needs to be made public it can be embedded into the program. Such a primitive, if possible, would have massive implications for cryptocurrency: - -1. The blockchain scalability problem would be much easier to solve. Instead of miners publishing blocks containing a list of transactions, they would be publishing a proof that they ran the blockchain state updater with some list of transactions and produced a certain output; thus, instead of transactions needing to be verified by every node in the network, they could be processed by one miner and then every other miner and user could quickly verify the proof of computation and if the proof turns out correct they would accept the new state. This is not a complete solution, because there would still be a need to transmit data, but the problem would be much easier with this powerful building block. -2. The blockchain privacy problem would be much easier to solve. The blockchain scalability solution above would hide the details behind individual transactions; it would only reveal the fact that all of them are legitimate, so transactions would be hidden from everyone but the sender and the receiver. -3. It would become computationally viable to use a Turing-complete consensus network as a generic distributed cloud computing system; if you have any computation you wanted done, you would be able to publish the program for miners and miners would be able to run the program for you and deliver the result alongside a proof of its validity. - -There is a large amount of existing research on this topic, including a protocol known as "SCIP" (Succinct Computational Integrity and Privacy) that is already working in test environments, although with the limitation that a trusted third party is required to initially set up the keys; use of this prior work by both its original developers and others is encouraged. - -**Problem**: create programs `POC_PROVE(P,I) -> (O,Q)` and `POC_VERIFY(P,O,Q) -> { 0, 1 }` such that `POC_PROVE` runs program `P` on input `I` and returns the program output `O` and a proof-of-computation `Q` and `POC_VERIFY` takes `P`, `O` and `Q` and outputs whether or not `Q` and `O` were legitimately produced by the `POC_PROVE` algorithm using `P`. - -**Requirements And Additional Assumptions** - -* The runtime of `POC_PROVE` should be in `O(n*polylog(n))` where `n` is the number of steps required to run the program. -* The runtime of `POC_VERIFY` should be either constant or logarithmic in the number of steps, and at most linear in the maximum memory usage of the program. -* The protocol should require no trusted third parties. If TTPs are required, the protocol should include a mechanism for simulating one efficiently using secure multiparty computation. - -### 4. Code Obfuscation - -For many years now we have known how to encrypt data. Simple, robust and well-tested algorithms exist for both symmetric key encryption, where the same key is needed to encrypt and decrypt, and public key encryption, where the encryption key and decryption key are different and one cannot be derived from the other. However, there is another kind of encryption that can potentially be very useful, but for which we currently have no viable algorithm: the encryption of programs. The holy grail is to create an obfuscator `O`, such that given any program P the obfuscator can produce a second program `O(P) = Q` such that `P` and `Q` return the same output if given the same input and, importantly, `Q` reveals no information whatsoever about the internals of `P`. One can hide inside of `Q` a password, a secret encryption key, or one can simply use `Q` to hide the proprietary workings of the algorithm itself. - -In 2007, it was proven that perfect "black box" encryption is impossible; essentially, the argument is that there is a difference between having black-box access to a program and having the code to that program, no matter how obfuscated, and one can construct certain classes of programs that resist obfuscation. However, there is also a weaker notion of obfuscation, known as indistinguishability obfuscation, that appears to be quite possible. The definition of an indistinguishability obfuscator `O` is that if you take two equivalent (ie. same inputs -> same outputs) programs `A` and `B` and calculate `O(A) = P` and `O(B) = Q`, then there is no computationally feasible way for an outsider without access to `A` or `B` to tell whether `P` came from `A` or `B`. - -This type of obfuscation may seem more limited, but it is nevertheless sufficient for many applications. For a heuristic argument why, consider two programs `F` and `G` where `F` internally contains and simply prints out that 32-byte string which is the hash of "12345", whereas G actually computes the hash of "12345" and prints it out. By the indistinguishability obfuscation definition, there is no computationally feasible way to tell `O(F)` from `O(G)` apart. Hence, if one can feasibly recover "12345" from `O(G)`, then for `O(G)` and `O(F)` to be indistinguishable one would also need to be able to feasibly recover "12345" from `O(F)` - a feat which essentially entails breaking the preimage resistance of a cryptographic hash function. - -Recently, a discovery was made by Craig Gentry, Amit Sahai et al on an algorithm which uses a construction known as "multilinear jugsaw puzzles" in order to accomplish this. Their algorithm, described here, claims to satisfy the indistinguishability obfuscation property, although at a high cost: the algorithm requires the use of fully homomorphic encryption, a highly inefficient construction that incurs roughly a one-billion-fold computational overhead. - -If this construction can be made better, the potential benefits are massive. The most interesting possibility in the world of cryptocurrency is the idea of an on-blockchain contract containing private information. This basically allows for the scripting properties of Turing-complete blockchain technologies, such as Ethereum, to be exported into any other financial or non-financial system on the internet; for example, one can imagine an Ethereum contract which contains a user's online banking password, and if certain conditions of the contract are satisfied the contract would initiate an HTTPS session with the bank, using some node as an intermediary, and log into the bank account with the user's password and make a specified withdrawal. Because the contract would be obfuscated, there would be no way for the intermediary node, or any other player in the blockchain, to modify the request in-transit or determine the user's password. The same trick can be done with any other website, or much more easily with a "dumb" blockchain such as Bitcoin. - -**Problem**: create a reasonably efficient indistinguishability obfuscation algorithm. - -**Additional Assumptions and Requirements** - -* Successful attacks must have an expected runtime above 2^80 -* The algorithm should be sufficiently fast that a standard ECDSA signature or an AES encryption should be feasible within 108 computational steps (more specifically, 108 gas in the Ethereum VM) - -### 5. Hash-Based Cryptography - -One of the looming threats on the horizon to cryptocurrency, and cryptography in general, is the issue of quantum computers. Currently, the problem does not seem too severe; all quantum computers are either "adiabatic quantum computers", effective at only an extremely limited set of problems and perhaps not even better than classical computers at all, or machines with a very small number of qubits not capable of factoring numbers higher than 35. In the future, however, quantum computers may become much more powerful, and the recent revelations around the activities of government agencies such as the NSA have sparked fears, however unlikely, that the US military may control a quantum computer already. With this in mind, the movement toward quantum-proof cryptography has become a somewhat higher priority. - -To date, all quantum-proof schemes fall into one of two categories. First, there are algorithms involving lattice-based constructions, relying on the hardness of the problem of finding a linear combination of vectors whose sum is much shorter than the length of any individual member. These algorithms appear to be powerful, and relatively efficient, but many distrust them because they rely on complicated mathematical objects and relatively unproven assumptions. However, there is also another class of algorithms that are quantum-proof: hash-based algorithms. One example of this is the classic Lamport signature: create a Merkle tree of 164 nodes (a figure chosen specifically to match 160 bits of security), publish the root, and then have the signature of a document be the combined Merkle tree proof of a subset of 82 nodes pseudorandomly chosen based on the hash of the document. This signature is one-time, and bulky (~3000 bytes), but fulfils the purpose. - -The question is, can we do better? There is an approach known as hash ladders, allowing the size of a signature to be brought down to 420 bytes, and one can use Merkle trees on another level to increase the number of signatures possible, although at the cost of adding 100-300 bytes to the signature. However, even still these approaches are imperfect, and if hash-based cryptography is to be competitive the properties of the algorithms will need to be substantially improved in order to have nicer properties. - -**Problem**: create a signature algorithm relying on no security assumption but the random oracle property of hashes that maintains 160 bits of security against classical computers (ie. 80 vs. quantum due to Grover's algorithm) with optimal size and other properties. - -**Requirements And Additional Assumptions** - -* The computational effort of producing a signature should be less than 224 computational steps, assuming a hash takes 28 steps (a reasonable assumption due to hardware optimizations and in the future hashing ASICs built into chips) -* The size of a signature should be as small as possible -* The size of a public key should be as small as possible -* The signature algorithm should be scalable to add any number of uses, although likely at the cost of adding a constant number of bytes per signature for every 2x increase in the maximum number of uses, and if possible the setup time should be sublinear in the number of uses. - -## Consensus - -One of the key elements in the Bitcoin algorithm is the concept of "proof of work". In any Byzantine-fault-tolerant system, the security level is often defined as the minimum percentage of hostile nodes - for example, in the context of secret sharing, the Berlekamp-Welch algorithm with 2x redundancy is guaranteed to provide the correct output assuming that the total number of hostile nodes does not exceed 25% of the network, and in the context of Bitcoin mining the requirement is that the size of the set of honest nodes exceeds the size of any individual hostile coalition. However, all of these security guarantees have one important qualification: there must be some way to define what an individual node is. Before Bitcoin, most fault-tolerant algorithms had high computational complexity and assumed that the size of the network would be small, and so each node would be run by a known individual or organization and so it is possible to count each node individually. - -With Bitcoin, however, nodes are numerous, mostly anonymous, and can enter or leave the system at any time. Unless one puts in careful thought, such a system would quickly run into what is known as a Sybil attack, where a hostile attacks simply creates five times as many nodes as the rest of the network combined, whether by running them all on the same machine or rented virtual private server or on a botnet, and uses this supermajority to subvert the network. In order to prevent this kind of attack, the only known solution is to use a resource-based counting mechanism. For this purpose, Bitcoin uses a scheme known as proof-of-work, which consists of solving problems that are difficult to solve, but easy to verify. The weight of a node in the consensus is based on the number of problem solutions that the node presents, and the Bitcoin system rewards nodes that present such solutions ("miners") with new bitcoins and transaction fees. - -Bitcoin's proof of work algorithm is a simple design known as Hashcash, invented by Adam Back in 1995. The hashcash function works as follows: - - def hashcash_produce(data, difficulty): - nonce = random.randrange(2**256) - while sha256(data + str(nonce)) > 2**256 / difficulty: - nonce += 1 - return nonce - - def hashcash_verify(data, nonce, difficulty): - return sha256(data + str(nonce)) <= 2**256 / difficulty - -Note that in the actual Bitcoin protocol nonces are limited to 32 bits; at higher difficulty levels, one is required to also manipulate transaction data in the block as a sort of "extranonce". - -Originally, the intent behind the Bitcoin design was very egalitarian in nature. Every individual would mine on their own desktop computer, producing a highly decentralized network without any point of control and a distribution mechanism that spread the initial supply a BTC across a wide number of users. And for the first 18 months of Bitcoin's existence, the system worked. In the summer of 2010, however, developers released a Bitcoin miner that took advantage of the massive parallelization offered by the graphics processing unit (GPU) of powerful computers, mining about 10-50 times more efficiently than CPUs. In 2013, specialization took a further turn, with the introduction of devices called "application-specific integrated circuits" - chips designed in silicon with the sole purpose of Bitcoin mining in mind, providing another 10-50x rise in efficiency. CPU and GPU mining are now completely unprofitable, and the only way to mine is to either start a multimillion-dollar ASIC manufacturing company or purchase an ASIC from one that already exists. - -Another related issue is mining pool centralization. Theoretically, the legitimate function of a mining pool is simple: instead of mining on their own and receiving a small chance of earning the block reward of 25 BTC, miners mine for a pool, and the pool sends them a proportionate constant payout (eg. 0.002 BTC per block). There are centralized mining pools, but there are also P2P pools which serve the same function. However, P2P pools require miners to validate the entire blockchain, something which general-purpose computers can easily do but ASICs are not capable of; as a result, ASIC miners nearly all opt for centralized mining pools. The result of these trends is grim. Right now, nearly 25% of all new ASIC hashpower is produced in a single factory in Shenzhen, and nearly 50% of the network is controlled by a single mining pool. - -The second problem is easy to alleviate; one simply creates a mining algorithm that forces every mining node to store the entire blockchain. The first problem, that of mining centralization, is much harder. There is the possibility that the problem will solve itself over time, and as the Bitcoin mining industry grows it will naturally become more decentralized as room emerges for more firms to participate. However, that is an empirical claim that may or may not come to pass, and we need to be prepared for the eventuality that it does not. Furthermore, the wasted energy and computation costs of proof of work as they stand today may prove to be entirely avoidable, and it is worth looking to see if that aspect of consensus algorithms can be alleviated. - -### 6. ASIC-Resistant Proof of Work - -One approach at solving the problem is creating a proof-of-work algorithm based on a type of computation that is very difficult to specialize. One specific ideas involves creating a hash function that is "memory-hard", making it much more difficult to create an ASIC that achieves massive gains through parallelization. This idea is simple, but fundamentally limited - if a function is memory-hard to compute, it is also generally memory-hard to verify. Additionally, there may be ways to specialize hardware for an algorithm that have nothing to do with hyperparallelizing it. Another approach involves randomly generating new mining functions per block, trying to make specialization gains impossible because the ASIC ideally suited for performing arbitrary computations is by definition simply a CPU. There may also be other strategies aside from these two. - -Ultimately, perfect ASIC resistance is impossible; there are always portions of circuits that are going to be unused by any specific algorithm and that can be trimmed to cut costs in a specialized device. However, what we are looking for is not perfect ASIC resistance but rather economic ASIC resistance. Economic ASIC resistance can be defined as follows. First of all, we note that in a non-specialized environment mining returns are sublinear - everyone owns one computer, say with N units of unused computational power, so up to N units of mining cost only the additional electricity cost, whereas mining beyond N units costs both electricity and hardware. If the cost of mining with specialized hardware, including the cost of research and development, is higher per unit hashpower than the cost of those first N units of mining per user then one can call an algorithm economically ASIC resistant. - -For a more in-depth discussion on ASIC-resistant hardware, see [https://blog.ethereum.org/2014/06/19/mining/](https://blog.ethereum.org/2014/06/19/mining/) - -**Problem**: Create two functions, `PoWProduce(data,diff) -> nonce` and `PoWVerify(data,nonce,diff) -> { 0, 1 }`, to serve as alternatives to Hashcash such that it is economically unattractive to produce an ASIC for `PoWProduce` - -**Additional Assumptions And Requirements**: - -* `PoWProduce` must have expected runtime linear in `diff` -* `PoWVerify` must have runtime at most polylogarithmic in `diff` -* Running `PoWProduce` should be the most efficient, or very close to the most efficient, way to produce values that return `1` when checked with `PoWVerify` (ie. no software optimization) -* `PoWProduce` must not be superlinear in computational power or time; that is to say, the expected number of successful `PoWProduce` computations for a node with `N` dollars worth of hardware after `t` seconds should be bounded by `kNt` for some `k`. Furthermore, the linearity should kick in quickly; ie. $1000 worth of mining hardware should function with over 90% efficiency. -* It should be shown with reasonably rigorous technological and economic analysis that the algorithm is economically ASIC resistant. - -### 7. Useful Proof of Work - -Another related economic issue, often pointed out by detractors of Bitcoin, is that the proof of work done in the Bitcoin network is essentially wasted effort. Miners spend 24 hours a day cranking out SHA256 (or in more advanced implementations Scrypt) computations with the hopes of producing a block that has a very low hash value, and ultimately all of this work has no value to society. Traditional centralized networks, like Paypal and the credit card network, manage to get by without performing any proof of work computations at all, whereas in the Bitcoin ecosystem about a million US dollars of electricity and manufacturing effort is essentially wasted every day to prop up the network. - -One way of solving the problem that many have proposed is making the proof of work function something which is simultaneously useful; a common candidate is something like Folding@home, an existing program where users can download software onto their computers to simulate protein folding and provide researchers with a large supply of data to help them cure diseases. The problem is, however, that Folding@home is not "easy to verify"; verifying the someone did a Folding@home computation correctly, and did not cut corners to maximize their rounds-per-second at the cost of making the result useless in actual research, takes as long as doing the computation oneself. If either an efficiently verifiable proof-of-computation for Folding@home can be produced, or if we can find some other useful computation which is easy to verify, then cryptocurrency mining could actually become a huge boon to society, not only removing the objection that Bitcoin wastes "energy", but even being socially beneficial by providing a public good. - -Note that there is one major concern with this approach that has been identified: if the useful PoW is implemented incorrectly, it can potentially reduce the cost of an attack on the network. If the useful PoW is useful in such a way that it is sometimes economically viable for certain very large entities to perform the computation even without the currency incentive, then those entities have an incentive to launch attacks against the network at no cost, since they would be performing the computations anyway. One simple, though crude and imperfect, way of addressing this problem is to make the PoW a half-and-half mix between useful and useless, making the cost of an attack at least 50% of what it would be in a useless-PoW environemnt. In practice, the overhead of making PoW verifiable may well introduce over 2x inefficiency unintentionally. Another economic solution is to make the computation a "pure" public good such that no individual entity derives a significant benefit from it. Proposed solutions to this problem should include a rigorous analysis of this issue. - -**Problem**: Create two functions, `PoWProduce(data,diff) -> nonce` and `PoWVerify(data,nonce,diff) -> { 0, 1 }`, to serve as alternatives to Hashcash such that the outputs of `PoWProduce` are independently useful. - -**Requirements** - -* `PoWProduce` must have expected runtime linear in `diff` -* `PoWVerify` must have expected runtime at most polylogarithmic in `diff` -* Running `PoWProduce` should be the most efficient way to produce values that return `1` when checked with `PoWVerify` -* `PoWProduce` must not be superlinear in computational power or time; that is to say, the expected number of successful `PoWProduce` computations for a node with `N` dollars worth of hardware after `t` seconds should be bounded by `kNt` for some `k`. Furthermore, the linearity should kick in quickly; ie. $1000 worth of mining hardware should function with over 90% efficiency. -* `PoWProduce` must produce a public good, such that the total value to everyone of the public good produced is greater than the cost of all resources invested into the mining process. -* The system must be able to exist without a trusted third party, but it is reasonable to allow a trusted third party to serve as a data source for useful computations. If the trusted third party acts maliciously in any way, the public good may be negated but the blockchain mining should not be compromised. - -### 8. Proof of Stake - -Another approach to solving the mining centralization problem is to abolish mining entirely, and move to some other mechanism for counting the weight of each node in the consensus. The most popular alternative under discussion to date is "proof of stake" - that is to say, instead of treating the consensus model as "one unit of CPU power, one vote" it becomes "one currency unit, one vote". - -A very simple proof of stake algorithm requires the miner mining the block to sign it with the private key to the address holding their coins, where the block is valid if `sha256(PREVHASH + ADDRESS + TIMESTAMP) <= 2^256 * BALANCE / DIFFICULTY` where `PREVHASH` is the hash of the previous block, `ADDRESS` is the signer's address with balance `BALANCE`, `TIMESTAMP` is the current Unix time in seconds and `DIFFICULTY` is an adjustable parameter to regulate the frequency of successful signatures. At first glance, this algorithm has the basic required properties: every miner has some random chance per second of succeeding, and if your address has twice as much money in it then you have double the chance of success. - -However, this algorithm has one important flaw: there is "nothing at stake". In the event of a fork, whether the fork is accidental or a malicious attempt to rewrite history and reverse a transaction, the optimal strategy for any miner is to mine on every chain, so that the miner gets their reward no matter which fork wins. Thus, assuming a large number of economically interested miners, an attacker may be able to send a transaction in exchange for some digital good (usually another cryptocurrency), receive the good, then start a fork of the blockchain from one block behind the transaction and send the money to themselves instead, and even with 1% of the total stake the attacker's fork would win because everyone else is mining on both. - -Another problem to keep in mind is the issue of so-called "long-range attacks" - attacks where the miner attempts to start a fork not five or ten blocks behind the head of the main chain, as happens normally, but hundreds of thousands of blocks back. If an algorithm is designed incorrectly, it may be possible for an attacker to start from that far back, and then mine billions of blocks into the future (since no proof of work is required), and new users would not be able to tell that the blockchain with billions of blocks more is illegitimate. This can generally be solved with timestamping, but special corner cases do tend to appear in overcomplicated designs. - -The Slasher algorithm, described [here](http://blog.ethereum.org/2014/01/15/slasher-a-punitive-proof-of-stake-algorithm/) and implemented by Zack Hess as a proof-of-concept [here](https://github.com/zack-bitcoin/slasher), represents my own attempt at fixing the nothing-at-stake problem. The core idea is that (1) the miners for each block are determined ahead of time, so in the event of a fork a miner will either have an opportunity to mine a given block on all chains or no chains, and (2) if a miner is caught signing two distinct blocks with the same block number they can be deprived of their reward. The algorithm is viable and effective, but it suffers from two flaws of unknown significance. First, if all of the miners for a given block learn each other's identities beforehand, they can meet up and collude to shut down the network. Second, the nothing-at-stake problem remaing for attacks going back more than 3000 blocks, although this is a smaller issue because such attacks would be very obvious and can automatically trigger warnings. - -For a more in-depth discussion on proof of stake, see [https://blog.ethereum.org/2014/07/05/stake/](https://blog.ethereum.org/2014/07/05/stake/) - -**Problem**: create a proof-of-stake algorithm that solves the nothing-at-stake problem and long-range attack problems, without introducing new collusion risks that require less than 25% of stakeholders to succeed. - -**Additional Requirements And Assumptions** - -* The expected return from mining should be bounded by `k` times the miner's stake for some `k`, and assuming $1 billion total participating stake a stake of $1000 should be able to reach 90% of this maximum efficiency. -* The algorithm should be fully incentive-compatible, addressing the double-voting issue defined above and the collusion issue defined above at both short and long range. - -### 9. Proof of Storage - -A third approach to the problem is to use a scarce computational resource other than computational power or currency. In this regard, the two main alternatives that have been proposed are storage and bandwidth. There is no way in principle to provide an after-the-fact cryptographic proof that bandwidth was given or used, so proof of bandwidth should most accurately be considered a subset of social proof, discussed in later problems, but proof of storage is something that certainly can be done computationally. An advantage of proof-of-storage is that it is completely ASIC-resistant; the kind of storage that we have in hard drives is already close to optimal. - -The most simple algorithm for proving that you own a file with `N` blocks is to build a Merkle tree out of it, publish the root, and every `k` blocks publish a Merkle tree proof of the `i`th block where `i` is the previous block hash mod `N`. However, this algorithm is limited because it is only a simple building block, not a complete solution. In order to turn this into a currency, one would need to determine which files are being stored, who stores whose files, to what extent and how the system should enforce redundancy, and if the files come from the users themselves how to prevent compression optimizations and long-range attacks. - -Currently, the latest work in this area are two projects called Permacoin and Torcoin, which solve some of the problems in proof of storage with two insights. First, users should not be able to choose which files they store. Instead, files should be randomly selected based on their public key and users should be required to store ALL of the work assigned or else face a zero reward. This idea, provided in the context of proof of bandwidth in the case of Torcoin, prevents attacks involving users only storing their own data. Second, a Lamport-like signature algorithm can be used that requires users to have their private key and store their file locally; as a result; uploading all of one's files to the cloud is no longer a viable strategy. This, to some degree, forces redundancy. - -However, the problem with Permacoin is that it leaves unclear what files should be stored; cryptocurrency issuance can theoretically pay for billions of dollars of work per year, but there is no single static archive whose storage is worth billions. Ideally, the system would allow for new files to be added, and perhaps even allow users to upload their own files, but without introducing new vulnerabilities. - -**Problem**: create a currency that uses proof-of-storage as its consensus and distribution algorithm. - -**Additional Assumptions And Requirements** - -* The currency must be future-proof, being able to expand the amount of data stored over time; the system should not eventually fall into some failure state if hard disk space continues to get cheaper and more efficient. -* The currency should ideally be maximally useful. At the least, the currency should allow people to upload their own files and have them stored, providing an uploading network with minimal cryptographic overhead, although ideally the currency should select for files that are public goods, providing net total value to society in excess of the number of currency units issued. -* The expected return from mining should be at most slightly superlinear, ie. it must be bounded by `ks/(1-s)` for some `k`, where `s` is the miner's share of the total network, although perfect linearity is ideal. -* The system should be maximally resistant against mining pool centralization as a result of any small degree of superlinearity. -* The system should be secure against nothing-at-stake and long-range attacks. -* The system should be secure against attacker involving users uploading specially formatted files or storing their own data. - -## Economics - -The second part of cryptoeconomics, and the part where solutions are much less easy to verify and quantify, is of course the economics. Cryptocurrencies are not just cryptographic systems, they are also economic systems, and both kinds of security need to be taken into account. Sometimes, cryptographic security may even be slightly compromised in favor of an economic approach - if a signature algorithm takes more effort to crack than one could gain from cracking it, that is often a reasonable substitute for true security. At the same time, economic problems are also much more difficult to define. One cannot usually definitively know whether or not a problem has been solved without extensive experimentation, and the result will often depend on cultural factors or the other organizational and social structures used by the individuals involved. However, if the economic problems can be solved, the solutions may often have reach far beyond just cryptocurrency. - -### 10. Stable-value cryptoassets - -One of the main problems with Bitcoin is the issue of price volatility. The value of a bitcoin often experiences very large fluctuations, rising or falling by as much as 25% in a single day and 3x in a month. The main economic reason behind this is that the supply of bitcoins is fixed, so its price is directly proportional to demand (and therefore, by efficient market hypothesis, the expected discounted future demand), and demand is very unpredictable. It is not known if Bitcoin will be simply a niche payment method for transcations requiring a high degree of privacy, a replacement for Western Union, a mainstream consumer payment system or the reserve currency of the world, and the expected value of a bitcoin differs over a thousandfold between these various levels of adoption. Furthermore, the utility of the Bitcoin protocol is heavily dependent on the movements of the Bitcoin price (ie. people are interested in Bitcoin more if the price is going up), creating a positive feedback loop, which has arguably been responsible for both Bitcoin's great meteoric rises and its many-month-long periods of rapid decline. - -To solve this problem, there are generally two paths that can be taken. The first is to have the network somehow detect its current level of economic usage, and have a supply function that automatically increases supply when usage increases. This reduces uncertainty; even though the expected future level of adoption of the protocol may have a variance of 10-100x, the circumstance where adoption increases 100x will also have 100x more supply and so the value of the currency will remain the same. There is a problem that if usage decreases there is no way to remove units from circulation, but even still the lack of upward uncertainty should reduce upward volatility, and downward volatility would also naturally reduce because it is no longer bad news for the value of the currency when an opportunity for increased usage is suddenly removed. Furthermore, in the long term the economy can be expected to grow, so the zero-supply-growth floor may not even ever be reached in practice. - -The problem is that measuring an economy in a secure way is a difficult problem. The most obvious metric that the system has access to is mining difficulty, but mining difficulty also goes up with Moore's law and in the short term with ASIC development, and there is no known way to estimate the impact of Moore's law alone and so the currency cannot know if its difficulty increased by 10x due to better hardware, a larger user volume or a combination of both. Other metrics, such as transaction count, are potentially gameable by entities that want the supply to change in a particular direction (generally, holders want a lower supply, miners want a higher supply). - -Another approach is to attempt to create a currency which tracks a specific asset, using some kind of incentive-compatible scheme likely based on the game-theoretic concept of Schelling points, to feed price information about the asset into the system in a decentralized way. This could then be combined with a supply function mechanism as above, or it can be incorporated into a zero-total-supply currency system which uses debts collateralized with other cryptographic assets to offset its positive supply and thus gain the ability to grow and shrink with changes to usage in either direction. The problem here is constructing the scheme in such a way that there is no incentive for entities to feed in false price information in order to increase or decrease the supply of the asset in their favor. - -**Problem**: construct a cryptographic asset with a stable price. - -**Requirements** - -* The expected root-mean-square daily change in the logarithm of the price of the asset should be less than 25% of that of Bitcoin under similar conditions. Ideally, the asset should be guaranteed to almost always maintain a value within 10% of an arbitrary cryptographic or real-world asset for which price information is easily accessible -* The expectation analysis should take into account black swan risks (ie. systems where the variance is 0% 99% of the time but 10x in a day the other 1% of the time are unacceptable) -* The solution must come with a model, including parameters such as short-term-consumption purchases, medium-term purchases, speculative purchases, positive and negative media, adoption and regulatory events, irrational actors and actors with political motives, show that their model well fits the history of Bitcoin and potentially major altcoins without overfitting, and show that under the model the other two requirements hold -* Zero-total-supply assets, ie. assets where each unit is balanced by a collateralized debt of a unit, are allowed, although such systems must include a robust margin-calling mechanism because it is assumed that most users are anonymous and can therefore trivially run away from debts - -### 11. Decentralized Public Goods Incentivization - -One of the challenges in economic systems in general is the problem of "public goods". For example, suppose that there is a scientific research project which will cost $1 million to complete, and it is known that if it is completed the resulting research will save one million people $5 each. In total, the social benefit is clear: if everyone contributes $1, then each individual person will see a benefit of $5 - $1 = $4 for $4 million total. However, the problem is that from the point of view of each individual person contributing does not make sense - whether or not you contribute has close to zero bearing on whether enough money will be collected, so everyone has the incentive to sit out and let everyone else throw their money in, with the result that no one does. - -So far, most problems to public goods have involved centralization; some large organization, whether a big company or a government, agrees to offer some of its private services only to those individuals who participate in paying for the public good. Often this is done implicitly: for example, some of the money from each purchase of an iPad goes toward research and development (some of which is a public good, and some of which is an excludable "club good"). At other times, it's more explicit, as in the case of taxation. In order for decentralized economic systems (we'll refer to decentralized economic systems that somehow rely on cryptography and/or cryptocurrency as "cryptoeconomic systems") to be effective, ways of incentivizing production of public goods relevant to that system are required. A few possible approaches include: - -* **Assurance contracts** - the idea behind an assurance contract is that `N` people may or may not put their funds into a pool, where that pool pays to produce a public good if and only if at least $X in total is contributed. Otherwise, the pool pays everyone back. If the pool creator acts optimally, the tipping point will be right at the top of the bell curve that is the probability distribution for how much other people might contribute, meaning that the chance that one user with their contribution of `X/N` will be pivotal should, by central limit theorem, approach `~1/sqrt(N)`, creating a `sqrt(N)`-sized amplifying effect on their donation. -* **Dominant assurance contracts** - a special type of assurance contract, called a dominant assurance contract, involves an entrepreneur that pays all contributors back slightly more than 100% of what they put in if the fund fails to reach its target (and takes profits if the fund succeeds); this provides an incentive for someone to create optimally targeted assurance contracts. -* **Currency issuance** - a cryptoeconomic system can contain its own currency or token system which is somehow necessary or useful in some part of the system. These currency units can then either be generated by the system and then sold or directly assigned to reward contribution. This approach gets around the free-rider problem because no one needs to pay the $1 explicitly; the value arises out of the emergent value of the network which is does not cost people to support. -* **Status goods issuance** - a status good can be defined as a good that confers only relative benefit to its holder and not absolute benefit to society; for example, you may stand out in the public if you wear an expensive diamond necklace, but if everyone could trivially obtain such a necklace the situation would be very similar to a world with no diamond necklaces at all. A cryptoeconomic system can release its own status goods, and then sell or award them. One example of a status good is a "badge"; some online forums, for example, show a special badge beside users that have contributed funds to support the forum's development and maintenance. Another important example of a status good is a namespace; for example, a decentralized messaging protocol may be able to fund itself by selling off all of the 1-4 letter usernames. -* **Recursive rewarding** - this is in some ways a mirror image of the concept of "recursive punishment" that arguably underlies a large number of social protocols. For example, consider the case of tax-funded police forces. In natural circumstances, there often arise opportunities to take actions which are beneficial to the perpetrator, but ultimately harmful to society as a whole (eg. theft). The most common solution to this problem is punishment - an act which is harmful in itself, but which shifts the incentives so that attacking is no longer beneficial to the perpetrator. However, there is a problem: there is no incentive to participate in the punishment process. This is solved by making punishment obligatory, with non-participation (in modern society by paying taxes) itself punishable by the same mechanism. Recursive rewarding is a mirror image of this strategy: here, we reward a desirable action, and people who partivipate in the rewarding mechanism (eg. by giving reward recipients a discount in shops) are themselves to be rewarded. - -Many of these approached can arguably be done in concert, or even simultaneously within one mechanism. - -**Problem**: come up with and implement methods for incentivizing public goods production in a decentralized environment. - -**Additional Assumptions And Requirements** - -* A fully trustworthy oracle exists for determining whether or not a certain public good task has been completed (in reality this is false, but this is the domain of another problem) -* The agents involved can be a combination of individual humans, teams of humans, AIs, simple software programs and decentralized cryptographic entities -* A certain degree of cultural filtering or conditioning may be required for the mechanism to work, but this should be as small as possible -* No reliance on trusted parties or centralized parties should be required. Where some kind of "supernode" role does exist, the protocol should provide a way for anyone to participate in that function with a mechanism for rewarding those who do it well -* The mechanism should ideally be able to handle both public goods which everyone values and public goods which are only valued by a small portion of the population (eg. the production of a freely available book or video on a specific topic) - -### 12. Reputation systems - -A concept which can arguably be considered to be a mirror image of currency is a reputation system. A reputation system serves three functions. First of all, it provides a mechanism for filtering honest people from dishonest people. Different people have different moral preference profiles, and so individuals who cheat less in one context are less likely to cheat in another context. Second, it provides an incentive not to cheat. If an individual can be said to possess a reputation of value `R`, and he enters a business deal where he is receiving payment `V` in exchange for a product with cost-of-production `C`, then as long as `R > C` the reputation system removes the incentive to run away with the money because doing so would sacrifice the reputation. Finally, reputation can be thought of as a kind of point system that people value intrinsically, both in a private context and as a status good in comparison with others. - -Money serves functions that are very similar. People who are willing to spend more money on something tend to want it more, creating a filtering function ensuring efficient resource consumption on the demand side. It provides an incentive not to cheat by consuming and not producing, because if you do so your remaining currency units and thus ability to consume in the future will go down. And finally, it is also very much an intrinsically valued point system; in fact, some argue that among very wealthy individuals this function of money is dominant. - -However, there are also differences. First, money is an absolute score - I have X units of currency C from the point of view of everyone in the world - but reputation is a relative measure, depending on both the owner of the reputation and the observer. I may have a high reputation in North America, a near-zero reputation in Africa, and a negative reputation among certain kinds of antitechnologist and ultranationalist groups. Second, reputation is free to give; it does not cost me anything to praise you, except potentially moral liability that I may incur if you turn out to act immorally in some way. This is in contrast with money, where adding X units to A means subtracting X units from B. - -However, up until very recently, reputation has been a very informal concept, having no concept of score and instead relying entirely on individual opinion. Because opinion is relatively easy to manipulate, this means that reputation as a concept has been highly suboptimal in its implementation, and has been quite vulnerable to informational and psychological attacks. Some specific problems are: - -1. How do we know how what the value of someone's reputation with someone else is after a particular number of interactions? A common attack on informal reputation systems is the "long con" - act honestly but passively and cheaply for a very long time, accumulate trust, and then suddenly go all out and destructively capitalize on one's reputation as much as possible. The initial dormant phase is cheap for the attacker, but ends up resulting in the attacker accumulating a disproportionately large amount of trust for the community and thereby ultimately causing much more damange than good. Overcompensate for this too much, however, and there ends up being no opportunity to gain trust. -2. How do we incorporate secondary trust? In general, when `A` is deciding whether or not to trust `B`, `A` has not had any prior dealings with `B`, and therefore has no way of knowing whether or not `B` is trustworthy. One approach is to just look at all ratings for `B`, but then we run into the issue of Sybil attacks: what if `B` creates 50000 fake users, all of whom rate each other highly, to give good ratings to him? To solve this problem, reputation systems rely on a fallback known as a web of trust: find some chain of people `P[1] ... P[k]` such that `A` trusts `P[1]`, `P[i]` trusts `P[i+1]` for all `i`, and `P[k]` trusts `B`. Under the "six degrees of separation hypothesis", any two people in the world except those completely disconnected from society have such a chain of maximum length `k = 5` (so at most six hops total). However, the question arises, if `A` has a certain rating for `P[1]` and `P[1]` has a certain rating for `B`, what should the reputation system recommend to `B`? -3. If a reputation system becomes more formalized, are there market attacks that reduce its effectiveness to simply being just another form of money? Specifically, how would a reputation system where giving reputation is free handle users multiplying their reputation with millions of "I praise you if you praise me" trades? Will such trades need to be explicitly banned, punishable by loss of reputation, or is there a better solution? -4. How do we deal with double use attacks? Specifically, suppose that `A` has a reputation with value `R = $1000`. Using this reputation, `A` has a business dealing where `P[1]` trusts her for $600. Then, she simultaneously engages in such a dealing with `P[2], P[3] ... P[10]`, each of whom individually believe that `A` will not betray them since $600 < $1000, and then runs away with $6000 taking the $1000 hit from the value of her reputation. How do we prevent such fractional reserve-like scenarios? - -**Problem**: design a formalized reputation system, including a score `rep(A,B) -> V` where `V` is the reputation of `B` from the point of view of `A`, a mechanism for determining the probability that one party can be trusted by another, and a mechanism for updating the reputation given a record of a particular open or finalized interaction. - -Note that for the purpose of this use case we are targeting specifically the "can I trust you" use case of reputation, and not the social-incentivizing "[whuffie](https://en.wikipedia.org/wiki/Whuffie)"-esque currency-like aspect. - -**Additional Assumptions and Requirements** - -* The system has access to a record of all finalized transactions inside the system and all transactions in progress, although entities are of course able to choose to make deals outside the system -* It is allowed to introduce mechanisms like charity donations, public goods provision and sacrifices as a way of increasing one's reputation. However, if non-monetary contributions are allowed, there needs to be some mechanism for measuring their value -* For simplicity, we can assume that interactions between two people are of the form "A pays, then B sends the product and A receives", with no possibility for loss beyond the principal (eg. food poisoning) or ambiguous quality. Ideally, however, the system should account for such possibilities. -* The system should continue to be reasonably accurate whether the parties involved are simple programs (eg. micropayment software protocols), more complicated AIs, DAOs, individual humans or human centralized or decentralized organizations -* If a mechanism is provided for determining the probability of a successful interaction, a success metric for the system can be defined as the sum over all transactions of `V * (S * log(p) - (1-S) * log(1-p))`, where `S = 1` if the transaction succeeded and `S = 0` if there was a registered complaint, `p` is the assigned probability and `V` is the value of the transaction. The objective is to maximize this metric. - -## Metrics - -In the world of cryptoeconomics, in order for something to be rewarded it must be measured. Some things are easy to measure; for example, just by looking at the string "dog5356356" and its SHA256 hash, `0000390f327fefc900...`, one can clearly see that around 216 SHA256 computations were done to produce it. Other computational results that cannot be verified so quickly can be easily measured competitively using challenge-response protocols, where different parties are incentivized to find errors in each other's proofs. Results to mathematical problems are also usually easy to computationally verify. Other things, however, cannot be verified just by looking them; in that case, in both the real world and the cryptographic world, there is only one solution: social proof. - -To some extent, proof of work consensus is itself a form of social proof. Transaction A happened before transaction B because the majority of users say it did, and there is an economic incentive to go with the majority opinion (specifically, if you generate a block on the incorrect chain, that block will get discarded and the miner will receive no reward). Assuming that most participants act truthfully, the incentive is to go along with the projected majority and tell the truth as well. This insight can be extended into [SchellingCoin](http://blog.ethereum.org/2014/03/28/schellingcoin-a-minimal-trust-universal-data-feed/), a generalized data feed protocol, protocols for proof of bandwidth, and anything else that can be quickly verified. The challenge is, however, what if verification has a cost? What if it takes some effort to determine whether or not a certain thing has happened, or what if the information is in principle only available to a few people? If there is too much gathering cost or secrecy, then centralization becomes necessary; the question is, how high can we go? How much can we measure without any social proof at all, and how much can we measure without a centralized verifier? - -### 13. Proof of excellence - -One interesting, and largely unexplored, solution to the problem of distribution specifically (there are reasons why it cannot be so easily used for mining) is using tasks that are socially useful but require original human-driven creative effort and talent. For example, one can come up with a "proof of proof" currency that rewards players for coming up with mathematical proofs of certain theorems. There is no generic algorithm, aside from brute force, for proving theorems, and yet proofs of theorems are theoretically computationally easy to verify: one simply needs to write every step of the proof in a formal language, allowing the use of only one inference rule (eg. `a + b = b + a` or `a * (b + c) = a * b + a * c` but not `a * (b + c) = a * c + b * a`) between each step, and having a program verify the correctness of the inferences at each step. - -For example, a proof of a common algebraic factorization problem appears as follows: - - a^2 - b^2 - = a^2 - a*b + a*b - b^2 - = a*a - a*b + a*b - b^2 - = a*(a - b) + a*b - b^2 - = a*(a - b) + a*b - b*b - = a*(a - b) + b*a - b*b - = a*(a - b) + b*(a - b) - = (a + b)*(a - b) - -Each step of the proof can be verified using pattern matching algorithms, but it is much harder for a computer to figure out that the trick is to add and subtract `a*b` into the expression (technically, in this case specialized algorithms can do it, but in more general cases especially involving second-order logic it becomes intractable). Note that for computers the proof must be written down in excruciating detail; blockchain-based algorithms specifically heavily benefit from simplicity. To alleviate this problem, compilers can likely be made that can make small two and three-step inferences and expand shorter proofs into more complete ones. - -Alternatives to proof-of-proof include proof-of-optimization, finding optimal inputs to some function to maximize a particular output (eg. the ability of a radio antenna to receive signals), algorithms involving playing strategy games or multiplayer AI challenges (one can even require users to submit programs to the blockchain that play against each other), and solving a specific math problem at greater and greater difficulty (eg. factoring). Note that because success in these problems is very sporadic, and highly inegalitarian, one cannot use most of these algorithms for consensus; rather, it makes sense to focus on distribution. - -**Problem**: create a proof-of-excellence distribution mechanism that rewards solving problems that are both dominated by human effort and whose solutions provide some benefit to humanity. - -**Additional Assumptions and Requirements** - -* Given a well-justified extrapolation of the global levels of human and computer competence at the underlying problem, over 75% of the rewards from the system should be provided by human labor, although software aids are allowed. -* The algorithm must ideally be future-proof; that is to say, it must continue rewarding value production in the long term and should not be an area that will eventually be "solved" completely. -* The distribution should be maximally egalitarian, though this is a secondary concern. -* The system should be secure against front-running attacks, ie. if an individual submits a solution, then it should not be practical for even a moderately powerful attacker to look at the solution and then resubmit his own transaction containing the same solution and thereby steal the reward. - -### 14. Anti-Sybil systems - -A problem that is somewhat related to the issue of a reputation system is the challenge of creating a "unique identity system" - a system for generating tokens that prove that an identity is not part of a Sybil attack. The naive form of anti-Sybil token is simple: a sacrifice or proof of deposit. In a sacrifice setup, such identities simply cost $X, and in a PoD system identities require a deposit of $Y in order to be active, where perhaps the deposit can be taken away or destroyed under certain circumstances. However, we would like to have a system that has nicer and more egalitarian features than "one-dollar-one-vote"; arguably, one-person-one-vote would be ideal. - -To date, we have seen two major strategies for trying to solve this problem. One potential solution is to come up with a proof-of-work algorithm which is dominated by human labor, and not computers. This is not as difficult as it may seem; although computers get more and more powerful every year, there are a number of problems that have remained out of computers' reach for decades, and it may even be possible to identify a class of problems that are the artificial-intelligence-theoretic equivalent of "NP-complete" - problems such that, if they can be solved, it with high probability implies that AI can essentially replicate human activity in its entirety, in which case we are essentially in a post-scarcity utopia and money and incentivization may not even be necessary. These problems may be non-interactive challenges like CAPTCHAs, although all existing CAPTCHAs are far from adequate for the task, or they may be interactive strategy games like Go. - -The second strategy is to use social proof, turning the muscle of decentralized information gathering toward a simple problem: are these two identities the same person? If they are not, then they receive two anti-Sybil tokens, and if they are they receive one token. In general, we can separately define two concepts of identity: voluntary identity and involuntary identity. A voluntary identity can be seen as a cluster of interactions which are in some fashion correlated with each other; for example, a cryptographic identity consists of the set of interactions signed by a particular public key. An involuntary identity is a cluster of interactions which are correlated with each other, but where the entity producing the interactions does not want the correlations to be visible. A simple unique identity system would rely on voluntary identities embedded in social networks, with the understanding that creating separate identities with reputations is an expensive task and so most people would not want to do it, but a more advanced system may try to detect involuntary slipups like writing style patterns or IP addresses. - -The question is, can we use these mechanisms, either separately or together, and perhaps in combination with cryptoeconomic protocols and sacrifices as a fallback in order to create an anti-Sybil system which is highly egalitarian? We will accept that any scheme can be cracked at some cost; however, what we want is for it to be much more efficient for individuals to obtain _one_ anti-Sybil token "the proper way" rather than purchasing one off the grey/black market. The challenge is to push the grey/black market cost as high as possible, as much as possible without making the first token difficult. - -**Problem** - create a mechanism for distributing anti-Sybil tokens - -**Additional Assumptions and Requirements**: - -* Everyone is part of a social network with similar characteristics to social networks now found in the real world, and social data can be provably provided to cryptoeconomic systems (eg. blockchains, Ethereum contracts) -* The cost of obtaining one anti-Sybil token for a human should be as low as possible -* The cost of obtaining multiple anti-Sybil tokens for a human should be as high as possible -* The cost of obtaining anti-Sybil tokens for an automated system should be as high as possible (this is a more important criterion than high cost for multi-obtainment for humans) -* The system should not create dependency on centralized parties (eg. government passport offices) that have the power to cheat the system - -### 15. Decentralized contribution metrics - -Incentivizing the production of public goods is, unfortunately, not the only problem that centralization solves. The other problem is determining, first, which public goods are worth producing in the first place and, second, determining to what extent a particular effort actually accomplished the production of the public good. This challenge deals with the latter issue. Although in the case of computational tasks it's easy to come up with a proof of solution, for non-computational tasks the situation is much more difficult. If a cryptoeconomic system wants to incentivize users to build better graphical user interfaces to its own system, how would it rate people's contributions? [Even more problematically](http://en.wikipedia.org/wiki/Underhanded_C_Contest), what about potentially quasi-adversarial tasks like incentivizing updates to its own code? What about a DAO that funds healthcare, or tries to incentivize adopting renewable energy? - -This is a subclass of the general "social proof" problem; here, the particular challenge is that each individual datum in question is something that very few people are interested in, and data gathering costs are often high. Sometimes, there is not even a concept of a single "correct" value with respect to the particular metric; in the case of quality measurement for an interface, a solution like A/B testing may be required. In adversarial cases, there may need to be an opportunity for incentivized opponents to look at a solution and attempt to pick it apart. - -**Problem**: come up with and implement a decentralized method for determining whether or not a particular task was performed by a specific person, and for estimating the quality of the work - -**Additional Assumptions and Requirements** - -* The agents involved can be a combination of individual humans, teams of humans, AIs, simple software programs and other DAOs -* There is no cryptographically verifiable information about the completion of any task; the system must rely entirely on some form of social proof - -### 16. Decentralized success metrics - -Another, related, problem to the problem of decentralized contribution metrics is the problem of decentralized success metrics. On the macroscopic scale, how do we know if, and to what extent, an organization has succeeded in accomplishing its objectives? In the case of something like Bitcoin, there is a simple, but imperfect, answer: success can be measured by the hashpower of the network. This setup is reasonably effective, but is flawed in two ways: first, hashpower is an imperfect proxy for price, because the development or nondevelopment of ASICs may skew the results, and second, price is an imperfect proxy for success, because the currency may have greater success as something with a lower market capitalization if it is more used in other ways. In the case of a DAO funding healthcare or anti-climate-change efforts, however, no such heuristic exists at all. Once again, some concept of social proof is the only option. - -Here, information gathering costs are low, and information is accessible to everyone in the public, so a higher level of accuracy is possible, hopefully even enough for financial contracts based off of the metric to be possible. However, in order to maintain that higher level of accuracy, and in the presence of such financial derivatives, new problems arise. Can one moderately powerful entity manipulate the metric for their own benefit? If information gathering costs do exist, is the system vulnerable to falling into a centralized equilibrium, where everyone is incentivized to simply follow along with the actions of some specific party? - -**Problem**: come up with and implement a decentralized method for measuring numerical real-world variables - -**Additional Assumptions and Requirements** - -* The agents involved can be a combination of individual humans, teams of humans, AIs, simple software programs and other DAOs -* The system should be able to measure anything that humans can currently reach a rough consensus on (eg. price of an asset, temperature, global CO2 concentration \ No newline at end of file diff --git a/pages/ethereum-and-blockchain-technologies-and-research/research/Security-Categorization.md b/pages/ethereum-and-blockchain-technologies-and-research/research/Security-Categorization.md deleted file mode 100644 index 5f4f16898..000000000 --- a/pages/ethereum-and-blockchain-technologies-and-research/research/Security-Categorization.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -name: Security Categorization -category: ---- - -See also: [https://github.com/ethereum/wiki/wiki/Design-Rationale](https://github.com/ethereum/wiki/wiki/Design-Rationale), for descriptions of potentially counterintuitive design decisions in Ethereum. - -The purpose of this document is to attempt to create a taxonomy of key security properties that we are targeting for the Ethereum protocol, implementation and materials to have at launch time, as well as provide supplementary information where needed for each one. - -### Yellow Paper - -* Paper is free of typos and mathematical and grammatical errors -* The definitions in the paper are clear and unambiguous - * Pay particular attention to external dependencies, eg. the definition of secp256k1 -* In places where the formal definition deviates drastically from all commonly used intuitive definitions, clear explanations are provided - -### Proof of Work - -The working spec description of Dagger Hashimoto is available at [https://github.com/ethereum/wiki/wiki/Ethash](https://github.com/ethereum/wiki/wiki/Ethash) - -The algorithm is intended to have the following key properties: - -* ASIC resistance (ie. lowest possible ASIC speedup coefficient) -* Light-client verifiability, in <1s on Python or Javascript on a desktop or C++ on a Raspberry Pi - -And should not have any of the following flaws: - -* High centralization risk (ie. unboundedly superlinear return) -* Possibility of superior "complex" software implementations (eg. as in SAT solving) -* Cheap evasion of memory hardness (due to light-client verifiability considerations, a low-memory implementation must exist, but this should not be a practical way of mining, and hybrid reduced-memory implementations should also be uneconomical) -* Outright trivial attack (eg. the underlying function is actually polytime invertible) -* Pool resistance -* If pools are going to happen, p2pools should be a viable option - -### Block algorithm - -A simulator of difficulty adjustment is available at https://github.com/ethereum/economic-modeling/blob/master/diffadjust/blkdiff.py . - -The modified GHOST algorithm is defined [here](https://github.com/ethereum/wiki/wiki/White-Paper#modified-ghost-implementation). - -The following properties are desired: - -* The difficulty adjustment should update quickly to increasing or decreasing hashpower and should not be maliciously gameable in any sense. -* The 12 second block time + GHOST should not have perverse incentives (ie. it should be optimal to mine on the head) -* The 12 second block time should not induce an excessively high orphan rate and higher confirmation times than expected. -* Ethereum should remain reasonably light-client friendly, especially for low-power IoT (patch solution if necessary: block skiplists, eg. every block with number % n^k == 0 must refer to the block n^k blocks ago, for say n = 4 and k = 0...3; this basically entails turning prevhash into an array) -* Blockchain bloat: blocksize too big to incentivize new full nodes. Will it be dynamically adjusted? If so, also rogue miners attack to bloat the blockchain -* It should be expensive to generate incentives not to mine on the best chain using baits inside of smart contracts - -### Gas economics - -* The floating gas limit should achieve the compatibility objectives described in https://github.com/ethereum/wiki/wiki/White-Paper#fees -* There should not exist a way for a transaction to get itself executed and spend large amounts of computational resources on many nodes without paying for gas - * The following is an example vulnerability: a miner can create a transaction A that spends a very large amount of gas (eg. ~gaslimit * 0.99) running useless computation. That miner then creates a transaction B with the same nonce that has no effect, and tries to mine a block containing B. If a miner produces a block containing B, it broadcasts A, forcing all other nodes on the network to waste time processing A, even though A actually getting accepted is nearly impossible since B is already published in a block. -* There should not be any kind of of perverse incentive in the way gas costs work on the high level (eg. how gas is passed from parent to child message, how gas is refunded, exception reversions, etc) -* Storage gas refund mechanism should not be exploitable -* The operation gas costs should match the cost of running the operation at least complexity-theoretically (ie. there should be no way of causing O(n^2) computational load with O(n) gas). - * An n*log(n) vulnerability against `JUMP`s in the JIT VM is known, but is deemed not sufficiently catastrophic to worry about - * An example prior vulnerability in PoC6 was that since `CALLDATACOPY` always cost 1 gas, you could incur n^2 computational load with n `CALLDATACOPY` instructions on n bytes of memory (ie. O(n) gas) - * A good implementation of `CALL` and `CREATE` should never actually copy memory to produce call data. Otherwise, it will be vulnerable to a quadratic execution attack where a contract runs CALL n times on n bytes of memory, causing n^2 computational load on O(n) gas - * The return data of a `CALL` is not a source of a quadratic execution vulnerability because the `RETURN` opcode expands memory in each inner call, thereby costing `n` memory expansion gas `n` times. -* Expanding the amount of data stored in the state should cost at least 5 gas per byte in all cases -* There should not exist some operations are much more expensive to execute per unit gas than others, leading to a high "multiplicative griefing factor". Note that this is not a primary concern for security audits; we will perform profiles of each operation ourselves later on in order to set gas costs optimally. - -### VM - -* The VM implementation and the formal specifications (so called Yellow Paper) should be equivalent. The VM implementation can be found at https://github.com/ethereum/go-ethereum/tree/master/vm -* The VM should be resistant to the following attack scenarios: - * Transactions/messages whose execution will somehow escape the VM and either reveal or modify memory or hard drive contents of the client's machine - * Transactions/messages whose execution will cause a system crash - * Transactions/messages that could be processed differently by different machines - * Transactions/messages that have a much higher execution time / gas cost ratio than most others, opening the door to a denial-of-service attack - -### Wire protocol - -The wire protocol is described here: https://github.com/ethereum/wiki/wiki/%C3%90%CE%9EVp2p-Wire-Protocol - -The wire protocol should be secure against the following issues: - -* Node isolation against the block spread algorithm -* Single account transaction paralelism ratio due to nonce validation in peers (vs DoS prevention) -* Sequences of wire messages that would lead to the recipient spending a very large amount of time responding to them -* Sequences of wire messages that would lead to the recipient storing a large amount of data -* Sequences of wire messages that would lead to the recipient storing data that is specifically crafted to make data structures blow up (eg. sending transactions with hashes in sequence in order to make trees very very deep) - * Any third party software, e.g. leveldb would also fall under this scrutiny - e.g. what kind of tree is leveldb? Is it vulnerable to such DoS attacks? -* Messages that would fingerprint the target - -### JS / RPC - -* Check that there are no exploits in the Javascript API, JSON-RPC API -* Define a security model for browser+js bindings. (-or give nathan@leastauthority.com a link to an existing doc.) - -### Libraries - -* Leveldb - * Check for hidden limits in leveldb and other libraries that might trigger inconsistent failures outside the VM, similar to http://bitcoinmagazine.com/3668/bitcoin-network-shaken-by-blockchain-fork/ -* Crytopgraphic libraries - * secp256k1 with a Go bridge (https://github.com/obscuren/secp256k1-go) - * A fork of the official golang sha3 package (https://github.com/obscuren/sha3) (Reason for using a sha3 fork is because the official sha3 has switched to FIPS-202 which Ethereum can't use because genesis addresses have been generated using an earlier version of sha3) - * Official ripemd package (code.google.com/p/go.crypto/ripemd160) - -### Non-Audit security-related product wishlist: - -* How-to write secure contracts -* How-to write secure html+js front-ends diff --git a/pages/ethereum-and-blockchain-technologies-and-research/research/Security-Issue-Process.md b/pages/ethereum-and-blockchain-technologies-and-research/research/Security-Issue-Process.md deleted file mode 100644 index 30695b60b..000000000 --- a/pages/ethereum-and-blockchain-technologies-and-research/research/Security-Issue-Process.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -name: Security Issue Process -category: ---- - -Draft of steps that should be taken when finding a security issue in Ethereum. Security issue is defined as a problem in scope of [Security-Categorization](https://github.com/ethereum/wiki/wiki/Security-Categorization). - -Partly inspired by [OWASP Risk Rating](https://www.owasp.org/index.php/OWASP_Risk_Rating_Methodology) - -### Documentation - -* Add a entry describing the issue at (TODO: github link). -* Estimate likelihood, impact and complexity of fix. -* Affected software version(s). - -### Estimate Likelihood - -* How likely is it to be uncovered and exploited by an attacker? -* Ease of discovery? -* Ease of exploit? -* Likelihood of detection? - -### Estimate Impact - -* Blockchain consensus. Potential of blockchain fork? -* Financial damage. Loss of ether? -* Privacy. E.g. revealing who sent a tx or who owns an address. -* Availability. Can it impact availablity of node(s)? - -### Technical description - -* Protocol version. -* Client version(s). Single or multiple implementations? -* OS / external library version(s). -* Link to relevant source code. -* How to fix. -* How to test. - -### Ownership / Responsibility - -* Who is assigned to fix the issue? -* Who will test / review a fix? -* Who takes responsibility for preparing new builds of client software? - -### Disclosure - -* Who takes on to disclose the issue? -* Communication channels (mail lists, twitter, github). diff --git a/pages/ethereum-and-blockchain-technologies-and-research/research/Serenity_Wishlist.md b/pages/ethereum-and-blockchain-technologies-and-research/research/Serenity_Wishlist.md deleted file mode 100644 index ee3f9dd20..000000000 --- a/pages/ethereum-and-blockchain-technologies-and-research/research/Serenity_Wishlist.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -name: Serenity Wishlist -category: ---- - -This document outlines known flaws and missing features in Ethereum Frontier and Homestead that are non-serious but inconvenient, and which we decided to leave in in order to be able to launch in any reasonable timeframe. We intend to thoroughly investigate solving all of these issues for Serenity (aka. Ethereum 1.1). - -### Big Issues - -1. Because every user must process every transaction (ie. the per-user required quantity of storage is linear in the number of users or level of usage), Ethereum is currently fundamentally unscalable, as are all other blockchain technologies to date. We believe this to be the single largest problem in blockchain development, and it will be our primary focus for either Serenity or a version soon after. -2. Proof of work is an extremely expensive means of maintaining consensus and produces substantial negative externalities due to environmental issues and to a lesser degree principal-agent issues, and its security guarantees are uncomfortably incomplete (eg. it is vulnerable to [P + epsilon attacks](https://blog.ethereum.org/2015/01/28/p-epsilon-attack/) or even outright bribes of fairly low size). We plan to resolve this via proof of stake, which resolves these issues via a combination of proof of stake and subjective resolution-of-last-resort. A small amount of proof of work may remain as an anti-DDoS measure. - -### Trie - -In the process of designing Ethereum 1.0 we have done a thorough job of optimizing the Ethereum virtual machine's computational power, but a much less thorough job of optimizing the database. There exists the possibility for substantial space savings, for both full nodes and light clients, by reorganizing Merkle tree structures and accounts. One example model for a more optimized state tree is the following: - -1. Assign account numbers sequentially, not via `address = sha3(pubkey) % 2**160`. This means that the set of accounts is contiguous, allowing standard binary Merkle trees to be used in place of Patricia trees, saving substantial space in state, history and LOAD/SSTORE time due to the resulting tight-packing. -2. Where Patricia trees are required, switch from hex to binary (est. 10-50% savings) -3. Where Patricia trees are required, note that currently a proof stores redundant info by storing a hash of a tree node in one node and then the other node separately. Create a special-purpose compression algorithm, either LZV style or placing nodes into each other directly when they refer to each other, to deduplicate (est. 35% savings). -4. Charge rent for accounts. This entails expanding accounts by adding a `last_accessed` parameter, and then when an account is accessed we update the parameter to the current block timestamp and simultaneously subtract `rent * (block.timestamp - acct.last_accessed)` from the account balance, where `rent` is somehow dynamically adjusted. If the new balance is below zero, then the account is destroyed and a large gas refund is provided. We theorize that large miners and account holders will want to create transactions that destroy accounts that are lagging on rent in order to reduce storage bloat; alternatively we can incentivize it with an additional security deposit. -5. Require transactions to include a timestamp, so that they can only be valid in `[timestamp, timestamp + 3600]`. This prevents replay attacks in the special case that accounts go down to zero balance, get deleted and then regain balance but with a nonce reset to zero. - -### More expressive Merkle trees - -Certain kinds of mechanisms, to be developed on Ethereum, require a richer set of data structures then just arrays, key/value maps, etc; the most commonly asked-for one is a heap (or an equivalent data structure that supports push/pop/top in logtime), highly useful in front-runner-proof markets among other applications. Currently, implementing a heap in Ethereum will lead to log^3(n) overhead, as we have a tree (the heap) on top of a tree (the account storage Patricia tree) on top of a tree (leveldb). Making a custom DB for the Patricia tree will likely need to be done at some point anyway, and will remove one level of overhead. However, the larger gain will come from the ability to have a Merklized heap-like structure, essentially making the heap operations native to the protocol. This reduces the total overhead all the way to the optimum of log(n). - -See also: Andrew Miller's [Lambda Auth](http://amiller.github.io/lambda-auth/), potentially useful as a starting point for a generalized design. - -### Events - -There should ideally be some mechanism by which one can create events that trigger automatically at certain times in the future, without any overlay protocols (as one simple application of this, consider a dice game that depends on future block data as a source of randomness). For this to work effectively, one must introduce an "event tree" into the Ethereum state alongside the state tree, and add specialized opcodes for creating events (events can be seen as one-way calls that get "frozen" and then executed in the future). A mechanism for gas costs for events, particularly recurring events, should be determined. - -### Verification - -Currently, secp256k1 ECDSA + SHA3 exists as a privileged signature verification algorithm in Ethereum. Ideally, since we are a generalized platform, it would be nice to be able to support any signature verification algorithm. A proposed design for this is: - -1. When a transaction is sent, it does not require a sender, only a "destination" address. Gas price, start gas, value, and data are still required. -2. The top-level message execution by default has a limit of 25000 gas, and within that time must either exit with an error, or run an `ACCEPT` opcode, paying for the full amount of gas from that contract's account. If the message exits with an error before ACCEPTing, the transaction is invalid. If it ACCEPTs, then it has the full amount of gas to run any other computation, send sub-messages, etc. The intent is for the first 25000 gas to be spent verifying a signature placed inside of the transaction data, and exiting with an error if the signature is invalid. - -Ideally, the initial limit would be large enough to support many kinds of signatures, but still small enough to be DDoS-proof. An alternative would be to require PoW on transactions, and scale the PoW difficulty with a verification gas limit set in the transaction; ASIC-resistant PoW can be used for this, though it would need to be carefully designed to be more CPU-friendly rather than GPU-friendly as is the case for Ethash. - -### Compression - -Currently, wire and database compression is done with a fairly crude algorithm that run-length-encodes zeroes but otherwise leaves data unchanged. Substantial gains can probably be made by applying either a pre-generated Huffman code or some separate compression algorithm such as [http://lloyd.github.io/easylzma/](http://lloyd.github.io/easylzma/). - -### Virtual machine - -The Ethereum virtual machine has a number of suboptimalities at present, and so there are plenty of features that can be added or impoved. Particular possibilities include: - -1. The addition of opcodes specialized for 64-bit arithmetic, which can be done on machines much more quickly. -2. The addition of `MCOPY` as an opcode and not a contract. -3. Replacement of DUP1...DUP16 and SWAP1...SWAP16 with `DUP ` (where `` is stored similarly to pushdata). This allows for unlimited depth in stack variables. -4. The addition of a `DEPTH` opcode to determine the current call stack depth, useful or determining whether or not there is enough stack space to make a particular sub-call with a compile-time-known depth. -5. A more radical rearchitecture where the VM deals with 64-bit values only, and long-arithmetic is done directly over memory slices. This removes the 256-bit limit and allows easy crypto calculations at arbitrary sizes. - -### Sending funds - -Currently, there is no way to send _all_ of one's funds to a contract from an externally owned account, unless one can exactly estimate the amount of gas that will be consumed. This adds some inconvenience to the process of emptying accounts. A possible solution is a "keep the change" opcode, by which a contract can (i) absorb all remaining gas in a message, (ii) claim `gas * gasprice` as ether for itself, and (iii) have that gas NOT count toward the miner's revenue or the block's gas limit. - -### Currency Neutrality - -Allow any currency to be used for purposes of security deposits, paying rent, etc. One possible framework in which this could happen is as follows: - -1. Create a base protocol-level concept of "currency". An eligible currency should give the protocol the ability to print more units of it and should support the standard send/receive/allow withdrawal interface. -2. Have (and subsidize liquidity on LMSR-style?) an on-protocol decentralized exchange to determine the price of each token relative to each other token. -3. Anyone can set a security deposit of any size in any currency. The protocol keeps track of a minimum security deposit in every currency (adjusted to target some number of validators), and you cannot add a deposit unless you provide at least this quantity. A deposit ceases to be usable if it falls below 50% of the minimum. - -Alternatives include being more liberal with regard to the assets involved, but using some kind of preference-revelation scheme to determine the value of a maximally arbitrary asset (note: this is hard when you do not have a single "favored currency" which you are assuming will have higher liquidity than everything else). - -A third option is to have a demurrage-heavy (or otherwise ephemeral) pseudo-currency, similar to gas, which is in some way assigned to validators. \ No newline at end of file diff --git a/pages/infrastructure-networking/Adaptive-Message-IDs.md b/pages/infrastructure-networking/Adaptive-Message-IDs.md deleted file mode 100644 index b73396415..000000000 --- a/pages/infrastructure-networking/Adaptive-Message-IDs.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -name: Message IDs -category: ---- - -### Goal - -Dynamic numeric identities for the sub protocol message types rather than the current fixed id system. This way we don't have to reserve parts of the message ID space up front and have a central entity to police this space to prevent clashes. - -### Overview - -All sub-protocol message IDs begin at 0x10 and count only those messages in the shared protocols, in alphabetical order. Sub-protocol versioning is provided in the base protocol to allow guarantees that there is consensus over the number and order of messages for each sub-protocol between peers. - -### Needed Changes - -Wire protocol Hello package changed to (*note protocol version has changed to 1*): - -**Hello** -[`0x00`: `P`, `p2pVersion`: `P`, `clientId`: `B`, [[`cap1`: `B_3`, `capVersion1`: `P`], [`cap2`: `B_3`, `capVersion2`: `P`], ...], `listenPort`: `P`, `nodeId`: `B_64`] First packet sent over the connection, and sent once by both sides. No other messages may be sent until a Hello is received. -* `p2pVersion` Specifies the implemented version of the P2P protocol. Now must be 1. -* `clientId` Specifies the client software identity, as a human-readable string (e.g. "Ethereum(++)/1.0.0"). -* `cap` Specifies a peer capability name as a length-3 ASCII string. Current supported capabilities are `eth`, `shh`. -* `capVersion` Specifies a peer capability version as a positive integer. Current supported versions are 35 for `eth`, and 2 for `shh`. -* `listenPort` specifies the port that the client is listening on (on the interface that the present connection traverses). If 0 it indicates the client is not listening. -* `nodeId` is the Unique Identity of the node and specifies a 512-bit hash that identifies this node. - -All `eth` sub-protocol message ids are lowered by `0x10` and have a `+` prepended to them to denote that the given ID is offset by some dynamic amount. - -### Conversation overview - -``` -[23:11:29] gavofyork: for each shared sub protocol, in alphabetic order, you deploy the subprotocol's messages -[23:11:40] gavofyork: (after the basic p2p messages) -[23:12:42] gavofyork: so for two whisper-only peers, defined message types are Hello = 0x00, Disconnect, Ping, Pong, GetPeers, Peers = 0x05, WhisperMessage1 = 0x06, ... -[23:13:50] gavofyork: but for two peers that have eth and shh, you'd get: Hello = 0x00, Disconnect, Ping, Pong, GetPeers, Peers = 0x05, Status = 0x06, GetTransactions = 0x07, Transactions = 0x08, GetBlockHashes = 0x09, BlockHashes = 0x0a, GetBlocks = 0x0b, Blocks = 0x0c, NewBlock = 0x0d, WhisperMessage1 = 0x0e, ... -[23:14:28] Jeffrey Wilcke: so what you mean is that you negotiate which message type gets what number -[23:14:34] gavofyork: exactamundo -[23:14:45] Jeffrey Wilcke: right interesting -[23:15:12] gavofyork: no arguing over what protocol gets what message-id space -[23:15:25] gavofyork: avoids any central registry or anything -[23:15:33] Jeffrey Wilcke: so receiving and sending might be completely different "numbers" but have the same meaning -[23:15:40] gavofyork: yup -[23:15:56] gavofyork: will make wire protocol analysis slightly harder -[23:16:02] gavofyork: though that's not necessarily a bad thing -[23:16:33] Jeffrey Wilcke: Ok so you tell a node that GetBlockHahses = 0x09 -[23:17:37] Jeffrey Wilcke: GetBlockHashes internally is say 0x03. We give it an array with [0x03, 0x09] meaning "map GetBlockHashes to 0x09" or "when you receive 0x09 I mean GetBlockHashes". -[23:18:12] gavofyork: don't even need to do that -[23:18:21] gavofyork: so we'll need a map internally -[23:18:28] gavofyork: but there's no need to ever serialise it -[23:18:46] Jeffrey Wilcke: No, well you have to let the other know how you understand messages -[23:18:54] Jeffrey Wilcke: meaning that get hashes = 9 -[23:19:01] gavofyork: "for each shared sub protocol, in alphabetic order, you deploy the subprotocol's messages" -[23:19:22] gavofyork: both form natural consensus on the alphabetic order of the shared subprotocols -[23:19:28] gavofyork: just from both Hello packets -[23:20:03] gavofyork: the one thing we should bring in is subprotocol versioning -[23:20:33] Jeffrey Wilcke: but how do we negotiate over the numbering? -[23:20:43] gavofyork: that is the negotiation :) -[23:21:04] gavofyork: you know the exact message type set & order in each subprotocol -[23:21:14] gavofyork: and you know the order they should be counted in -[23:21:26] gavofyork: and you know where to count from -[23:21:28] Jeffrey Wilcke: of course, but how do negotiate over the subprotocol -[23:21:33] gavofyork: oh -[23:21:36] gavofyork: that's in the Hello packet -[23:21:45] gavofyork: that contains the supported subprotocols -[23:21:52] gavofyork: e.g. A <=> B: -[23:21:53] Jeffrey Wilcke: aaah i follow -[23:21:56] gavofyork: ok -[23:22:11] Jeffrey Wilcke: right ok. i thought you meant alphabetical in the _messages_ -[23:22:19] Jeffrey Wilcke: ok makes sense -``` \ No newline at end of file diff --git a/pages/infrastructure-networking/Adaptive-Peer-Time.md b/pages/infrastructure-networking/Adaptive-Peer-Time.md deleted file mode 100644 index 0405c26da..000000000 --- a/pages/infrastructure-networking/Adaptive-Peer-Time.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -name: Adaptive Peer Time -category: ---- - -### Goals - -At present, a single mining peer with its clock substantially (> 25% of the expected block time) ahead of the other peers will cause problems on the network. Forks are common as peers are inconsistently forced to ignore the future blocks. - -A system with multiple peers should be robust to a few peers having substantially fast clocks. - -### Basic Overview - -Each peer does a ping-sequence, each message timestamped with the hardware clock (H) directly after handshake to determine both the network traversal distance ("ping time") and an estimate of the peer's hardware clock (Hp). - -The clock-offset (D) of the peer then becomes its hardware clock (H) corrected to become the median of the peer hardware clocks (median({H1, H2, ...}) = M). - -The clock offset (D) is dynamically evaluated as the peer set changes. - -### Required Changes - -Protocol changes: -* Ping & Pong packets include a timestamp. - -Rest to be implemented lazily. \ No newline at end of file diff --git a/pages/infrastructure-networking/Brain-Wallet.md b/pages/infrastructure-networking/Brain-Wallet.md deleted file mode 100644 index 3a98efc25..000000000 --- a/pages/infrastructure-networking/Brain-Wallet.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -name: Brain Wallet -category: ---- - -Ethereum brain wallets are formed through applying the SHA3 to a seed to get a result `R`, then using `R` as an accumulator for 16384 repeat SHA3 operations. This process is continued until the result, when used as a private key, forms a valid Direct ICAP (34 digit) address, defined as the first byte of the address being 0. - -``` -FUNCTION toBrain(STRING seed) RETURNS SECRET - A = SHA3(seed) - REPEAT 16384 TIMES - A = SHA3(A) - END REPEAT - WHILE SECRET_TO_ADDRESS(A)[0] != 0 DO - A = SHA3(A) - END WHILE - RETURN A -END FUNCTION -``` - -See [C++ implementation](https://github.com/ethereum/cpp-ethereum/blob/develop/libethcore/KeyManager.cpp#L215-L225) for an example. - - -### **Comments (Gustav):** - -Recent advancement in brain wallet cracking [1] show how vulnerable brain wallets are to weak passwords. Applying a KDF hardens brain wallets by reducing number of passwords an attacker can generate per second. - -Even though the seed in AZ is generated for people and can thus be designed to have enough entropy, it is desirable to configure a KDF to be as strong as possible without impacting usability. - -Benchmarking SHA3 in Go [2] on a i5-4278U CPU @ 2.60GHz gives 16384 hashes in 30ms. A C implementation on a high-end CPU would be significantly faster. - -I would recommend we configure a KDF that is much harder (even up to 1-2s CPU time) and also has a memory cost. Scrypt comes to mind, which we already specify in for the key storage [3]. - -This would make our brainwallets much harder to crack, and perhaps even allowing the seed to be shorter, improving usability. - -1. https://rya.nc/cracking_cryptocurrency_brainwallets.pdf -2. https://github.com/ethereum/go-ethereum/blob/master/crypto/crypto_test.go#L65 -3. https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition \ No newline at end of file diff --git a/pages/infrastructure-networking/Clearinghouse.md b/pages/infrastructure-networking/Clearinghouse.md deleted file mode 100644 index 18b429c07..000000000 --- a/pages/infrastructure-networking/Clearinghouse.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -name: Clearinghouse -category: ---- - -### Introduction - -In some type of financial instruments like Futures (but not Forwards), parties are guaranteed against credit losses resulting from the counterparty default by a "clearinghouse". Essentially, a clearinghouse provides this guarantee via a procedure in which the gains and losses that accrue on daily basis throughout the life of a contract are converted into actual cash (daily settlement of gains or losses). - -### Daily Settlement - -As explained a daily settlement is the actual conversion into cash of daily gains or losses. This procedure is called **daily settlement** or **marking to market** and it is best illustrated via an actual example. - -Let's assume two parties enter a Future contract to buy some underlying with a settlement price of 100 USD in a month time (not to be confused with the daily settlement procedure). In order to enter this contract the clearinghouse will set an **initial margin requirement**both the future traders (in this case the party that is going to buy the underlying or the **holder of the long position** and the party that is selling the underlying or the **holder of the short position**) will have to deposit upfront (notice in the context of clearinghouse operations **margin** does not have the same meaning of leverage trading on borrowed money that is used elsewhere). Our initial margin requirement will be 5 USD per contract and will be deposited into a clearinghouse **margin account** associated with the specific contract. - -During the life of the contract as the margin account balances change, the parties involved in the contract must maintains their corresponding balances above a level called the **maintenance margin requirement** again decided by the clearinghouse and usually lower than the initial margin. - -At the end of each day, the clearinghouse will provide a **settlement price** (usually an average price of any trades that happened during the day) and execute the **mark-to-market** process (daily settlement). - -In our specific example, let's assume the maintenance margin has been set at 3 USD per contract and buying party is entering 10 contract (in other words he will have to deposit an initial margin of 50 USD. We shall also assume money cannot be withdrawn from the clearinghouse (i.e. excess funds). The initial price will be 100 USD (the price of the future contract). - -A complete example, is provided in the table below. Notice the two panels report the daily balances of the two parties (long and short). - - -#### Panel A. Holder of Long Position of 10 Contracts - -|Day (1)|Beginning Balance (2)|Funds Deposited (3)|Settlement Price (4)|Futures Price Change (5)|Gain/Loss (6)|Ending Balance (7)| -|:----------:|-------------:|------:|---:|---:|---:|---:| -|0|0|50|100.0| - | - |50| -|1|50|0|99.20| -0.80| -8|42| -|2|42|0|96.00| -3.20| -32|10| -|3|10|40|101.00|5.00|50|100| -|4|100|0|103.50|2.50|25|125| -|5|125|0|103.00| -0.50| -5|120| -|6|120|0|104.00|1.00|10|130| - - -#### Panel B. Holder of Short Position of 10 Contracts -|Day (1)|Beginning Balance (2)|Funds Deposited (3)|Settlement Price (4)|Futures Price Change (5)|Gain/Loss (6)|Ending Balance (7) -|:----------:|-------------:|------:|---:|---:|---:|---:| -|0|0|50|100.0| -| -|50 -|1|50|0|99.20| -0.80|8|58 -|2|58|0|96.00| -3.20|32|90 -|3|90|0|101.00|5.00| -50|40 -|4|40|0|103.50|2.50| -25| 15 -|5|15|35|103.00| -0.50| 5|55 -|6|55|0|104.00|1.00| -10|45|} - -The day the contract is entered will be referred as ''Day 0'', both parties will deposit an initial margin of 50 USD and we shall assume that on ''Day 1'' the future price moves down to 99.20 USD as indicated in Column 4 of Panel A. In Column 5 we can see the Future price change -0.80 (99.20 - 100) and this amount is multipled by the number of contract, 10, to obtain the number in Column 6: -0.80 x 10 = - 8 USD. The ending balance is shown in Column 7 and it is the beginning balance plus/minus any gain/loss. The ending balance on Day 1 for the Holder of the Long Position is 42 USD and it is above the maintenance margin of 30 USD so no extra deposit is required. - -### Ethereum clearinghouse implementation and logic - -* does it apply to all contracts? -* which flag should be set to enable clearinghouse? -* how are the money/ether debited/credited? Push or pull system? -* Normally clearinghouses use an average daily price (not close price). How to implement? THIS IS IMPORTANT TO AVOID PRICE MANIPULATION ethereum would be even more vulnerable than classic clearinghouse. -* what happens in case of default (failed margin call)? Reputation system? -* many contracts will require an external price feed (i.e. Gold price from CME or LIBOR interest rates). How do we feed them? -* can money being withdrawn from the clearinghouse (i.e. excess funds/gains)? Would be simpler if this was not the case. -* what if the parties really want to exchange the underlying? i.e. no cash/ether settlement? (NOT SPECIFIC TO CLEARINGHOUSE) -* losses/gains are magnified by the leverage inherently provided by the clearinghouse. ACCEPTABLE FOR ETHEREUM? NOTICE ALTHOUGH A FULL SUM DO NOT NEED TO BE DEPOSITED UPFRONT. - -### Code reference sample diff --git a/pages/infrastructure-networking/Default-Extra-Data-Standard.md b/pages/infrastructure-networking/Default-Extra-Data-Standard.md deleted file mode 100644 index 145868ce0..000000000 --- a/pages/infrastructure-networking/Default-Extra-Data-Standard.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -name: Extra Data -category: ---- - -Implementations are encouraged to follow this protocol for populating the `extraData` field of mined blocks. - -`extraData` should be an RLP list whose first element is a version identifier encoded as a canonical RLP positive integer. All other items in the list are determined by the version ID. - -`[` version: `P`, ... `]` - -### Version 0 - -`[` version: `P`, clientIdentity: `B` `]` - -One further argument, a raw representation of a string to identify the client (this would usually be a shortened form of the client identifier as returned by the JSON RPC's `web3_clientVersion`). diff --git a/pages/infrastructure-networking/Deterministic_Wallet_Spec.md b/pages/infrastructure-networking/Deterministic_Wallet_Spec.md deleted file mode 100644 index b8da58be5..000000000 --- a/pages/infrastructure-networking/Deterministic_Wallet_Spec.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -name: Deterministic Wallet Spec -category: ---- - -Address/key generation - -The following is a proposed deterministic wallet specification. - -Let `S` be the secret. We define `key(i) = sha3(S + zpad(int_to_big_endian(i), 32))`, where `i` is an incrementing index starting at 0 - -Assuming `S = "123dog"`, we thus have: - - key(0) = sha3("123dog\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") - -Note that the big endian representation of 0 is the empty string. - - key(1) = sha3("123dog\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01") - key(2) = sha3("123dog\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02") - key(255) = sha3("123dog\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff") - key(256) = sha3("123dog\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00") - key(4294967297) = sha3("123dog\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01") \ No newline at end of file diff --git a/pages/infrastructure-networking/EVM-JIT-Binary-Interface.md b/pages/infrastructure-networking/EVM-JIT-Binary-Interface.md deleted file mode 100644 index 3e2d2a85e..000000000 --- a/pages/infrastructure-networking/EVM-JIT-Binary-Interface.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -name: EVM JIT Binary Interface -category: ---- - -# JIT C Interface - -``` C -#include - -// JIT object opaque type -typedef struct evm_jit evm_jit; - -// Contract execution return code -typedef int evm_jit_return_code; - -// Host-endian 256-bit integer type -typedef struct i256 i256; - -// Big-endian right aligned 256-bit hash -typedef struct h256 h256; - -// Runtime data struct - must be provided by external language (Go, C++, Python) -typedef struct evm_jit_rt evm_jit_rt; - -// Runtime callback functions - implementations must be provided by external language (Go, C++, Python) -void evm_jit_rt_sload(evm_jit_rt* _rt, i256* _index, i256* _ret); -void evm_jit_rt_sstore(evm_jit_rt* _rt, i256* _index, i256* _value); -void evm_jit_rt_balance(evm_jit_rt* _rt, h256* _address, i256* _ret); -// And so on... - -evm_jit* evm_jit_create(evm_jit_rt* _runtime_data); - -evm_jit_return_code evm_jit_execute(evm_jit* _jit); - -void evm_jit_get_return_data(evm_jit* _jit, char* _return_data_offset, size_t* _return_data_size); - -void evm_jit_destroy(evm_jit* _jit); -``` - -# Return Code - -Informs user about contract exit status: - -Code| Exit Status -----|----- -0 | Stop -1 | Return -2 | Suicide -101 | Bad Jump Destination -102 | Out Of Gas -103 | Stack Underflow -104 | Bad Instruction - - - -# JIT Runtime Data - -A set of data possibly needed by running contract, sometimes by the compiler itself. -Can be called ExtVM data in C++, VMEnv data in Go. - -Name | Type | Access | Description ------ |------|--------|------------ -Gas | i256 | inout | Gas counter. -Address | h256 | in | Account address. -Caller | h256 | in | -Origin | h256 | in | -CallValue | i256 | in | -CallDataSize | i256 | in | -GasPrice | i256 | in | -PrevHash | i256 | in | -CoinBase | h256 | in | -TimeStamp | i256 | in | -Number | i256 | in | -Difficulty | i256 | in | -GasLimit | i256 | in | -CodeSize | i256 | const | -CallData | byte*| in | -Code | byte*| const | diff --git "a/pages/infrastructure-networking/Ethereum-Raspberry-Pi-e\317\200-Programme.md" "b/pages/infrastructure-networking/Ethereum-Raspberry-Pi-e\317\200-Programme.md" deleted file mode 100644 index ef6ea8a2f..000000000 --- "a/pages/infrastructure-networking/Ethereum-Raspberry-Pi-e\317\200-Programme.md" +++ /dev/null @@ -1,21 +0,0 @@ ---- -name: Ethereum Raspberry Pi -category: ---- - -# The Ethereum Raspberry Pi (eπ) Programme - -The eπ programme is aimed to get as many nodes distributed around the world as possible. Any existing Ethereum meetup group is eligible to apply. - -We will offer to loan the group a set of equipment to run an Ethereum node. This will include: - -- Raspberry Pi 2 Model B; -- 64 GB fast memory card; -- PSU. - -We expect you guys to be the ones to run the install (https://github.com/ethereum/wiki/wiki/Raspberry-Pi-instructions). - -Your node will be placed on both our public and curated node lists, and aside from allowing us to show dots all over the world, will help us better understand network dynamics and emergent effects stemming from our propagation strategies. - -To apply for the programme, send an application including your name, meetup group name/town and an address for shipment to epi@ethereum.org. - diff --git a/pages/infrastructure-networking/Exchange-Integration.md b/pages/infrastructure-networking/Exchange-Integration.md deleted file mode 100644 index 9fa065749..000000000 --- a/pages/infrastructure-networking/Exchange-Integration.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: Exchange Integration -category: ---- - -## Overview - -TODO - -## Reference implementation - -TODO: Design/documentation for implementation - -https://github.com/debris/eth-exchange diff --git a/pages/infrastructure-networking/ICAP:-Inter-exchange-Client-Address-Protocol.md b/pages/infrastructure-networking/ICAP:-Inter-exchange-Client-Address-Protocol.md deleted file mode 100644 index d68a810be..000000000 --- a/pages/infrastructure-networking/ICAP:-Inter-exchange-Client-Address-Protocol.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -name: ICAP Inter Exchange Client Address Protocol -category: ---- - -Transferring funds between third-party accounts, especially those of exchanges, places considerable burden on the user and is error prone, due to the way in which deposits are identified to the client account. This problem was tackled by the existing banking industry through having a common code known as *IBAN*. This code amalgamated the institution and client account along with a error-detection mechanism practically eliminating trivial errors and providing considerable convenience for the user. Unfortunately, this is a heavily regulated and centralised service accessible only to large, well-established institutions. The present protocol, ICAP, may be viewed as a decentralised version of it suitable for any institutions containing funds on the Ethereum system. - -### IBAN - -For a good overview of the IBAN system, please see [Wikipedia's IBAN article](https://en.wikipedia.org/wiki/International_Bank_Account_Number). An IBAN code consists of up to 34 case insensitive alpha-numeric characters. It contains three pieces of information: - -- The country code; a top-level identifier for the context of the following (ISO 3166-1 alpha-2); -- The error-detection code; uses the *mod-97-10* checksumming protocol (ISO/IEC 7064:2003); -- The basic bank account number (BBAN); an identifier of the institution, branch and client account, whose composition is dependent on the aforementioned country. - -For the UK, the BBAN is composed of: - -- Institution identifier, 4-character alphabetical, e.g. `MIDL` (ironically) represents HSBC bank. -- Sort-code (branch identifier within the institution), a 6-digit decimal number, e.g. `402702` would be the Lancaster branch of HSBC. -- Account number (client identifier within the branch), an 8-digit decimal number. - -# Proposed Design - -Introduce a new IBAN country code: *XE*, formulated as the Ethereum *E* prefixed with the "extended" *X*, as used in non-jurisdictional currencies (e.g. XRP, XCP). - -There will be three BBAN possibilities for this code; *direct*, *basic* and *indirect*. - -#### Direct - -The BBAN for this code when direct will be 30 characters and will comprise one field: - -- Account identifier, 30 characters alphanumeric (< 155-bit). This will be interpreted as a big-endian encoded base-36 integer representing the least significant bits of a 160-bit Ethereum address. As such, these Ethereum addresses will generally begin with a zero byte. - -e.g. XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS corresponds to the address `00c5496aee77c1ba1f0854206a26dda82a81d6d8`. - -#### Basic - -The same as the direct encoding, except that the code is 31 characters (making it non-compliant for IBAN) and composes the same, single, field: - -- Account identifier, 31 characters alphanumeric (< 161-bit). This will be interpreted as a big-endian encoded base-36 integer representing a 160-bit Ethereum address. - -#### Indirect - -The BBAN for this code when indirect will be 16 characters and will comprise three fields: - -- Asset identifier, 3-character alphanumeric (< 16-bit); -- Institution identifier, 4-character alphanumeric (< 21-bit); -- Institution client identifier, 9-character alphanumeric (< 47-bit); - -Including the four initial characters, this leads to a final client-account address length of 20 characters, of the form: - -``` -XE81ETHXREGGAVOFYORK -``` - -Split into: - -- `XE` The country code for Ethereum; -- `66` The checksum; -- `ETH` The asset identifier within the client account - in this case, "ETH" is the only valid asset identifier, since Ethereum's base registry contract supports only this asset; -- `XREG` The institution code for the account - in this case, Ethereum's base registry contract; -- `GAVOFYORK` The client identifier within the institution - in this case, a direct payment with no additional data to whatever primary address is associated with the name "GAVOFYORK" in Ethereum's base registry contract; - -## Notes - -Institution codes beginning with `X` are reserved for system use. - -## Other forms - -### URI - -General URIs can be formed though the URI scheme name `iban`, followed by the colon character `:`, followed by the 20-character alphanumeric identifier, thus for the example above, we would use: - -``` -iban:XE81ETHXREGGAVOFYORK -``` - -### QR Code - -A QR code may be generated directly from the URI using standard QR encodings. For example, the example above `iban:XE81ETHXREGGAVOFYORK` would have the corresponding QR code: - -![QR code for iban:XE81ETHXREGGAVOFYORK](http://opensecrecy.com/qr-XE81ETHXREGGAVOFYORK.gif) - -# Transaction Semantics - -The mechanism for indirect asset transfer over three routing protocols are specified, all of which are specific to the Ethereum domain (country-code of `XE`). One is for currency transfers directly to an included address ("direct"), another is for clients with the system address found through a Registry-lookup system of the client-ID, denoted by asset class `ETH`, whereas the last is for transfers to an intermediary with associated data to specify client, denoted by asset class `XET` (the latter two are "indirect"). - -## Direct - -If the IBAN code is 34 characters, it is a direct address; a direct transfer is made to the address which, when base-36 encoded gives exactly the data segment (the last 30 characters) of the IBAN code. - -## Indirect ETH Asset: Simple transfers - -Within the ETH asset code of Ethereum's country-code (XE), i.e. as long as the code begins with `XE**ETH` (where `**` is the valid checksum), then we can define the required transaction to be the deposit address given by a call to the *registry contract* denoted by the institution code. For institutions not beginning with `X`, this corresponds to the primary address associated with the *Ethereum standard name*: - -[institution code] `/` [client identifier] - -The *Ethereum standard name* is simply the normal hierarchical lookup mechanism, as specified in the Ethereum standard interfaces document. - -We define a *registry contract* as a contract fulfilling the Registry interface as specified in the Ethereum standard interfaces document. - -**TODO**: JS code for specifying the transfer. - -## Indirect XET Asset: Institution transfers - -For the `XET` asset code within the Ethereum country code (i.e. while the code begins XE**XET), then we can derive the transaction that must be made through a lookup to the Ethereum `iban` registry contract. For a given institution, this contract specifies two values: the deposit call signature hash and the institution's Ethereum address. - -At present, only a single such deposit call is defined, which is: - -``` -function deposit(uint64 clientAccount) -``` - -whose signature hash is `0x13765838`. The transaction to transfer the assets should be formed as an ether-laden call to the institution's Ethereum address using the `deposit` method as specified above, with the client account determined through the value of the big-endian, base-36 interpretation of the alpha-numeric *Institution client identifier*, literally using the value of the characters `0` to `9`, then evaluating 'A' (or 'a') as 10, 'B' (or 'b') as 11 and so forth. - -**TODO**: JS code for specifying the transfer. \ No newline at end of file diff --git a/pages/infrastructure-networking/IPv6.md b/pages/infrastructure-networking/IPv6.md deleted file mode 100644 index 855661d3e..000000000 --- a/pages/infrastructure-networking/IPv6.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: IPv6 -category: ---- - -### Goals - -Allow IPv6 to be used over the ethereum peer network - -### Basic Design - -Allow IP addresses to be specified either as a 4-byte array (IPv4) or a 16-byte array (IPv6). - -### Needed Changes - -**Peers** -[`0x05`, [`ip1`: `B_4` OR `B_16`, `port1`: `P`, `id1`: `B_64`], [`ip2`: `B_4` OR `B_16`, `port2`: `P`, `id2`: `B_64`], ... ] Specifies a number of known peers. -* `ip` is either a 4-byte array 'ABCD' that should be interpreted as the IPv4 address A.B.C.D or a 8-byte array 'ABCDEFGHIJKLMNOP' that should be interpreted as the IPv6 address AB:CD:EF:GH:IJ:KL:MN:OP. -* `port` is a 2-byte array that should be interpreted as a 16-bit big-endian integer. -* `id` is the 512-bit hash that acts as the unique identifier of the node. diff --git a/pages/infrastructure-networking/Kademlia-Peer-Selection.md b/pages/infrastructure-networking/Kademlia-Peer-Selection.md deleted file mode 100644 index ee4187f20..000000000 --- a/pages/infrastructure-networking/Kademlia-Peer-Selection.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -name: Cademlia Peer Selection -category: ---- - -# Peer addresses - -Nodes in the P2P network are identified by 256-bit cryptographic hashes of the nodes' public keys. - -The distance between two addresses is the MSB first numerical value of their XOR. - -# Peer table format - -The peer table consists of rows, initially only one, at most 255 (typically much less). Each row contains at most _k_ peers (data structures containing information about said peer such as their peer address, network address, a timestamp, signature by the peer and possibly various other meta-data), where _k_ is a parameter (not necessarily global) with typical values betwen 5 and 20. - -This parameter, _k_, determines the redundancy of the network: the peer selection algorithm described in this page aims to maintain exactly _k_ peers in each row. If several different protocols requiring routing are used on the network, each protocol _p_ can specify its own redundancy requirement _k__p_, in which case the corresponding _k__p_ number of peers supporting that protocol are maintained. Participants must specify what protocols they support. - -Row numbering starts with 0. Each row number _i_ contains peers whose address matches the first _i_ bits of this node's address. The _i_+1st bit of the address must differ from this nodes address in all rows except the last one. - -As a matter of implementation, it might be worth internally representing all 255 rows from the outset (requiring that the _i_+1st bit be different from our node in all rows); but then considering all of the rows at the end as if they were one row. That is, we look at non empty rows at the end and treat the elements in them as if they belonged to row _i_ where _i_ is the lowest index such that the total number of all elements in row _i_ and in all higher rows, together is at most _k_. - -Note: there is a difference here to the original Kedemlia paper http://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf The rows with a high _i_ for us here are the rows with a low _i_ in the paper. For us, high _i_ means high number of bits agreeing, for them high _i_ mean high xor distance. - -# Adding a new peer - -A peer is added to the row to which it belongs according to the length of address prefix in common with this node. If that would increase the length of the row in question beyond _k_, the **worst** peer (according to some, not necessarily global, peer quality metric) is dropped from the row, except if it is the last row, in which case a new row _i_ + 1 is added and the elements in the old last row are split between the two rows according to the bit at the corresponding position. Note: If we followed the implementation suggestion in the previous section, then we do not need to make an exception for the last row, nor do we have to worry about splitting the last row on the implementation level. - -One sufficient condition for adding a peer is a signed "_add_me_" message containing the sender's peer address and network address, the addressee's peer address and a recent timestamp. - -# Lookup - -A lookup request contains a peer address (which might or might not be valid, it does not matter). The response is the peer list from the full row corresponding to the requested address (information about at most _k_ peers, or _k__p_ peers for the protocol _p_ in use). - -For brevity, it might be worth treating _add_me_ requests for nodes that are not already in the peer table as self-lookups and respond accordingly. - -The new peers are added to the peer table after which the ones in the row corresponding to the address being searched are sent the lookup request recursively, until no peers are returned that are closer to the searched address. - -# Joining the network - -Requires only one bootstrap peer, to which the new node sends an _add_me_ message and subsequently adds every node from the response to its own peer table. - -Thereafter, it performs a lookup of a synthetic random address from the address range corresponding to rows with indices that are smaller than the row in which the bootstrap node ended up. - -# Backwards compatibility mode and DoS safety - -Nodes can still safely dump their full peer table and accept connections from naive nodes. Overwriting the entire peer table of a node requires significant computational effort even with relatively low _k_. DoS attacks against non-naive nodes (as described in this page) require generating addresses with corresponding key pairs for each row, requiring quite a bit of hashing power. \ No newline at end of file diff --git a/pages/infrastructure-networking/Layers.md b/pages/infrastructure-networking/Layers.md deleted file mode 100644 index 227a0cc7a..000000000 --- a/pages/infrastructure-networking/Layers.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -name: Layers -category: ---- - -## Networking daemon - -Purpose: the networking daemon must be able to connect to other Ethereum nodes, and accept and share data, so as to serve as the backbone for the Ethereum network. The daemon itself should be as neutral as possible; ideally, it should be useful as part of any currency or cryptographic protocol without modification. It should include anti-DDoS features; perhaps maintain a running score preventing any single IP from making more than one request per second. - -Interface: - -1. every time the daemon receives a new message (ie. H(M) is not equal to H(Mprev) for any Mprev received previously), it should send a POST request to http://localhost: containing the data, where outputport can be set in the ~/.ethereum/ethereum.conf file (default 1242 if not set) -2. the daemon should listen on port , where inputport can be set in the ~/.ethereum/ethereum.conf file (default 1243 if not set), and if it receives a message in a post request it should push the data out to all connected nodes in the network. -Dependencies: internet, bootstrapping nodes - -## Ethereum Core - -### Communication layer - -1. Process_network_message(string) -> msg or transaction or block -2. Create_network_message - -### IO Layer (ie. usually database) - -1. Insert object(value) (key = sha256(value)) -2. Get object (key) -> value - -### Data layer - -1. get_transaction -2. get_block -3. get_address_balance / nonce -4. get_contract_memory_at_index -5. get_contract_root -6. get_object (Merkle trie nodes, etc) -7. block class -8. transaction class - -### Manager - -1. get_latest_block -2. add_block (including validation and total difficulty calculation) -3. apply_transactions_to_block (for miners) - -### Application Layer - -1. Wallet -2. Full -3. SPV -4. Graphical block explorer -5. Miner - -## Classes - -### Block class - -Purpose: the block class should be able to parse blocks, serialize blocks and handle certain updating operations to blocks. - -Interface: - -1. deserialize: string -> void (constructor) -2. get_balance: number address -> number -3. get_contract_state: number address, number index -> number -4. update_balance: number address, number newbalance -> void -5. update_contract_state: number address, number index, number newvalue -> void -6. get_contract_size: number address -> number -7. serialize: void -> string - -### Transaction class - -Purpose: the transaction class should be able to parse transactions, sign transactions and serialize transactions. Note that the serialize method should fail for transactions without a signature; transactions that are created inside a block and not deserialized should never actually be stored or serialized in any form. - -Interface: - -1. deserialize: string -> void (constructor) -2. sign: privkey -> void -3. serialize: void -> string -4. create: number address, number value, number fee, array[number] data -> void (constructor) -5. hash: void -> number -6. to, from, value, fee, data (accessible and settable member variables) diff --git a/pages/infrastructure-networking/Mining.md b/pages/infrastructure-networking/Mining.md deleted file mode 100644 index 2fce6bcb0..000000000 --- a/pages/infrastructure-networking/Mining.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -name: Mining -category: ---- - -# Introduction - -The word mining originates in the context of the gold analogy for crypto currencies. Gold or precious metals are scarce, so are digital tokens, and the only way to increase the total volume is through mining it. This is appropriate to the extent that in Ethereum too, the only mode of issuance post launch is via the mining. Unlike these examples however, mining is also the way to secure the network by creating, verifying, publishing and propagating blocks in the blockchain. - -* Mining Ether = Securing the network = verify computation - -## So what is mining anyway? - -Ethereum Frontier like all blockchain technologies uses an incentive-driven model of security. Consensus is based on choosing the block with the highest total difficulty. -Miners produce blocks which the others check for validity. Among other well-formedness criteria, a block is only valid if it contains **proof of work** (PoW) of a given **difficulty**. -Note that in Ethereum 1.1, this is likely gonna be replaced by a **proof of stake** model. - -The proof of work algorithm used is called [Ethash](https://github.com/ethereum/wiki/wiki/Ethash) (a modified version of [Dagger-Hashimoto](https://github.com/ethereum/wiki/wiki/Dagger-Hashimoto) involves finding a nonce input to the algorithm so that the result is below a certain threshold depending on the difficulty. The point in PoW algorithms is that there is no better strategy to find such a nonce than enumerating the possibilities while verification of a solution is trivial and cheap. If outputs have a uniform distribution, then we can guarantee that on average the time needed to find a nonce depends on the difficulty threshold, making it possible to control the time of finding a new block just by manipulating difficulty. - -The difficulty dynamically adjusts so that on average one block is produced by the entire network every 12 seconds (ie., 12 s block time). This heartbeat basically punctuates the synchronisation of system state and guarantees that maintaining a fork (to allow double spend) or rewriting history is impossible unless the attacker possesses more than half of the network mining power (so called 51% attack). - -Any node participating in the network can be a miner and their expected revenue from mining will be directly proportional to their (relative) mining power or **hashrate**, ie., number of nonces tried per second normalised by the total hashrate of the network. - -Ethash PoW is memory hard, making it ASIC resistant. This means that calculating the PoW requires choosing subsets of a fixed resource dependent on the nonce and block header. This resource (a few gigabyte size data) is called a **DAG**. The [DAG](https://github.com/ethereum/wiki/wiki/Ethash-DAG) is totally different every 30000 blocks (a 100 hour window, called an **epoch**) and takes a while to generate. Since the DAG only depends on block height, it can be pregenerated but if its not, the client needs to wait till the end of this process to produce a block. Until clients actually precache dags ahead of time the network may experience a massive block delay on each epoch transition. Note that the DAG does not need to be generated for verifying the PoW essentially allowing for verification with both low CPU and small memory. - -As a special case, when you start up your node from scratch, mining will only start once the DAG is built for the current epoch. - - -## Mining Rewards - -Note that mining 'real' Ether will start with the Frontier release. On the Olympics testnet, the [Frontier pre-release](http://ethereum.gitbooks.io/frontier-guide/), the ether mined have no value (but see [Olympic rewards](https://blog.ethereum.org/2015/05/09/olympic-frontier-pre-release/)). - -The successful PoW miner of the winning block receives: -* A **static block reward** for the 'winning' block, consisting of exactly 5.0 Ether -* All of the gas expended within the block, that is, all the gas consumed by the execution of all the transactions in the block submitted by the winning miner is compensated for by the senders. The gascost incurred is credited to the miner's account as part of the consensus protocoll. Over time, it's expected these will dwarf the static block reward. -- An extra reward for including Uncles as part of the block, in the form of an extra 1/32 per Uncle included - -Uncles are stale blocks, ie with parent that are ancestors (max 6 blocks back) of the including block. -Valid uncles are rewarded in order to neutralise the effect of network lag on the dispersion of mining rewards, thereby increasing security. -Uncles included in a block formed by the successful PoW miner receive 7/8 of the static block reward = 4.375 ether -A maximum of 2 uncles allowed per block. - -## Ethash DAG - -Ethash uses a **DAG** (directed acyclic graph) for the proof of work algorithm, this is generated for each **epoch**, i.e every 30000 blocks (100 hours). The DAG takes a long time to generate. If clients only generate it on demand, you may see a long wait at each epoch transition before the first block of the new epoch is found. However, the DAG only depends on block number, so it CAN and SHOULD be calculated in advance to avoid long wait at each epoch transition. `geth` implements automatic DAG generation and maintains two DAGS at a time for smooth epoch transitions. Automatic DAG generation is turned on and off when mining is controlled from the console. It is also turned on by default if `geth` is launched with the `--mine` option. Note that clients share a DAG resource, so if you are running multiple instances of any client, make sure automatic dag generation is switched on in at most one client. - -To generate the DAG for an arbitrary epoch: - -``` -geth makedag -``` - -For instance `geth makedag 360000 ~/.ethash`. Note that ethash uses `~/.ethash` (Mac/Linux) or `~/AppData/Ethash` (Windows) for the DAG so that it can shared between clients. - - -# The Algorithm - -Our algorithm, [Ethash](https://github.com/ethereum/wiki/wiki/Ethash) (previously known as Dagger-Hashimoto), is based around the provision of a large, transient, randomly generated dataset which forms a DAG (the Dagger-part), and attempting to solve a particular constraint on it, partly determined through a block's header-hash. - -It is designed to hash a fast verifiability time within a slow CPU-only environment, yet provide vast speed-ups for mining when provided with a large amount of memory with high-bandwidth. The large memory requirements mean that large-scale miners get comparatively little super-linear benefit. The high bandwidth requirement means that a speed-up from piling on many super-fast processing units sharing the same memory gives little benefit over a single unit. - -## Formal Requirements - -TODO: Content from formal requirements doc. - -## Design Decisions Taken - -TODO: Content from design decisions doc. - -## Infrastructure Overview - -Mining will be accomplished in one of two ways: either on CPU (and possibly the GPU, to be confirmed) with the Mist client or on the GPU though a combination of the Ethereum daemon and [sgminer](https://github.com/sgminer-dev/sgminer). - -An sgminer module for Ethash is expected to be released at some point during, but not necessarily before the Frontier Genesis. - -## JSON-RPC - -Communication between the external mining application and the Ethereum daemon for work provision and submission happens through the JSON-RPC API. Two RPC functions are provided; `eth_getWork` and `eth_submitWork`. - -These are formally documented on the [JSON-RPC API](https://github.com/ethereum/wiki/wiki/JSON-RPC) wiki article. - diff --git a/pages/infrastructure-networking/NatSpec-Determination.md b/pages/infrastructure-networking/NatSpec-Determination.md deleted file mode 100644 index 41deff0aa..000000000 --- a/pages/infrastructure-networking/NatSpec-Determination.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -name: NatSpec Determination -category: ---- - -Publishing and finding the [NatSpec] (https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format) documentation for a contract is an important part of the Ethereum system. There are two pieces to this puzzle: the first is for a given client to be able to determine, given a call to a contract, what a **trustworthy** NatSpec documentation hash for the contract is; the second is to find the actual NatSpec documentation body given its content hash. - -### Trusted Content Determination - -The former, trusted content determination, will ultimately be accomplished through a sophisticated reputation system. In the meantime, we (the Ethereum foundation) will maintain our own curated repository of trusted NatSpec documentation hashes in a contract. The contract is trivial, just providing a mapping from contract code hash to NatSpec JSON file hash. It can be found [here](https://github.com/ethereum/dapp-bin/blob/master/NatSpecReg/contract.sol). We, alone, will retain the key updating and adding entries to this contract. - -This contract will have a specific address on the PoC-9 & Frontier testnet, probably referenced from the Ethereum services contract. - -### Content Publishing and Distribution - -The latter, content publishing and distribution, will ultimately be accomplished through the "Swarm" subsystem or IPFS. Until then, we will piggy back on the existing workaround for content-based publication and distribution; the [URL Hint](https://github.com/ethereum/wiki/wiki/URL-Hint-Protocol) system. - diff --git a/pages/infrastructure-networking/Natspec-Example.md b/pages/infrastructure-networking/Natspec-Example.md deleted file mode 100644 index bb09be753..000000000 --- a/pages/infrastructure-networking/Natspec-Example.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -name: NatSpec Example -category: ---- - -# Introduction - -This is intended as an example of proof of concept of the natspec evaluation in Alethzero, the CPP client and as a showcase of the functionality of Natspec comments. - -# Steps - -## Create the natspec documentation - -Open up alethzero client and type in the following contract that we will use as an example - -``` -contract test { - /// @notice Will multiply `a` by 7. - function multiply(uint a) returns(uint d) { - return a * 7; - } -} -``` - -![Creating natspec in AZ](images/natspec1.png) - -Then press the `Execute` button in order to generate the contract creation transaction. We can do that from the JSON Api too but we are using AlethZero in order to create the natspec documentation from the contract. Pressing the execute button will create a local database entry (LevelDB) of a mapping of the contract's hash to the natspec documentation. - -This is just a temporary solution to showcase the functionality of natspec. The idea is for people to be able to retrieve natspec documentations of contracts from a trusted authority which most users can trust. - -## Open up the example contract - -![Opening up example contract](images/natspec2.png) -We will be using the JSON Api to try and perform the only transaction that our example contract has defined in its interface. Open up Alethzero's internal browser and type in the following path to get to our example `/path/to/cpp-ethereum/libjsqrc/ethereumjs/example/natspec_contract.html`. - -You should see a page similar to below. Press the button to start the example. -![Starting natspec example](images/natspec3.png) -## Performing the transaction - -This is the interface our _application_ has for the contract. Using the textbox we can provide the input to the transaction and then execute it. - -## Authentication - -At this final stage is where natspec actually comes into place. Each and every transaction has an authentication stage. The natspec documentation is what is provided to the user in order to notify him of the transaction and query whether or not to go ahead with it. -![Authenticating natspec](images/natspec4.png) - -As you can see from the picture below even if a contract's transaction does not have any specific documentation we will still get a generic popup message asking us whether or not we want to authenticate the transaction. -![Authenticating unknown transaction](images/natspec5.png) \ No newline at end of file diff --git a/pages/infrastructure-networking/Network-Status.md b/pages/infrastructure-networking/Network-Status.md deleted file mode 100644 index 30fb35cea..000000000 --- a/pages/infrastructure-networking/Network-Status.md +++ /dev/null @@ -1,101 +0,0 @@ ---- -name: NatSpec Status -category: ---- - -# Network Status Monitoring - -The [Ethereum (centralised) network status monitor](https://stats.ethdev.com) (known sometimes as "eth-netstats") is a web-based application to monitor the health of the testnet/mainnet through a group of nodes. - -## Listing - -To list your node, you must install the client-side information relay, a node module. Instructions given here work on Ubuntu (Mac OS X follow same instructions, but sudo may be unnecessary). Other platforms vary (please make sure that nodejs-legacy is also installed, otherwise some modules might fail). - -Clone the git repo, then install pm2: - -``` -git clone https://github.com/cubedro/eth-net-intelligence-api -cd eth-net-intelligence-api -npm install -sudo npm install -g pm2 -``` - -Then edit the `app.json` file in it to configure for your node: - -- alter the value to the right of `LISTENING_PORT` to the ethereum listening port (default: 30303) -- alter the value to the right of `INSTANCE_NAME` to whatever you wish to name your node; -- alter the value to the right of `CONTACT_DETAILS` if you wish to share your contact details -- alter the value to the right of `RPC_PORT` to the rpc port for your node (by default 8545 for both cpp and go); -- and alter the value to the right of `WS_SECRET` to the secret (you'll have to get this off [the official skype channel](http://tinyurl.com/ofndjbo)). - -Finally run the process with: - -``` -pm2 start app.json -``` - -Several commands are available: - -- `pm2 list` to display the process status; -- `pm2 logs` to display logs; -- `pm2 gracefulReload node-app` for a soft reload; -- `pm2 stop node-app` to stop the app; -- `pm2 kill` to kill the daemon. - -### Updating -In order to update you have to do the following: -- `git pull` to pull the latest version -- `sudo npm update` to update the dependencies -- `pm2 gracefulReload node-app` to reload the client - - -*** - -## Auto-installation on a fresh Ubuntu install -Fetch and run the build shell. This will install everything you need: latest ethereum - CLI from develop branch (you can choose between eth or geth), node.js, npm & pm2. - -```bash -bash <(curl https://raw.githubusercontent.com/cubedro/eth-net-intelligence-api/master/bin/build.sh) -``` - -### Configuration -Configure the app modifying [processes.json](/eth-net-intelligence-api/blob/master/processes.json). Note that you have to modify the backup processes.json file located in `./bin/processes.json` (to allow you to set your env vars without being rewritten when updating). - -```js -"env": - { - "NODE_ENV" : "production", // tell the client we're in production environment - "RPC_HOST" : "localhost", // eth JSON-RPC host the default is 8545 - "RPC_PORT" : "8545", // eth JSON-RPC port - "LISTENING_PORT" : "30303", // eth listening port (only used for display) - "INSTANCE_NAME" : "", // whatever you wish to name your node - "CONTACT_DETAILS" : "", // add your contact details here if you wish (email/skype) - "WS_SERVER" : "wss://stats.ethdev.com", // path to eth-netstats WebSockets api server - "WS_SECRET" : "", // WebSockets api server secret used for login - } -``` - -### Run - -Run it using pm2: - -```bash -cd ~/bin -pm2 start processes.json -``` - -ethereum (eth or geth) must be running with rpc enabled. - -``` -geth --rpc -``` -the default port (if one is not specified) for rpc under geth is 8545 - -### Updating -To update the API client use the following command: - -```bash -~/bin/www/bin/update.sh -``` - -It will stop the current netstats client processes, automatically detect your ethereum implementation and version, update it to the latest develop build, update netstats client and reload the processes. \ No newline at end of file diff --git a/pages/infrastructure-networking/NewBlock-Message.md b/pages/infrastructure-networking/NewBlock-Message.md deleted file mode 100644 index 91699561d..000000000 --- a/pages/infrastructure-networking/NewBlock-Message.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -name: NewBlock Message -category: ---- - -### Goals - -At present `Blocks` messages may be sent either as a response to a `GetBlocks` message receipt or due to a new block being mined or discovered. This causes some issues for the state transition mechanisms, which are to be avoided. - -### Basic Design - -Provide a second response type explicitly used for distributing a new block. - -### Needed Changes - -New packet for the Ethereum sub-protocol, `NewBlock`: - -**Blocks** -[`+0x06`, [`blockHeader`, `transactionList`, `uncleList`], `...`] Specify (a) block(s) as an answer to `GetBlocks`. The items in the list (following the message ID) are blocks in the format described in the main Ethereum specification. This may validly contain no blocks if no blocks were able to be returned for the `GetBlocks` query. - -**NewBlock** -[`+0x07`, [`blockHeader`, `transactionList`, `uncleList`], `totalDifficulty`] Specify a single block that the peer should know about. The composite item in the list (following the message ID) is a block in the format described in the main Ethereum specification. -- `totalDifficulty` is the total difficulty of the block (aka score). diff --git a/pages/infrastructure-networking/Raspberry-Pi-instructions.md b/pages/infrastructure-networking/Raspberry-Pi-instructions.md deleted file mode 100644 index 6d86d36c5..000000000 --- a/pages/infrastructure-networking/Raspberry-Pi-instructions.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -name: Raspberry Pi Instructions -category: ---- - -## Get the "everything-is-ready" image for your Raspberry Pi 2 -Download from: http://gav.ethdev.com/ArchLinuxEthereum12082015.img.zip -(it's 2.4 GB in size, if you want to save bandwidth, go and build it yourself, see instructions below) - -Unzip it and follow those guidelines to copy the image to your sd card: https://www.raspberrypi.org/documentation/installation/installing-images/ - -Plugin the sd card, LAN connection and the power supply and lets start! - -In order to connect to your pi follow those instructions: https://www.raspberrypi.org/documentation/remote-access/ssh - -Currently there are two users, `root` and `pi`. -The passwords are `root` and `raspberry`, respectivly. The first thing you should do is change that. Otherwise everyone can see your IP in netstats and just log into your Raspberry Pi. -Log in and type `passwd ` to update the password for each user. - - - -Currently the go client (geth) and the cpp client (eth) are preinstalled. You can find instruction on how to use them here: https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options and here: https://github.com/ethereum/cpp-ethereum/wiki/Using-Ethereum-CLI-Client. But executing eth/geth with `--help` will give you more up-to-date information on how to use them. -Also eth-netstats is installed. You can find instructions in how to use it here: https://github.com/ethereum/wiki/wiki/Network-Status. -It is used to display your client on the centralized network server (http://stats.ethdev.com/). -In order to give your client a different name, choose your favorite command line text editor and change the `INSTANCE_NAME` parameter in `~/eth-net-intelligence-api/app.json` to whatever you like. - -For convenience there is `startClientWithNetstat.sh` script (execute it with bash) which starts the client and registers it on eth-netstats. -(Note: Downloading the chain takes several hours up to a day, during that time the Raspberry Pi is so busy that netstats doesn't work properly, it may even crash. You may not see your client on netstats until the download is complete. If you don't see you client after one complete day, try a reboot and execute the script again.) - -For updating the clients you can just do `bash updateClient.sh` (this may take a while and may not work, since it is pulling current develop. Dependencies have changed). - -## Resize your system to use large sd cards - -The image is for a 8GB sd card. It allocates 2 GB as swap (needed for compiling and mining :-) ). If your sd card is larger than 8GB, then follow those instructions: - -As root execute -``` -fdisk /dev/mmcblk0 -``` - -Delete the third partition: -``` -d -3 -``` - -Create a new primary partition and use default sizes prompted. This will then create a partition that fills the disk. -``` -n -p -3 -enter -enter -``` -Save and exit fdisk: -``` -w -``` - -Now reboot (`reboot`). Once rebooted: -``` -resize2fs /dev/mmcblk0p3 -``` - -That's it, now you are using all the disk space available. -This has been tested on the Raspberry Pi 2 only. - -## Just get the binaries - -Alternativly, you can use the linux system of your choice and and get the arm binaries here: -* https://build.ethdev.com/builds/ARM%20Go%20develop%20branch/geth-ARM-latest.tar.bz2 (go) -* \ (cpp-ethereum) - -## Build it yourself -If you want to build all that yourself, you can do so following those instructions: - -We start with a ArchLinux system with 2 GB swap. Instructions on how to get there can be found here: -http://archlinuxarm.org/forum/viewtopic.php?f=60&t=8366 - -### go-ethereum -[Installation instructions for ARM](https://github.com/ethereum/go-ethereum/wiki/Installation-Instructions-for-ARM) - -### cpp-ethereum -First we install all necessary libaries as described here https://github.com/ethereum/cpp-ethereum/wiki/Building-on-ArchLinux (but without the qt libs): - -These are the required packages from the official repositories: -``` -sudo pacman -Sy -sudo pacman -S base-devel cmake scons clang llvm boost leveldb crypto++ jsoncpp -``` - -These are packages that you can get from the [AUR(Arch User Repositories)](https://aur.archlinux.org/). I would suggest using [yaourt](https://wiki.archlinux.org/index.php/yaourt) or any other of the [AUR helpers](https://wiki.archlinux.org/index.php/AUR_helpers). - -``` -yaourt -S argtable libjson-rpc-cpp -``` - -Yaourt can be installed by doing this: - -``` -curl -O https://aur.archlinux.org/packages/pa/package-query/package-query.tar.gz -tar -xvzf package-query.tar.gz -cd package-query -makepkg -si - -cd .. -curl -O https://aur.archlinux.org/packages/ya/yaourt/yaourt.tar.gz -tar -xvzf yaourt.tar.gz -cd yaourt -makepkg -si -``` -#### Building the client - -The instructions for building the client from here and on are identical with Ubuntu so the reader should refer to the [relevant page](https://github.com/ethereum/cpp-ethereum/wiki/Building-on-Ubuntu#choose-your-source). but use `cmake .. -DBUNDLE=minimal -DETHASHCL=0 -DEVMJIT=0` instead. - -Resources: - -http://archlinuxarm.org/forum/viewtopic.php?f=60&t=8366 -http://archlinuxarm.org/forum/viewtopic.php?f=31&t=3119 -https://github.com/ethereum/cpp-ethereum/wiki/Building-on-ArchLinux \ No newline at end of file diff --git a/pages/infrastructure-networking/Registrar-ABI.md b/pages/infrastructure-networking/Registrar-ABI.md deleted file mode 100644 index 06c577036..000000000 --- a/pages/infrastructure-networking/Registrar-ABI.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -name: Registrar ABI -category: ---- - -### Registrar - -Read-only interface that all registrars must implement - -#### Javascript -``` -var Registrar = web3.eth.contract([{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"name","outputs":[{"name":"o_name","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"owner","outputs":[{"name":"o_owner","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"content","outputs":[{"name":"o_content","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"addr","outputs":[{"name":"o_address","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"subRegistrar","outputs":[{"name":"o_subRegistrar","type":"address"}],"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"}],"name":"Changed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"addr","type":"address"}],"name":"PrimaryChanged","type":"event"}]); -``` - -#### Solidity -``` -contract Registrar{function name(address _owner)constant returns(bytes32 o_name){}function owner(bytes32 _name)constant returns(address o_owner){}function content(bytes32 _name)constant returns(bytes32 o_content){}function addr(bytes32 _name)constant returns(address o_address){}function subRegistrar(bytes32 _name)constant returns(address o_subRegistrar){}} -``` - -### GlobalRegistrar - -`GlobalRegistrar` is the main name registration object. The global registrar object on the PoC-9 testnet is at address `0xc6d9d2cd449a754c494264e1809c50e34d64562b`. - -#### Javascript -``` -var GlobalRegistrar = web3.eth.contract([{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"name","outputs":[{"name":"o_name","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"content","outputs":[{"name":"","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"addr","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"reserve","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"subRegistrar","outputs":[{"name":"o_subRegistrar","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_newOwner","type":"address"}],"name":"transfer","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_registrar","type":"address"}],"name":"setSubRegistrar","outputs":[],"type":"function"},{"constant":false,"inputs":[],"name":"Registrar","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_a","type":"address"},{"name":"_primary","type":"bool"}],"name":"setAddress","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_content","type":"bytes32"}],"name":"setContent","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"disown","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"register","outputs":[{"name":"","type":"address"}],"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"}],"name":"Changed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"addr","type":"address"}],"name":"PrimaryChanged","type":"event"}]); -``` - -#### Solidity - -``` -contract GlobalRegistrar{function name(address _owner)constant returns(bytes32 o_name){}function owner(bytes32 _name)constant returns(address ){}function content(bytes32 _name)constant returns(bytes32 ){}function addr(bytes32 _name)constant returns(address ){}function reserve(bytes32 _name){}function subRegistrar(bytes32 _name)constant returns(address o_subRegistrar){}function transfer(bytes32 _name,address _newOwner){}function setSubRegistrar(bytes32 _name,address _registrar){}function Registrar(){}function setAddress(bytes32 _name,address _a,bool _primary){}function setContent(bytes32 _name,bytes32 _content){}function disown(bytes32 _name){}function register(bytes32 _name)constant returns(address ){}} -``` - -### OwnedRegistrar - -OwnedRegistrar fill the same interface as Registrar but allows a single owner complete authority over its contents. - -#### Javascript - -``` -var OwnedRegistrar = web3.eth.contract([{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"name","outputs":[{"name":"o_name","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"owner","outputs":[{"name":"o_owner","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"getAddress","outputs":[{"name":"o_owner","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"content","outputs":[{"name":"","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"addr","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"subRegistrar","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"getName","outputs":[{"name":"o_name","type":"bytes32"}],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_registrar","type":"address"}],"name":"setSubRegistrar","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"record","outputs":[{"name":"o_primary","type":"address"},{"name":"o_subRegistrar","type":"address"},{"name":"o_content","type":"bytes32"}],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_a","type":"address"},{"name":"_primary","type":"bool"}],"name":"setAddress","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_content","type":"bytes32"}],"name":"setContent","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"disown","outputs":[],"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"}],"name":"Changed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"addr","type":"address"}],"name":"PrimaryChanged","type":"event"}]); -``` - -#### Solidity -``` -contract OwnedRegistrar{function name(address _owner)constant returns(bytes32 o_name){}function owner(bytes32 _name)constant returns(address o_owner){}function getAddress(bytes32 _name)constant returns(address o_owner){}function content(bytes32 _name)constant returns(bytes32 ){}function addr(bytes32 _name)constant returns(address ){}function subRegistrar(bytes32 _name)constant returns(address ){}function getName(address _owner)constant returns(bytes32 o_name){}function setSubRegistrar(bytes32 _name,address _registrar){}function record(bytes32 _name)constant returns(address o_primary,address o_subRegistrar,bytes32 o_content){}function setAddress(bytes32 _name,address _a,bool _primary){}function setContent(bytes32 _name,bytes32 _content){}function disown(bytes32 _name){}} -``` \ No newline at end of file diff --git a/pages/infrastructure-networking/URL-Hint-Protocol.md b/pages/infrastructure-networking/URL-Hint-Protocol.md deleted file mode 100644 index 553604489..000000000 --- a/pages/infrastructure-networking/URL-Hint-Protocol.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -name: URL Hint Protocol -category: ---- - -There exists a root `Registry` contract at address 0x42 (this is the auctioning thing). There exists a contract interface, `register`, which `Registry` implements. - -Entries in `register`, when looked up (indexed by a string32 name) have several value fields, including `content` and `register`. - -`content` is the content hash which gets loaded when you enter this name into Mist/AZ. - -`register` is the address of a subregistry contract (some contract implementing `register`) which gets queried recursively. - -### Example - -- `eth://gavofyork` results in the main Registry (at 0x42) being queried for the entry `gavofyork`. The content field of this entry (a SHA3 hash of a zip file OR manifest) is used to display content (see Content section for more info). - -## URL Composition - -All URLs canonically begin `eth://` and are a number of components, each separated by a `/`. The field `register` is used to do a recursive lookup. - -So the components of `gavofyork/tools/site/contact` would comprise four components, in order: `gavofyork`, `tools`, `site`, `contact`. - -Any periods `.` before the left-most slash `/` delineate components which are specified in reverse order. - -So non-canonical forms of the above address are: - -- `tools.gavofyork/site/contact` -- `site.tools.gavofyork/contact` -- `contact.site.tools.gavofyork` - -NOTE: any periods after the leftmost `/` are treated no differently than other alphanumeric characters. - -### Example - -- `eth://gavofyork/site` results in the main Registry (at 0x42) being queried for the entry `gavofyork`. The register field of this entry (an address of a `register`-implementing contract) is then queried for the entry `site`. The `content` field of this entry is used to display content. - -# Content - -Normally Swarm would be used to determine the content from the content hash. - -For 1.0, this will not be possible, so we will fall back to using HTTP distribution. To enable this we will include one or many URLHint contracts, which provide hints of URLs that allow downloading of particular content hashes. Find the contract in dapp-bin. - -The content downloaded should be treated in many ways (and hashed) to discover what the content is. Possible ways include base 64 encoding, hex encoding and raw, and any content-cropping needed (e.g. a HTML page should have everything up to body tags removed). - -It will be up to the dapp/content uploader to keep URLHint entries updated. - -The address of the URLHint contract will be specified on an ad-hoc basis and users will be able to enter additional ones into their browser. - diff --git a/pages/introduction/Decentralized-apps-(dapps).md b/pages/introduction/Decentralized-apps-(dapps).md deleted file mode 100644 index 1dbed731b..000000000 --- a/pages/introduction/Decentralized-apps-(dapps).md +++ /dev/null @@ -1,83 +0,0 @@ -Any good, service, governance or economic activity can be decentralized and tokenized with and transacted via Ethereum. The token represents the dapp (an abbreviation for decentralized app) while it uses the Ethereum blockchain, but the price of the token is different. Activity that has any economic or governance aspect, conceived or as of yet inconceived, can be done via Ethereum, provided that the right code is written and the necessary hardware is used (such as computers running an Ethereum node, and in some special cases, a measurement device to measure a resource flow for additional verification/auditable purposes, like a meter for electricity ⚡🔌, water 🚰 or gas 🔥; or a waste 🗑️ volume detector). Here's a challenge: keep an eye out for activity that has not been implemented on Ethereum (or could be implemented in a better way; check this article and research to check whether it's implementeId and if so, how well) and then: -
    -
  • develop a dapp for the idea yourself (after learning Solidity, if you don't already know it); or
  • -
  • sign an NDA with someone who is interested in developing dapps, share the idea, and form some agreement if they want to proceed with it (which could be proposed in the NDA itself), e.g. a founder's stake in an ICO, a salary, equity in the venture (although a community model more like Ethereum's non-profit foundation is better for a more equitable solution), royalties, a fee for every transaction, etc.
  • -
- -This platform aspect of Ethereum has been referred to as a 'fat protocol' here, as opposed to the 'thin protocols' of Web 1.0 and 2.0 with HTTP, SMTP, etc., with the take home point (in bold) being: -
the market cap of the protocol always grows faster than the combined value of the applications built on top, since the success of the application layer drives further speculation at the protocol layer.
-One kind of application that is particularly intriguing is decentralized autononous organisations (DAOs, this includes entities as large as, or even larger than nation-states 🇦🇺🇺🇸🇮🇳🇬🇧🇨🇳🇧🇷🇷🇺🇯🇵, social networks, multinational public companies, etc.). Note that having complete autonomy is probably not a good idea, since code may not be able to handle new issues that arise, so human intervention should probably always be an option, but preferably in the hands of a small, non-profit entity or some decentralized solution (perhaps similar to the Aragon Network). By analogy, you wouldn't want a nuclear power plant to be completely automated with no possible means of human intervention. As a precaution, you'd want several safeguards including, for example, an off button 😉. As explained in this Ethereum Wiki here, the first DAO, known as The DAO, resulted in many funds being stolen, and Ethereum hard forking into Ethereum and Ethereum Classic. - -The following list is sourced from [Coin Market Cap tokens (you can sort by market cap)](https://coinmarketcap.com/tokens/) and State of the Dapps, both of which lists many more, as well as elsewhere, e.g. Gitter research room chats. (There are 854 dapps on State of the Dapps as of Dec 1 2017; then [909 on Jan 1 2018] (https://web.archive.org/web/20180101114436/https://www.stateofthedapps.com/). 😯 You can search by tags.) Other examples are also presented e.g. on day 4 of [Devcon 3](http://www.ryanyosua.me/devcon-3-talks/), as well as outlined in the Ethereum whitepaper in the introduction and applications section. Note also that while most of the dapps in the following list run on the Ethereum platform, some examples do not, and where they don't run on Ethereum, it is generally noted as what they do run on. This is not a big deal, as any dapp could theoretically run on another blockchain, (or indirectly via inter-blockchains like Cosmos or Polkadot) provided that the host blockchain has the required features. Also note that the below list is not an endorsement, and is not exhaustive or necessarily well-maintained. At worst, it's included because it was briefly looked into and it seemed like a good idea, while more time may have been spent doing due diligence on some ideas and can therefore have a better idea of its usefulness. Dapps that have been implemented, or are under development, or have been publicly conceptualised, includes: -* a stable coin, e.g. [Dai](https://makerdao.com/whitepaper/DaiDec17WP.pdf) -* smart contracts for the legally enforceable and/or liquid transfer of assets, plus related services e.g. [Mattereum](https://mattereum.com/) and [Sweetbridge](https://sweetbridge.com), e.g. settlement, accounting, risk management, resource sharing, and Optimization & Liquid Talent. Also, asset-based lending: secure loans with holding of assets e.g cryptocurrenices (locking them up) in exchange for cash (fiat currencies), such as Sweetbridge and [SALT](https://coinmarketcap.com/currencies/salt/); -* [Veritaseum](http://veritas.veritaseum.com/), which "enables software-driven P2P capital markets without brokerages, banks and traditional exchanges". -* [invoice financing with Populous](https://populous.co/) -* decentralized exchanges to buy and sell cryptos and fiat, e.g. localethereum; for cryptos only there is DecentrexOmega One and NVO, where the latter two have not been launched as of November 30. -* non-decentralized exchanges such as [Coinbase](https://www.coinbase.com/) (US), [BTCmarkets](https://btcmarkets.net/) (Australia), while more are below, or ones that only exchange cryptocurrencies like Poloniex; -* other exchanges like [OmiseGo](https://omisego.network/). "OmiseGO is a public Ethereum-based financial technology for use in mainstream digital wallets, that enables real-time, peer-to-peer value exchange and payment services agnostically across jurisdictions and organizational silos, and across both fiat money and decentralized currencies. Designed to enable financial inclusion and disrupt existing institutions, access will be made available to everyone via the OmiseGO network and digital wallet framework."; -* exchange platforms like [Binance](https://www.binance.com/aboutUs.html); -* asset exchanges like [WAX](https://wax.io/). -* the Brave browser (which the author uses) which uses the Basic Attention Token, which provides a better solution for users, publishers and advertisers; -* [MaidSafe](https://maidsafe.net/), which has another browser that actually runs on the [Omni](http://www.omnilayer.org/) layer that runs on Bitcoin, not Ethereum. It is also claiming to be: "The World's First Autonomous Data Network". [Currently you have to receive an invite which requires roughly an hour of interaction on their Discourse forum/site.](https://web.archive.org/web/20171230003420/https://invite.maidsafe.net/) -* [ZeroNet](https://zeronet.io/), another decentralized internet network that runs on Bitcoin cryptography and the [BitTorrent network](http://www.bittorrent.com/). [It on Ubuntu 17.10](http://127.0.0.1:43110/Talk.ZeroNetwork.bit/?Topic:1514631579_13fVMZu2wTNAykEvkYHYfGmTBMSFxz9gFG/It+would+be+good+if+you+could+link+to+a+comment). You can make [your own site](http://127.0.0.1:43110/1zz1z8YPFQizJshGkgHq7GVtBSPCyQM5W/), although [you may have issues with following a tutorial](http://127.0.0.1:43110/Blog.ZeroNetwork.bit/?Post:99:ZeroChat+tutorial#comment_1_13fVMZu2wTNAykEvkYHYfGmTBMSFxz9gFG). Note that this link won't work unless you are running ZeroNet.sh) by clicking the download button on the homepage (then as detailed concisely below the button) extracting it and running (in bash) `./ZeroNet.sh` while `cd`ed to the extracted folder that ZeroNet.sh is located in. -* storage, e.g. Swarm and a distributed hypermedia protocol, IPFS [website](https://ipfs.io/), [doc](https://github.com/ipfs/ipfs); -* communication protocols, e.g. Whisper (also see here for code), which allows dapps (you don't need to capitalize this since it is an abbreviation of decentralized applications) to communicate with each other; -* multi-chain networks/tools like [Polkadot](https://polkadot.io/) and [BTCRelay](http://btcrelay.org/) -* Ethereum Name Service (names like jamesray.eth map to an address); -* mesh networking e.g. implemented here and as voted for here on Twitter (which also has other ideas posted in the comments); -* social networks e.g. Akasha (news here), -* Status: "A Mobile Ethereum OS: Browse, chat and make payments securely on the decentralized web."; -* decentralized search engines, e.g. Weipoint (a news post is here); -* reputation and ratings network e.g. as used by [Etheal](https://etheal.com/), which is described below (CTRL+F); -* identity (e.g. as provided by uPort, as well as [in-blockchain proposal](https://www.ethnews.com/erc725-a-self-sovereign-identity-standard-for-ethereum and [Shyft](https://www.shyft.network/)); -* decentralized electricity trading and other decentralized energy economic applications, which would allow renewable energy to be more economical and accelerate the transition to a clean, renewable energy and safe climate future. - -Sun on Twitter Twemoji 2.3Wind Face on Twitter Twemoji 2.3Deciduous Tree on Twitter Twemoji 2.3Water Wave on Twitter Twemoji 2.3 - -Examples of local electricity trading include: Grid+, LO3/Transactive Grid, Power Ledger, Nexergy, Local Volts and Divvi. Grid+ uses Ethereum and they have open source code. Power Ledger has closed source code and runs on the Ethereum Enterprise Alliance, rather than the public Ethereum blockchain. They had a token sale in early October. Both Power Ledger and Grid+ also detail more unique applications in their pipeline, such as renewable energy asset generation (Power Ledger) and Grid+'s in-home computer, an "intelligent agent" that pays for a customers electricity in real-time, using stable tokens, stores cryptocurrency like the hardware wallet functions of Ledger and Trezor; providing Casper proof-of-stake signing, and provide an Ethereum API for IoT ([pp. 26 and 34-36, white paper](https://drive.google.com/file/d/0Bz90riPGRHquNDVXVE81RmppaUk/view)). Transactive Grid uses Ethereum and it has been rolled out in Brooklyn with a microgrid, however LO3 hasn't released any code or details for its Transactive Grid application. The others are still all under development (as of August 2017), and they have been scant on the details of how they would implement their application, at the least not releasing their code. Divvi say on its website that they will use the blockchain. Local Volts and Nexergy do not. -* electricity tokenization: e.g. SolarCoin, EnergyCoin, although both are altcoins rather than Ethereum tokens; -* governance of any organisation, e.g. Democracy.Earth; and also governance of DAOs, e.g. Aragon; -* decentralized search engines like [BitClave](https://www.bitclave.com/en/), [Weipoint](https://www.weipoint.com/) and [Epocum](https://www.stateofthedapps.com/dapps/epocum); -* wallets like MyEtherWallet or hardware wallets Trezor or Ledger; -* blockchain explorers like [Etherscan](https://etherscan.io/); -* a gateway to decentralized services such as [Infura](https://infura.io/); -* visit dapps in your browser with [Metamask](https://metamask.io/); -* decentralized media; -* asset titles (such as land titles). Read more on that here: "Having so far built the software and tested it with a couple dozen land title registrations, Bitfury and the Georgian National Agency of Public Registry have now signed a new memorandum of understanding to expand the service to purchases and sales of land titles, registration of new land titles, demolition of property, mortgages and rentals, as well as notary services". Nottar.io also provides notary services. A similar, more specific application is for academic certificates with [Smart Diploma](https://www.stateofthedapps.com/dapps/smart-diploma); -* Debit card 💳 transactions 🤝 (done on several exchanges 💱, e.g. Coinjar Swipe (but it accepts BTC only), Coinbase, while others which I've mentioned elsewhere in this article have plans to do this e.g. [OmiseGO](https://www.omise.co/go); -* co-ownership of real assets e.g. the [Swarm Fund](https://www.swarm.fund/how-swarm-works/index.html) -* crowdsales, e.g. an Initial Coin Offering (ICO) as compared with an Intial Public Offering (IPO), or for tokens with Ethereum: an Initial Token Offering (ITO). Note that this is not so much a business model in itself, per se, rather it is more of a fundraising method (which has also led to scams, e.g. here); -* crowd development (but not as part of the blockchain, e.g. here), e.g. for infrastructure and other public assets; -* think of public companies being remodelled into communities with tokens instead of shares, governance using a platform like Democracy.Earth (which can be tailored to have voting anywhere between one vote one person like direct democracy, or conventionally more hierarchical like a board of directors and token-holders instead of or in addition to—and probably eventually superceding—shareholders); -* dividend payouts and secure email-based transactions with [Dividend](https://www.dividend.cloud/). For sending ETH via email there is also [You've Got ETH](https://www.stateofthedapps.com/dapps/you-ve-got-eth); -* prediction 🔮 🦉 markets like GNOSIS, Augur and [WINGS DAO](https://www.stateofthedapps.com/dapps/wings-dao); -* [Built-in price discovery and a liquidity mechanism for tokens with Bancor](https://www.bancor.network/); -* labour/recruitment/freelance markets like Chronobank and [Ethlance](https://ethlance.com/); -* permissioned distributed ledgers like [Hydrachain](http://www.brainbot.com/projects#hydrachain); -* trust-based models like the [Trustlines Network](http://trustlines.network/) -* Secure distributed computing, e.g. Golem. Ethereum needs to be faster e.g. with EWASM and parallelizability. -* accountability, e.g. for non-profits (e.g. "how do I know how badly you need a donation unless I can see your net liabilities, net assets, and balance sheet, and how you plan to use the funds?") and aid (also see here) -* Self Learning, Autonomous, Decentralized Artificial Intelligence (this could be used for many things such as self-driving cars, robots, or anything else that is owned by a contract; bots; and art); -* decentralised financial services like [WeTrust](https://www.wetrust.io); -* futures-like dapps such as [TimeBank](https://www.stateofthedapps.com/dapps/timebank) and [hodlethereum](https://hodlethereum.com/); -* sharing car refueling stations with [Share&Charge](https://www.stateofthedapps.com/dapps/share-charge); -* health, e.g. [Etheal](https://etheal.com/), a healthcare service comparison site with a content platform, trust and review / reputation system; an anonymous marketing platform for surveys, ads and communication research where users are paid by pharmaceutical companies; and a platform for building health apps; -* examples of contracts are [here](https://solidity.readthedocs.io/en/develop/solidity-by-example.html) and [here](https://viper.readthedocs.io/en/latest/viper-by-example.html), e.g. voting, auctions (open or blind), safe remote purchases, micropayment channels, crowdfunding and company stock. Many more can be found on Github, which may be referenced from the whitepaper and the website of a dapp. -* [insurance](https://www.stateofthedapps.com/tagged/insurance/); - - -Examples that have been conceptualized, but not implemented (at least as far as the creator of this wiki is aware of) include: -* reducing transaction costs for existing business models (here is a good read about that). However, to tokenize online centric business models, the network model should change from client-server to peer-to-peer, to avoid a conflict of interest. This is more difficult to achieve since a server is a piece of infrastructure, and transferring to a peer-to-peer model would cause it to be a sunk cost. Additionally, it may be difficult to build a replacement dapp for a successful website, because it is hard to get a network of engaged users to change to using something else (inertia). Centralized web apps (not just mobile apps but websites, and use the word to contrast with dapps) include: -* * Google (although note [Weipoint](https://www.weipoint.com/) as mentioned previously), -* * social networks like [Facebook](http://www.trustnodes.com/2018/01/04/zuckerberg-studying-cryptocurrency-implementation-facebook), Twitter, (although note [Akasha](https://akasha.world/) above); -* * online marketplaces e.g. Amazon, eBay and Alibaba (decentralized alternatives include [Soma for products or services](https://soma.co/), [Canya for services](https://canya.io/) also note this simple implementation and subreddit [here](https://www.reddit.com/r/ethmarket/), as well as more specific or niche marketplaces like [Cryptokitties](https://www.cryptokitties.co/), [Hamster](https://hmstr.io/)). For more info see [here](https://www.forbes.com/sites/rogeraitken/2017/10/24/whats-the-future-of-online-marketplaces-blockchains-technology-impact/#3f6bde2a63a0) -* making economically viable other business models that have seen low uptake or aren't economically viable without blockchain tech. So-called sharing economy business models (which are more aptly called tasker or rentier capitalism models) like Airbnb, Uber, AirTasker, Fiverr, Upwork, TaskRabbit, and Menulog are particularly ripe for transformation (the term transformation is preferrable to disruption, since it should be a net positive change, while negative effects are manageable or solvable), since no trusted third party for a transaction is needed, such as banks 🏦, credit card 💳 companies or PayPal, just a smart contract; and -* mortgage brokers; -* More examples are here—scroll to the examples—they have bold headings and are about two thirds of the way down, or search for "Dank meme trading". Note that the Basic Attention Token has already been mentioned, and the creator of this wiki is skeptical that AI will create truly beautiful art, since no AI can have any feeling. CryptoKitties is an example of meme trading and has taken up [a lot of the transactions on the Ethereum network](https://etherscan.io/address/0x06012c8cf97bead5deae237070f9587f8e7a266d). -* curation markets, which is part of what [Steemit](https://steemit.com/@jamesray/feed) does (which runs on the STEEM network), and which curators, social networks and wiki authors would all benefit from. More info is [here](https://medium.com/@simondlr/introducing-curation-markets-trade-popularity-of-memes-information-with-code-70bf6fed9881); -* [P2P Decentralised Autonomous Transportation Network](http://www.flyingcarpet.network/) -* [Waste collection management](https://twitter.com/JamesCRay01/status/936992945173020672). Other ideas include plus generally thinking of existing business models running on the blockchain, like real estate developers and investment trusts (with which blockchains could be used e.g. for crowdfunding). -* legally enforceable wills running on the blockchain, as well as being able to appoint an executor in a legally enforceable way on the blockchain. - -More examples are e.g. [here in a blog post](https://medium.com/@Ethereum_AI/ethereum-introduction-what-exactly-is-it-why-care-how-to-invest-9a627ab04408) and [here on Wikipedia](https://github.com/Ethereum-community/Ethereum-introduction/wiki/Decentralised-apps-(dapps)) diff --git a/pages/introduction/Ethereum-introduction.md b/pages/introduction/Ethereum-introduction.md deleted file mode 100644 index 8d6a862fb..000000000 --- a/pages/introduction/Ethereum-introduction.md +++ /dev/null @@ -1,277 +0,0 @@ -![Ethereum Homestead gold ingots](https://sustergy.files.wordpress.com/2017/05/ethereum-homestead-background-17.jpg?w=1000) - -Note that due to the lightning-fast pace of development in the Ethereum space with core development and dapps continually being launched, certain parts of this article may be outdated. You can help by keeping it up to date! - - - -Table of Contents -================= - - * [Table of Contents](#table-of-contents) - * [About Ethereum](#about-ethereum) - * [Uses](#uses) - * [List of dapps](#list-of-dapps) - * [Market analysis](#market-analysis) - * [Issues](#issues) - * [Scalability](#scalability) - * [Proof of work / proof of stake / other proving methods](#proof-of-work--proof-of-stake--other-proving-methods) - * [Public permissionless blockchains vs. private permissioned blockchains](#public-permissionless-blockchains-vs-private-permissioned-blockchains) - * [No technological artefacts can be a panacea](#no-technological-artefacts-can-be-a-panacea) - * [How do you buy and sell Ether, the currency of Ethereum?](#how-do-you-buy-and-sell-ether-the-currency-of-ethereum) - * [Table of exchanges](#table-of-exchanges) - * [More details about what I've tried (not very necessary to know)](#more-details-about-what-ive-tried-not-very-necessary-to-know) - * [Development](#development) - * [Concluding remarks](#concluding-remarks) - * [Further reading](#further-reading) - -# About Ethereum -Ethereum is a [decentralized](https://medium.com/@VitalikButerin/the-meaning-of-decentralization-a0c92b76a274) blockchain platform for "building unstoppable applications", while Ether is the cryptocurrency used on this platform. Ethereum has been described in several ways, such as (the first and third resources are more general introductions, while the second is a technical introduction, although all are outdated. -Another introduction is available [here](https://bitsonblocks.net/2016/10/02/a-gentle-introduction-to-ethereum/), but again, it is outdated. Despite being outdated, Ethereum has maintained backwards compatibility thus far up till January 1 2018, so the info is still relevant.): - -Let's briefly breakdown what those terms mean. - -**Decentralized** technology uses [peer-to-peer computer networks](https://en.wikipedia.org/wiki/Peer-to-peer) (there's a picture below), and are not subject to the whims of a central authority such as a government or server administrator (like Google or Facebook) which can help to achieve better decision making for public good. **Blockchain** means that the currency is built and secured by adding and verifying blocks of transactions to blocks made previously, thus forming a "chain". Blocks added to the chain become harder and harder to crack over time, as they are verified by more nodes in the blockchain peer-to-peer network. Blockchain technology has been referred to as the **Web 3.0**. The world wide web (retroactively the Web 1.0) consisted of websites publishing content and users passively reading/viewing it. The Web 2.0 used user interaction, such as forums (with upvoting and commenting), reaction buttons (e.g. the Facebook reactions: likes 👍, love ❤️ , laughter 😆, wow 😲, sad 😢, angry 😠), sharing (republishing), however these interactions have no direct economic effect on the host website; users do not share in the value generated from the website. The Web 3.0 is starting to be defined as the movement away from centralisation of computation power in servers which provide services to clients (known as the client-server network model) to peer-to-peer networks and blockchains, and from centralisation of authority and sovereignty from nation-states and corporations to the networked individual. - -![server-based-network](https://sustergy.files.wordpress.com/2017/05/200px-server-based-network-svg.png) -![p2p-network](https://sustergy.files.wordpress.com/2017/05/200px-p2p-network-svg.png) - -**Cryptocurrency** refers to a a digital currency that secures transactions with cryptographic code, which is solved through hardware computational power (known as mining or proof of work) or other less energy-intensive ways such as proof-of-stake. (There are more details on that below.) - -Zero knowledge proofs like ZK SNARKs can also be used to make cryptocurrency transactions more private 🕵️ or secret 🤐 (which is different to being secure 🔒), thus negating the need to run applications on a permissioned private network like the [Ethereum Enterprise Alliance](https://entethalliance.org/). Ethereum uses [precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128](https://github.com/ethereum/EIPs/pull/213), for [pairing checks](https://github.com/ethereum/EIPs/pull/212), which permit [zk-SNARKs](https://blog.ethereum.org/2017/10/12/byzantium-hf-announcement/), also see [here](https://medium.com/@VitalikButerin/zk-snarks-under-the-hood-b33151a013f6), [as implemented](https://github.com/ethereum/EIPs#finalized-eips-standards-that-have-been-adopted) in the [Byzantium hard fork](https://blog.ethereum.org/2017/10/12/byzantium-hf-announcement/). There is also the Zerocoin protocol which is demonstrated by Zcoin (which plans to integrate Ethereum). - -# Uses -The platform part of Ethereum makes it much more useful than just a cryptocurrency. With it, you can create any decentralized application (known as a dapp, which works over a peer-to- peer network rather than a centralized client-server network 💻🕸️), so the functionality is only limited by what programs could potentially do and not do, and by consequence, what programmers develop, 👨‍💻 but it can theoretically be used for any economic or governance activity. - -## List of dapps - -For a list of dapps, visit [here](https://github.com/Ethereum-community/Ethereum-introduction/wiki/Decentralised-apps-(dapps)). - - -*** - - -However, there are several issues that will need to be resolved to help Ethereum be used to its full potential, which are described below. - -## Market analysis -As of the 1st of December 2017, [the market capitalisation of Ethereum is $32.6 billion USD](https://cryptolization.com/ethereum) (refer to the link for the latest figure), and [it has been in circulation possibly since 30 July 2015](https://github.com/jamesray1/homestead-guide/blob/32d2fa4ccfa3d45f8493a673a08247450d55fea0/source/introduction/the-homestead-release.rst#milestones-of-the-ethereum-development-roadmap), with the [first transaction using Ethereum on 8 August 2015](https://www.etherchain.org/account/0x5abfec25f74cd88437631a7731906932776356f9). Compare this with the next largest and the current largest cryptocurrency, [Bitcoin, with a market cap of $41.0 b. US](https://cryptolization.com/ethereum), where [it has been in circulation since January 2009](http://www.newyorker.com/reporting/2011/10/10/111010fa_fact_davis). Technically, Ethereum has had a much faster growth rate, while more importantly for long term investment (I do not encourage speculation as that only causes volatility as has been seen) the fundamentals are much better than Bitcoin. While it is true that Bitcoin has more of a market and currency, e.g. in terms of more entities that will accept it as a form of payment, the creator of this wiki expects that time will change that (indeed the market cap of Ethereum recently surpassed half that of Bitcoin, around May 2017). Also, [the number of transactions of Ethereum surpassed that of several cryptocurrencies combined on 22 Nov 2017](https://www.reddit.com/r/ethereum/comments/7est9k/ethereum_is_now_processing_more_transactions_a/). However, note [this retort](https://www.reddit.com/r/ethereum/comments/7est9k/ethereum_is_now_processing_more_transactions_a/dq7a31u/). - -# Issues -There also several issues with Ethereum, such as not being scalable enough, not being full decentralized, energy consumption with mining, if quantum computing advances it would be insecure (but this is being fixed). With its [large storage database](https://www.reddit.com/r/ethtrader/comments/7axn5g/ethereum_blockchain_sizewe_have_a_problem/) (I have to provide a [Reddit link](https://www.reddit.com/r/ethtrader/comments/7axn5g/ethereum_blockchain_sizewe_have_a_problem/) as a source as the [original link](https://etherscan.io/chart/chaindatasizefull) doesn't have the graph any more, while [Wayback doesn't render it either](https://web.archive.org/web/20171211015955/https://etherscan.io/chart/chaindatasizefull).), mining and architecture requiring to run a full node to mine or validate transactions, it is not decentralized enough. More (outdated but still applicable) info on that is e.g. [here](https://ethereum.stackexchange.com/questions/143/what-are-the-ethereum-disk-space-needs#826), as well as [here](https://github.com/ethereum/go-ethereum#full-node-on-the-main-ethereum-network). - -## Scalability - -Ethereum will need to scale to process far more transactions per second (to become a "world computer") than Visa, Mastercard and American Express combined (which process on the order of [tens of thousands of transactions per second](https://usa.visa.com/run-your-business/small-business-tools/retail.html) [in the link, CTRL+F 24,000]), while Ethereum 1.0, the current version as of December 30 2017, processed [a record of 1103523 transactions on Friday, December 22, 2017, or 12.77 transactions per second](https://web.archive.org/web/20171230005127/https://etherscan.io/chart/tx). - -Note that [Ripple claims that it's Consensus Ledger can process a thousand transactions per second](https://ripple.com/dev-blog/ripple-consensus-ledger-can-sustain-1000-transactions-per-second/), while it could process more with payment channels. "Although payment channels achieve practically infinite scalability by decoupling payment from settlement, they do so without incurring the risk typically associated with delayed settlement." Further note that Ripple achieves this by trading off on decentralization, through a [distributed network of validators or distributed servers](https://ripple.com/build/xrp-ledger-consensus-process/), while it has been described as a [federation protocol](https://wiki.ripple.com/Federation_protocol). - -There are even more scalable blockchains that use a delegated proof of stake (DPOS) consensus protocol, such as Bitshares and Steem. [Bitshares can apparently process 100,000 TPS](https://bitshares.org/technology/industrial-performance-and-scalability/). - -More generally, in order to have faster payments or higher transaction throughput, you need to reduce the number of validators (miners are a kind of validator that perform energy intensive computational work, finding a random nonce or sequence number in a large set of numbers) in the consensus protocol, or reduce the other (i.e. for faster payments you can reduce transaction throughput or reduce validators, while for higher transaction throughput you can reduce validators or have payments take longer to finalize). This is [a trade-off triangle](https://twitter.com/VladZamfir/status/932319930363494400). You could potentially have one blockchain with [heterogeneous sharding](https://twitter.com/VladZamfir/status/932320997021171712), with different shards with a different degree of balance between these properties. Ethereum is working on [sharding](https://github.com/ethereum/sharding/blob/develop/docs/doc.md), which includes using [stateless clients](https://github.com/ethereum/sharding/blob/develop/docs/doc.md#stateless-clients) (while more on that is [here](https://ethresear.ch/t/the-stateless-client-concept/172/14)). - -If you increase scalability in an instant via some blockchain or shard, while keeping latency constant (or reducing it) you need to reduce decentralization, which reduces the number of points of attack needed to compromise the whole network, i.e. reducing decentralization reduces security. - -## Proof of work / proof of stake / other proving methods -The mining process to crack cryptographic code (specifically to discover the nonce, a very large number, for each block by trial and error) requires a lot of computation power. Nevertheless, I'm guessing that the computation power should be less when you consider the energy consumption of incumbent financial systems. (Think of extracting and processing resources to make coins and notes, minting and printing, energy consumption of banks and tiers of related energy consumption in the life cycle of fiat money.) Still, developers of some cryptocurrencies such as Ethereum are transitioning to (as is the case for Ethereum), or already using, a different way of maintaining and creating blocks, known as proof of stake. For more information, you can see this Proof of Stake Wikipedia article here (although note the header warning about the article potentially not being verifiable or neutral due to relying heavily on sources too closely associated to the subject). The tricky part is in getting proof methods to work better than proof of work, as outlined here in the criticism section of the PoS Wiki. - -## No technological artefacts can be a panacea -For the continual improvement of humanity, there needs to be balance in life between things that benefit us materially and things that benefit us on higher levels, particularly spiritually. There is a risk that technology can make some people better off, and others worse off. So there needs to be consideration for how technology can be implemented to maximise [utility](https://en.wikipedia.org/wiki/Utilitarianism). One consideration of that is [here](https://medium.com/@RhysLindmark/co-evolving-the-phase-shift-to-cryptocapitalism-by-founding-the-ethereum-commons-co-op-f4771e5f0c83). - -## There's a risk of attacks from quantum computing, if it becomes performant enough - - - -# How do you buy and sell Ether, the currency of Ethereum? - -Summary: compare deals with buying and sell through different exchanges such as P2P ones with an arbitrator like [**LocalEthereum**](https://localethereum.com), or with centralized exchanges (which vary with your local jurisdiction, e.g. in Australia there is [BTCmarkets](https://btcmarkets.net/fees) and in the US plus worldwide there is [Coinbase](https://www.coinbase.com), which also allows you to spend cryptocurrencies e.g. with a debit card. For more see the table below, [here](https://github.com/jamesray1/Ethereum-introduction/wiki/Ethereum-introduction#table-of-exchanges)). - -The simplest way may be to use [**LocalEthereum**](https://localethereum.com), where you don't need to go through KYC processes. The creator of this wiki has found that "I can **sell Ether for a better deal** than I can find with an exchange, without any trading or withdrawal fees, apart from those associated with different payment methods". I like that it has lower fees compared to exchanges. I also read about how the localethereum platform works, and it seems pretty secure. The maker fee (which is what the party of the trade that puts up the offer) is 0.25% while the taker fee is 0.75%. [BTCmarkets](https://btcmarkets.net/fees) has higher fees compared to the maker fee, and higher than the taker fee if the amount is below $3000. Additionally, there have been hacks with exchanges like Mt. Gox and Bithumb. That's harder to achieve with localethereum since they can't get access to your funds, they can only settle disputes (if they arise) by sending the funds in the escrow to the buyer or the seller. However, I have been able to find a **better deal**, at least at certain times, with buying Ether if I buy through [**BTCmarkets**](https://btcmarkets.net/fees), although that would be slower via BPAY with bank transfer than paying via cash deposit via an ATM or bank." - -More information about Ether is [here](http://ethdocs.org/en/latest/ether.html). - -Disclaimer from the creator of this wiki: I have put most of my funds in Ether, the currency of Ethereum. Does that shock you? 😲 Yep, it's risky, but I've done due diligence 🔍 with fundamental analysis, and a little bit of sentiment and technical analysis, and I think that the market cap of Ether will continue to grow 🌱🌳 and increase, albeit with some volatility 📈. I consider it a digital currency that is in a pioneering, rapid growth stage of development (fuelled by a lot of genuine uptake of the currency as well as speculation about its future value, if not its current value), not just an asset. I hope my post will outline why investing in Ether is a good idea (and not just investing a small percentage of your cash, unless you are tied up with a mortgage 🏠 or have other monetary or non-monetary ties or circumstances that limit your investable capital). However, if you don't want to risk the downside volatility, e.g. if you don't have any risk capital, then you may want to consider buying a stable coin like [Dai Coin](https://makerdao.com/) instead. - -Based on my research below, if you're in Australia 🇦🇺 (otherwise skip to the next paragraph), I recommend creating an account with BTCmarkets.net, verifying your ID, and using BPAY or PoliPayments to deposit AUD. Note that the rest of the following info in this paragraph is outdated since MEBank used to not support BPAY publicly, but now they do. If your bank doesn't support PoliPayments and you want to use that instead of BPAY, although I can't think of any good reason why you'd want to use PoliPayments over BPAY, then you can set up a bank account with BOQ (or any other bank that supports POLi Payments, doesn't invest in fossil fuels and has no fees for transaction and savings accounts [note that Bendigo doesn't have an Ultimate Everyday account any more]. You can probably ignore the interest rate since it is so marginal compared to other bank's rates and the gains that you are likely to make by holding funds with Ether instead. However, when I did research for interest rates I found that ME Bank savings rates were second only to UBank, which invests in fossil fuels indirectly as it is owned by NAB. - -## Table of exchanges - -You can use [localethereum](https://localethereum.com) anywhere, but in my experience you may not get as good a deal as buying it on a local exchange. - -If you're not in Australia 🇦🇺, then here's a comparison of exchange rates 💱 for fiat to crypto- and crypto- to crypto- currencies (note that there is still a focus on Australia, but you can click on the links to get more information of the fees): - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Exchange link (may go to a fees page)Fiat to crypto exchange fee buy/sell spread
BTCmarketsAUD is the only fiat currency. 0.85% trading fee. Funds available to deposit, withdraw, buy and sell are: AUD, ETH, ETC, BTC and LTC. To deposit AUD, you need to verify your account and then use POLi Payments (available banks are here. My bank is ME Bank, which doesn't support POLi Payments. I applied with BOQ because they do support POLi Payments, they don't invest in fossil fuels [like ME Bank] and they have transaction and savings accounts with no fees [like ME Bank].)
GDAX0.25/.3% maker fee low volume, 0% taker fee BTC for USD/EUR/GBP, ETH/LTC for USD/BTC/EUR
Coinjar, has a debit card with accounts for Ether, BTC, XRP and LTC.1.00% AUD/BTC (and only AUD/BTC)
CoinbaseIn Aus: 3.99% credit/debit card only (no other transaction method accepted). Other fiat and crypto currencies are available.
CEX7% BTC/ETH for USD/EUR/GBP/RUB
ice3x1% ZAR/BTC
LunoZAR/BTC fee not easy to find
okcoinCNY/USD for BTC/LTC, fee not easy to find
MaicoinTN/BTC Fee not shown, claimed none
- - - - - - - - - - - - - - - - - - - - - - - -
Crypto to crypto exchange fee / buy/sell spread
Poloniex0.15/.25% BTC/ETH “maker-taker” (presumably the same as buy-sell)
gdax.com/fees/0.25/.3% maker fee low volume, 0% taker fee ETH/LTC for BTC
Exodus~0.4720–.528% BTC/ETH variable. Desktop app. Sometimes currencies are not available for exchange!
NVODecentralised. ICO 05/27/17 02:00 UTC to 06/27/17 02:00 UTC
- -Exchanges are listed in [this article](https://medium.com/@Ethereum_AI/ethereum-introduction-what-exactly-is-it-why-care-how-to-invest-9a627ab04408), which I've copied and pasted (repetition is OK): - -**America, US dollars** - -https://www.coinbase.com - -https://gemini.com/ - -**Australian Dollar** - -https://btcmarkets.net/ - -**Canadian Dollar** - -https://www.quadrigacx.com - -**Chinese Yuan** - -https://www.huobi.com - -https://www.okcoin.com - -https://yunbi.com - -**European Euros** - -https://www.kraken.com - -**India** - -https://duckduckgo.com/?q=Ethereum+exchange+india&t=brave&ia=web - -**Mexican Peso** - -https://bitso.com - -**South Korean Won** - -https://coinone.co.kr/ - -https://www.bithumb.com/ - -## More details about what I've tried (not very necessary to know) - -I bought BTC in a different way. Step 2 worked for me. I will try step 1 next time I buy more BTC. - -I created an account on btcmarkets.net, verified my email address, tried to login, but couldn't. I tried to disable two factor authentication, but it asked for my mobile number, which I didn't enter when I created my account. I tried to reset my password and log in again, but that didn't work. I entered my email address correctly. I sent a message to support to ask for help. I figured out that my password was too long, and have notified btcmarkets.net. After creating a password of 23 characters, I was able to log in. I created another password of 56 characters using Chinese characters, emojis and ASCII characters, and was able to log in. (Incidentally, it is a hassle to do this, so a decentralised, private password generator would be wonderful.) - -The following steps are what I have tried so far, in detail. -
    -
  1. Convert AUD to Bitcoin (BTC) via an exchange like Coinjar. I left a review of Coinjar here. Fee: 1%. While this step is tailored for Australia, it can be adapted to any country that has a bitcoin exchange.
  2. -
  3. I created a Poloniex account, sent funds from got the Bitcoin deposit address, then sent my BitGo funds to that address. Once the transaction completed, I then used Poloniex Exchange to convert to Eth, with a maker-taker fee of: 0.15/0.25%.
  4. -
-Before step 2 above, I tried the following: -
    -
  1. Create an Ethereum Wallet 👛 like MyEtherWallet. Unfortunately Mist, a program being developed by Ethereum that has a browser and a wallet is still a pre-release, so it may not be very suitable for end users just yet.
  2. -
  3. Convert BTC to Ether (ETH) via a cryptocurrency exchange like Shapeshift. Use a precise transaction, make sure the amount is within the min. and max. deposit. Copy and paste the bitcoin address in Coinjar by signing in (if you aren't already) and going to Accounts > Everyday Bitcoin > View address. Put this address as the refundable address. Copy and paste the address from MyEtherWallet. Put this as the destination address. Tick the box to save the destination address for future payments. However, this didn't work.
  4. -
-I also sent an email to Coinjar to suggest that they develop functionality for purchasing Ether directly using AUD. You can do the same with the exchange of your choice. - -I have been able to deposit funds into Coinjar (needing to be less than the transaction limits) but have not been able to get Eth funds as of yet. I have also tried to create an account on BitGo, send coins from Coinjar to BitGo, and use Shapeshift with that account and still with MyEtherWallet, however that didn't work. - -I will not discuss trading (which I mean buying with the intention to sell most or all of the purchase at any future time particularly in the short term in order to realize a profit) as I am not very interested in trying to guess the short-term direction of markets (although I admit that trading helps to provide liquidity). - -# Development -Are you interested in learning to develop smart contracts with Ethereum, and maybe develop a really useful dapp and become a millionaire? - -Check out the [Ethereum website](https://www.ethereum.org/)! Then, you can [read the Solidity docs](https://solidity.readthedocs.io/en/develop/). - -If you want to help contribute to core development, there is also: -* the [Yellow Paper](https://github.com/ethereum/yellowpaper/pull/376) (make sure that you read the [EIPs](https://github.com/ethereum/EIPs) too since as of Dec 8 it is not up-to-date with the last commit on August 8, while the Constantinople EIPs were implemented in October). Instead I recommend ; -* Learn Python first, e.g. with [Learn Python the Hard Way](https://www.learnpythonthehardway.org/) (I learnt using this, it's pretty good), [Codecademy](https://www.codecademy.com/learn/learn-python), [Pydocs](https://docs.python.org/3/), [Coursera](https://www.coursera.org/courses?languages=en&query=learn+python), etc. Knowing Python is useful for [pyethereum](https://github.com/ethereum/pyethereum), which is being used as an Ethereum client, to implement Serenity and sharding, as well as [vyper](https://github.com/ethereum/Vyper), an experimental, secure smart contract programming language; -* [LLL](https://media.consensys.net/an-introduction-to-lll-for-ethereum-smart-contract-development-e26e38ea6c23) (also see [here](https://github.com/ethereum/solidity/tree/develop/liblll) and [here](https://github.com/ethereum/solidity/tree/develop/lllc)); -* [JULIA](https://solidity.readthedocs.io/en/develop/julia.html), an intermediate language for different Ethereum virtual machines; -* clients such as [Geth](https://github.com/ethereum/go-ethereum), [Parity](https://github.com/paritytech/parity) which is under [Parity Tech](https://github.com/paritytech) a separate organization to the Ethereum Foundation, [C++ Ethereum](https://github.com/ethereum/cpp-ethereum), [Pyethereum](https://github.com/ethereum/pyethereum); -* [Serenity](https://github.com/ethereum/pyethereum/tree/serenity); -* [sharding](https://github.com/ethereum/sharding/blob/develop/docs/doc.md); -* [research](https://github.com/ethereum/research) such as stateless clients, sharding, scalability improvements, Casper and more; -* [EWasM](https://github.com/ewasm); -* if you're interested in testing, see the documentation [here](https://ethereum-tests.readthedocs.io/en/latest/), as well as [the Github tests repo](https://github.com/ethereum/tests), [a Gist here (it is outdated)](https://gist.github.com/Souptacular/fd197b1fac7c6d2660b0bef27a33ed40#lll-and-evm-stack-resources), and [Gitter here](https://gitter.im/ethereum/tests) ; and -* [many other repositories](https://github.com/ethereum). - -# Concluding remarks - -Ether certainly seems like a good investment, and a good alternative to using fiat currencies, as well as an enabler for otherwise uneconomical business, due to lower transaction costs. It's more decentralized nature than central banks has advantages for trade from a local to global scale. With governance applications and systems on top Ethereum, it is even possible to do away with the hindering borders surmounted by nation-states. By doing away with these borders, society can be more open, inclusive and equitable. - -However, all technology can only help mankind and the world to a certain extent. What is more important is for each and every person to become increasingly blissful. Each person must go within and enter a stillness of body and mind, which is when that bliss starts to manifest, and practice balanced living. Practicing certain techniques such as those given by Self-Realization Fellowship, such as daily Kriya yoga meditation, developing unconditional love that starts in the heart, keeping the mind at the point between the eyebrows, and moral living, helps each person manifest that bliss within, and from there, express that bliss outwardly at all times. - -# Further reading - -* [Another introduction](https://github.com/jamesray1/Ethereum-introduction/wiki/Ethereum-introduction) -* [MyEtherWallet knowledge base (good for issues with wallets)](https://myetherwallet.github.io/knowledge-base/) -* [An introduction (Frontier first release, outdated)](https://ethereum.gitbooks.io/frontier-guide/content/ethereum.html) -* [Here's another introduction, made in November 2017](https://medium.com/@Ethereum_AI/ethereum-introduction-what-exactly-is-it-why-care-how-to-invest-9a627ab04408) -* [Ethereum community on Gitter](https://gitter.im/ethereum) -* [Ethereum research forum](https://ethresear.ch/) -* [Correct by construction Casper prototype](https://ethresear.ch/t/the-correct-by-construction-casper-paper-prototype-published-at-devcon-tear-it-apart/196) -* [Casper the Friendly Finality Gadget](https://ethresear.ch/t/latest-casper-basics-tear-it-apart/151/57) -* [The stateless client concept](https://ethresear.ch/t/the-stateless-client-concept/172) -* [Ethereum 2 and alternative PoS implementations](https://ethresear.ch/t/ethereum-2-and-alternative-pos-implementations/190/7) -* [Ethereum wiki](https://en.wikipedia.org/wiki/Ethereum) -* [Ethereum and the hodlers that love them](https://www.reddit.com/r/ethtrader/comments/6jyn9y/ethereum_the_hodlors_that_love_them/) - - -This article was originally created here in May 2017, and has been regularly updated since then: https://sustergy.wordpress.com/2017/05/18/why-buy-ether-and-how/. Feel free to send a donation to the initial author at jamesray.eth, or make edits to it yourself, or fork it! diff --git a/pages/introduction/FAQ.md b/pages/introduction/FAQ.md deleted file mode 100644 index cc812a4a4..000000000 --- a/pages/introduction/FAQ.md +++ /dev/null @@ -1,263 +0,0 @@ ---- -name: FAQ -category: ---- - -Answers to questions about Ethereum - - - - -* [Ethereum](#ethereum) - * [What is Ethereum?](#what-is-ethereum) - * [Where can I learn more about Ethereum?](#where-can-i-learn-more-about-ethereum) - * [Where can I find the main project repositories?](#where-can-i-find-the-main-project-repositories) - * [Where can I learn about the Ether sale and mining?](#where-can-i-learn-about-the-ether-sale-and-mining) -* [Clients](#clients) - * [Where can I find official releases?](#where-can-i-find-official-releases) - * [How to install development builds?](#how-to-install-development-builds) - * [How to install the clients from source?](#how-to-install-the-clients-from-source) -* [Mining](#mining) - * [How can I mine Ether?](#how-can-i-mine-ether) - * [How to get free testnet Ether?](#how-to-get-free-testnet-ether) -* [Contracts](#contracts) - * [Where can I learn about contract development?](#where-can-i-learn-about-contract-development) - * [Where can I learn Solidity?](#where-can-i-learn-solidity) - * [Where can I learn Serpent?](#where-can-i-learn-serpent) - * [Where can I learn LLL?](#where-can-i-learn-lll) - * [Where can I learn Solidity?](#where-can-i-learn-solidity) - * [How to test contracts?](#how-to-test-contracts) - * [How to deploy contracts automatically?](#how-to-deploy-contracts-automatically) - * [Where to find example contracts?](#where-to-find-example-contracts) -* [ÐApps](#Ðapps) - * [Where can I learn about the Ethereum APIs?](#where-can-i-learn-about-the-ethereum-apis) - * [Where can I learn about ÐApp development?](#where-can-i-learn-about-Ðapp-development) - * [Where can I find ÐApp development tools?](#where-can-i-find-Ðapp-development-tools) - * [Where can I find example ÐApps?](#where-can-i-find-example-Ðapps) -* [IRC](#irc) - * [How can I join the Ethereum IRC channels?](#how-can-i-join-the-ethereum-irc-channels) - * [Where can I find the Ethereum IRC logs?](#where-can-i-find-the-ethereum-irc-logs) - * [Where can I learn about the ZeroGox bot?](#where-can-i-learn-about-the-zerogox-bot) -* [More Questions and Answers](#more-questions-and-answers) - - - -## Ethereum - -### What is Ethereum? - -There are several ways to answer this question, which are introduced on the dedicated [What is Ethereum](http://github.com/ethereum/wiki/wiki/What-is-Ethereum) wiki page. - -If you prefer to learn by watching videos, see: - + [Vitalik Buterin explains Ethereum](https://www.youtube.com/watch?v=TDGq4aeevgY) (Video, 3min) - + [Vitalik Buterin reveals Ethereum at Bitcoin Miami 2014](http://youtu.be/l9dpjN3Mwps) (Video, 28min) - + [Singularity 1 on 1: Ethereum is a Decentralized Consensus Platform](http://youtu.be/fbEtivJIfIU) (Video, 69min) - + [Our second Reddit "Ask Me Anything" for community selected questions](http://www.reddit.com/r/IAmA/comments/2bjmgb/hi_we_are_the_ethereum_project_team_ask_us/) (not actually a video) - -### Where can I learn more about Ethereum? - -- Main site: https://www.ethereum.org -- Forums: https://forum.ethereum.org -- Github: https://github.com/ethereum -- Blog: https://blog.ethereum.org -- Wiki: http://wiki.ethereum.org -- Meetups: http://ethereum.meetup.com -- Whitepaper: http://ethereum.org/ethereum.html -- Yellow Paper: http://gavwood.com/paper.pdf -- Facebook: https://www.facebook.com/ethereumproject -- Youtube: http://www.youtube.com/ethereumproject -- Google+: http://google.com/+EthereumOrgOfficial -- IRC Freenode: #ethereum (http://bitly.com/IRC_ethereum for weblink) - -### Where can I find the main project repositories? - -+ [cpp-ethereum](https://github.com/ethereum/cpp-ethereum/) ([@gavofyork](https://github.com/gavofyork), [@programmerTim](https://github.com/programmerTim), [@caktux](https://github.com/caktux)) -+ [go-ethereum](https://github.com/ethereum/go-ethereum) ([@obscuren](https://github.com/obscuren), [@maran](https://github.com/maran)) -+ [pyethereum](https://github.com/ethereum/pyethereum) ([@vbuterin](https://github.com/vbuterin), [@heikoheiko](https://github.com/heikoheiko), [@chenhouwu](https://github.com/chenhouwu)) -+ [ethereumj](https://github.com/ethereum/ethereumj) ([@romanman](https://github.com/romanman), [@nicksavers](https://github.com/nicksavers)) -+ [ethereumjs-lib](https://github.com/ethereum/ethereumjs-lib) ([@ethers](https://github.com/ethers), [@wanderer](https://github.com/wanderer)) - -### Where can I learn about the Ether sale and mining? - -+ [The Ether Sale FAQ](https://forum.ethereum.org/discussion/196/the-ether-sale-faq/p1) -+ [The Mining FAQ](https://forum.ethereum.org/discussion/197/mining-faq-live-updates/p1) - -## Clients - -### Where can I find official releases? - -+ [Releases for AlethZero](https://github.com/ethereum/cpp-ethereum/releases) -+ [Releases for Mist](https://github.com/ethereum/go-ethereum/releases) -+ [Releases for Pyethereum](https://github.com/ethereum/pyethereum/releases) - -### How to install development builds? - -+ Homebrew - + [Homebrew Ethereum](https://github.com/caktux/homebrew-ethereum) ([@caktux](https://github.com/caktux)) -+ Guides - + [AlethZero super easy install guide for OSX](https://forum.ethereum.org/discussion/1388/alethzero-super-easy-install-guide-for-osx) ([@stephantual](https://github.com/stephantual)) - + [Go-Ethereum simple build guide for OSX](http://forum.ethereum.org/discussion/905/go-ethereum-cli-ethereal-simple-build-guide-for-osx-now-with-one-line-install) ([@stephantual](https://github.com/stephantual)) - + [Building on Ubuntu](https://github.com/ethereum/cpp-ethereum/wiki/Building-on-Ubuntu#user-content-trusty-1404) -+ Builds - + [Ethdev Buildbot](http://build.ethdev.com/waterfall) - -### How to install the clients from source? - -+ [Building AlethZero (C++)](https://github.com/ethereum/cpp-ethereum/wiki) -+ [Building Mist (Go)](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum%28Go%29) -+ [Installing Pyethereum (Python)](https://github.com/ethereum/pyethereum#quickstart) -+ [Installing EthereumJ (Java)](https://github.com/ethereum/ethereumj#maven) -+ [Installing Ethereumjs-lib (JavaScript for Browser and Node)](https://github.com/ethereum/ethereumjs-lib#install) - -## Mining - -### How can I mine Ether? - -With AlethZero - -+ To process transactions - + Disable "Debug" > "Force Mining" - + Click "Mine" -+ To force mine (Use sparingly, unless stress testing) - + Enable "Debug" > "Force Mining" - + Click "Mine" - -With the eth client - -``` -# Only force mine to acquire ether or stress test -$ eth --force-mining --mining on [YOUR OPTIONS...] -``` - -### How to get free testnet Ether? - -+ [ZeroGox Wei Faucet](https://zerogox.com/ethereum/wei_faucet) ([@caktux](https://github.com/caktux)) - -## Contracts - -### Where can I learn about contract development? - -+ Articles - + [Ethereum Development Tutorial](https://github.com/ethereum/wiki/wiki/Ethereum-Development-Tutorial) -+ Videos - + [Ethereum](https://www.youtube.com/user/ethereumproject/videos) - + [EtherCasts](https://www.youtube.com/user/EtherCasts/videos) - -### Where can I learn Serpent, the Python-like language? - -+ Specifications - + [The Serpent Language](https://github.com/ethereum/wiki/wiki/Serpent) -+ Examples - + [Vitalik's Serpent examples](https://github.com/ethereum/serpent/tree/master/examples) -+ Tutorials - + [Pyethereum and Serpent Programming Guide](https://blog.ethereum.org/2014/04/10/pyethereum-and-serpent-programming-guide/) -+ Videos - + [Learn Ethereum with Vitalik](https://www.youtube.com/watch?v=nXYDfLCLmMs) - -### Where can I learn LLL, the Lisp-like language? - -+ Specifications - + [The LLL Language](https://github.com/ethereum/cpp-ethereum/wiki/LLL-PoC-6) -+ Examples - + [LLL examples for PoC 6](https://github.com/ethereum/cpp-ethereum/wiki/LLL%20Examples%20for%20PoC%205) -+ Videos - + [Programming Society with Asm](https://www.youtube.com/watch?v=xO1AxsYAkU8) - -### Where can I learn Solidity, the JavaScript-like language? - -+ Specifications - + [Solidity, Docs and ABI](https://github.com/ethereum/cpp-ethereum/wiki/Solidity%2C-Docs-and-ABI) - + [Solidity Features](https://github.com/ethereum/wiki/wiki/Solidity-Features) -+ Tutorials - + [Solidity Tutorial](https://github.com/ethereum/wiki/wiki/Solidity-Tutorial) - + [Contract Writing in Solidity](https://dappsforbeginners.wordpress.com) - -### How to test contracts? - -+ [EVM Contract Simulator](https://github.com/EtherCasts/evm-sim/) ([@EtherCasts](https://github.com/EtherCasts)) -+ [Pyethereum Tester](https://github.com/ethereum/pyethereum/blob/master/tests/test_contracts.py) ([@ethereum](https://github.com/ethereum)) - -### How to deploy contracts automatically? - -+ [Ethereum Package Manager](https://github.com/project-douglas/epm) - -### Where to find example contracts? - -+ Serpent - + [By Vitalik Buterin](https://github.com/ethereum/serpent/tree/master/examples) ([@vbuterin](https://github.com/vbuterin)) - + [By EtherCasts](https://github.com/EtherCasts) ([@EtherCasts](https://github.com/EtherCasts)) - + [By Rob Myers](https://github.com/robmyers/artworld-ethereum) ([@robmyers](https://github.com/robmyers)) - + [By Tyler Florez](https://github.com/qualiabyte/ethereum-contracts) ([@qualiabyte](https://github.com/qualiabyte)) -+ LLL - + [By Gavin Wood](https://github.com/ethereum/cpp-ethereum/wiki/LLL%20Examples%20for%20PoC%205) ([@gavofyork](https://github.com/gavofyork)) - + [By Dennis Mckinnon](https://github.com/dennismckinnon/Ethereum-Contracts) ([@dennismckinnon](https://github.com/dennismckinnon)) - + [By Project Douglas](https://github.com/project-douglas/eris/tree/master/contracts) ([@project-douglas](https://github.com/project-douglas)) - + [By Doug A.](https://github.com/d11e9/g3) ([@dlle9](https://github.com/d11e9)) - -## ÐApps - -### Where can I learn about the Ethereum APIs? - -+ [The PoC 6 API for C++](https://github.com/ethereum/cpp-ethereum/wiki/Client-Development-with-PoC-6) -+ [The PoC 5 API for Go](https://github.com/ethereum/go-ethereum/wiki/PoC-5-Public-Go-API) -+ [The PoC 6 API for QML](https://github.com/ethereum/go-ethereum/wiki/QML-PoC6-API) -+ [The PoC 7 API for JavaScript](https://github.com/ethereum/wiki/wiki/JavaScript-API) - -### Where can I learn about ÐApp development? - -+ [Writing Your Own Currency](http://hidskes.com/blog/2014/05/21/ethereum-dapp-development-for-web-developers/) ([@maran](https://github.com/maran)) - -### Where can I find ÐApp development tools? - -Official - -+ [AlethZero GUI client (C++)](https://github.com/ethereum/cpp-ethereum/wiki/Using-AlethZero) -+ [Eth command-line client (C++)](https://github.com/ethereum/cpp-ethereum/wiki/Using-Ethereum-CLI-Client) -+ [LLLC Compiler (C++)](https://github.com/ethereum/cpp-ethereum/blob/develop/lllc/main.cpp) -+ [Ethereum command-line client (Go)](https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options) -+ [Mist Browser (Go)](https://github.com/ethereum/go-ethereum) -+ [Pyeth command-line client (Python)](https://github.com/ethereum/pyethereum#interacting-with-the-network) -+ [Serpent Compiler (Python)](https://github.com/ethereum/wiki/wiki/Serpent) - -Community - -+ [C3D](https://github.com/project-douglas/c3d) ([@project-douglas](https://github.com/project-douglas)) -+ [Emacs LLL Mode](https://github.com/robmyers/lll-mode) ([@robmyers](https://github.com/robmyers)) -+ [Emacs Serpent Mode](https://github.com/robmyers/serpent-mode) ([@robmyers](https://github.com/robmyers)) -+ [EPM](https://github.com/project-douglas/epm) ([@project-douglas](https://github.com/project-douglas)) -+ [EPM Sublime Plugin](https://github.com/project-douglas/epm-sublime) ([@project-douglas](https://github.com/project-douglas)) -+ [Ethos Browser](https://github.com/projectdnet/ethos) ([@projectdnet](https://github.com/projectdnet)) -+ [EVM-Sim](https://github.com/EtherCasts/evm-sim/) ([@EtherCasts](https://github.com/EtherCasts)) -+ [MintChalk](http://www.mintchalk.com/) ([@mintchalk](https://github.com/mintchalk)) -+ [Poly-Eth](https://github.com/projectdnet/poly-eth) ([@projectdnet](https://github.com/projectdnet)) - -### Where can I find example ÐApps? - -+ [dapp-bin](https://github.com/ethereum/dapp-bin) ([@ethereum](https://github.com/ethereum)) -+ [GavCoin](http://gavwood.com/gavcoin.html) ([@gavofyork](https://github.com/gavofyork)) -+ [JeffCoin](https://github.com/obscuren/jeffcoin) ([@obscuren](https://github.com/obscuren)) -+ [Make It Rain](https://github.com/EtherCasts/make-it-rain) ([@EtherCasts](https://github.com/EtherCasts)) -+ [Chronos](https://github.com/mquandalle/chronos) ([@mquandalle](https://github.com/mquandalle)) -+ [Artworld-Ethereum](https://github.com/robmyers/artworld-ethereum) ([@robmyers](https://github.com/robmyers)) -+ [Eris](https://github.com/project-douglas/eris) ([@project-douglas](https://github.com/project-douglas), [@compleatang](https://github.com/compleatang), [@dennismckinnon](https://github.com/dennismckinnon)) -+ [CryptoCoinWatch](https://github.com/EtherCasts/cryptocoinwatch) ([@EtherCasts](https://github.com/EtherCasts)) -+ [Occam's Run](https://github.com/d11e9/Occams-Run) ([@d11e9](https://github.com/d11e9)) -+ [TrustDavis](https://github.com/EtherCasts/trustdavis) ([@EtherCasts](https://github.com/EtherCasts)) - -## IRC - -### How can I join the Ethereum IRC channels? - -+ [Chat with the ethereum dev community on IRC!](https://forum.ethereum.org/discussion/1495/chat-with-the-ethereum-dev-community-on-irc) - -### Where can I find the Ethereum IRC logs? - -+ [The ZeroGox logs](https://zerogox.com/bot/log) - -### Where can I learn about the ZeroGox bot? - -+ [The ZeroGox bot](https://zerogox.com/bot) - -# More Questions and Answers - -+ [FAQ by @fivedogit](https://docs.google.com/document/d/14EIe984_86Y-uuNm-a4EsVeD3eI4qAAlz_MZof1qkqM/) \ No newline at end of file diff --git a/pages/introduction/Gitter-Channels.md b/pages/introduction/Gitter-Channels.md deleted file mode 100644 index 89d323787..000000000 --- a/pages/introduction/Gitter-Channels.md +++ /dev/null @@ -1,44 +0,0 @@ -https://gitter.im/ethereum - -# Node Software ("Clients") - -## Go - -https://gitter.im/ethereum/go-ethereum - -## CPP - -https://gitter.im/ethereum/cpp-ethereum - -## Python - -https://gitter.im/ethereum/pyethapp - the client - -https://gitter.im/ethereum/pyethereum - the core library (evm, blocks, txs, ...) - -https://gitter.im/ethereum/pydevp2p - p2p network - -# DApp Development - -https://gitter.im/ethereum/web3.js - -https://gitter.im/ethereum/mist - -https://gitter.im/ethereum/solidity - -https://gitter.im/ethereum/serpent - -# Other - -https://gitter.im/ethereum/porting - -https://gitter.im/ethereum/research - -# Protocol - -https://gitter.im/ethereum/devp2p - -https://gitter.im/ethereum/light-client - - - diff --git a/pages/introduction/Glossary.md b/pages/introduction/Glossary.md deleted file mode 100644 index 06dd59b44..000000000 --- a/pages/introduction/Glossary.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -name: Glossary -category: ---- - -One of the things that cryptocurrency, and really any new genre of technology, is notorious for is the sheer quantity of vocabulary that gets generated to describe all of the new concepts. Anyone dealing with peer-to-peer internet software on anything more than a casual basis needs to deal with concepts of cryptography, including hashes, signatures and public and private keys, symmetric and asymmetric encryption, denial of service protection, as well as arcane constructions such as distributed hash tables and webs of trust. New Bitcoin users are forced to contend with learning not just the common basics of cryptography, but also additional internal jargon such as "blocks", "confirmations", "mining", "SPV clients" and "51% attacks", as well as economic concepts like incentive-compatibility and the fine nuances of centralization and decentralization. Ethereum, being a decentralized application development platform based on a generalization of a cryptocurrency, necessarily incorporates both of these sets of concepts, as well as adding many of its own. To help anyone new to Ethereum, whether they are in it as cryptocurrency enthusiasts, business owners, social or political visionaries, web developers or are simply ordinary people looking to see how the technology can improve their lives, the following list is intended to provide a basic summary of the vocabulary that Ethereum users often tend to use: - -### Cryptography - -See also: http://en.wikipedia.org/wiki/Public-key_cryptography - -* **Computational infeasibility**: a process is computationally infeasible if it would take an impracticably long time (eg. billions of years) to do it for anyone who might conceivably have an interest in carrying it out. Generally, 280 computational steps is considered the lower bound for computational infeasibility. -* **Hash**: a hash function (or hash algorithm) is a process by which a document (ie. a piece of data or file) is processed into a small piece of data (usually 32 bytes) which looks completely random, and from which no meaningful data can be recovered about the document, but which has the important property that the result of hashing one particular document is always the same. Additionally, it is crucially important that it is computationally infeasible to find two documents that have the same hash. Generally, changing even one letter in a document will completely randomize the hash; for example, the SHA3 hash of "Saturday" is `c38bbc8e93c09f6ed3fe39b5135da91ad1a99d397ef16948606cdcbd14929f9d`, whereas the SHA3 hash of Caturday is `b4013c0eed56d5a0b448b02ec1d10dd18c1b3832068fbbdc65b98fa9b14b6dbf`. Hashes are usually used as a way of creating a globally agreed-upon identifier for a particular document that cannot be forged. -* **Encryption**: encryption is a process by which a document (**plaintext**) is combined with a shorter string of data, called a **key** (eg. `c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4`), to produce an output (**ciphertext**) which can be "decrypted" back into the original plaintext by someone else who has the key, but which is incomprehensible and computationally infeasible to decrypt for anyone who does not have the key. -* **Public key encryption**: a special kind of encryption where there is a process for generating two keys at the same time (typically called a **private key** and a **public key**), such that documents encrypted using one key can be decrypted with the other. Generally, as suggested by the name, individuals publish their public keys and keep their private keys to themselves. -* **Digital signature**: a digital signing algorithm is a process by which a user can produce a short string of data called a "signature" of a document using a private key such that anyone with the corresponding public key, the signature and the document can verify that (1) the document was "signed" by the owner of that particular private key, and (2) the document was not changed after it was signed. Note that this differs from traditional signatures where you can scribble extra text onto a document after you sign it and there's no way to tell the difference; in a digital signature any change to the document will render the signature invalid. - -### Blockchains - -See also: https://bitcoin.org/en/vocabulary - -* **Address**: an address is essentially the representation of a public key belonging to a particular user; for example, the address associated with the private key given above is `cd2a3d9f938e13cd947ec05abc7fe734df8dd826`. Note that in practice, the address is technically the hash of a public key, but for simplicity it's better to ignore this distinction. -* **Transaction**: a transaction is a document authorizing some particular action associated with the blockchain. In a currency, the dominant transaction type is sending currency units or tokens to someone else; in other systems actions like registering domain names, making and fulfilling trade offers and entering into contracts are also valid transaction types. -* **Block**: a block is a package of data that contains zero or more transactions, the hash of the previous block ("parent"), and optionally other data. The total set of blocks, with every block except for the initial "genesis block" containing the hash of its parent, is called the **blockchain** and contains the entire transaction history of a network. Note that some blockchain-based cryptocurrencies instead use the word "ledger" for a blockchain; the two are roughly equivalent, although in systems that use the term "ledger" each block generally contains a full copy of the current state (eg. currency balances, partially fulfilled contracts, registrations) of every account allowing users to discard outdated historical data. -* **Account**: an account is the entry in a ledger, indexed by its address, that contains the complete data about the state of that account. In a currency system, this involves currency balances and perhaps unfulfilled trade orders; in other cases more complex relationships may be stored inside of accounts. -* **Proof of work**: one important property of a block in Bitcoin, Ethereum and many other crypto-ledgers is that the hash of the block must be smaller than some target value. The reason this is necessary is that in a decentralized system anyone can produce blocks, so in order to prevent the network from being flooded with blocks, and to provide a way of measuring how much consensus there is behind a particular version of the blockchain, it must in some way be hard to produce a block. Because hashes are pseudorandom, finding a block whose hash is less than `0000000100000000000000000000000000000000000000000000000000000000` takes an average of 4.3 billion attempts. In all such systems, the target value self-adjusts so that on average one node in the network finds a block every N minutes (eg. N = 10 for Bitcoin and 1 for Ethereum). -* **Nonce**: a meaningless value in a block which can be adjusted in order to try to satisfy the proof of work condition -* **Mining**: mining is the process of repeatedly aggregating transactions, constructing a block and trying difference nonces until a nonce is found that satisfies the proof of work condition. If a miner gets lucky and produces a valid block, they are granted a certain number of coins as a reward as well as all of the transaction fees in the block, and all miners start trying to create a new block containing the hash of the newly generated block as their parent. -* **Stale**: a stale is a block that is created when there is already another block with the same parent out there; stales typically get discarded and are wasted effort. -* **Fork**: a situation where two blocks are generated pointing to the same block as their parent, and some portion of miners see one block first and some see the other. This may lead to two blockchains growing at the same time. Generally, it is mathematically near-certain that a fork will resolve itself within four blocks as miners on one chain will eventually get lucky and that chain will grow longer and all miners switch to it; however, forks may last longer if miners disagree on whether or not a particular block is valid. -* **Double spend**: a deliberate fork, where a user with a large amount of mining power sends a transaction to purchase some produce, then after receiving the product creates another transaction sending the same coins to themselves. The attacker then creates a block, at the same level as the block containing the original transaction but containing the second transaction instead, and starts mining on the fork. If the attacker has more than 50% of all mining power, the double spend is guaranteed to succeed eventually at any block depth. Below 50%, there is some probability of success, but it is usually only substantial at a depth up to about 2-5; for this reason, most cryptocurrency exchanges, gambling sites and financial services wait until six blocks have been produced ("six confirmations") before accepting a payment. -* **SPV client** (or **light client**) - a client that downloads only a small part of the blockchain, allowing users of low-power or low-storage hardware like smartphones and laptops to maintain almost the same guarantee of security by sometimes selectively downloading small parts of the state without needing to spend megabytes of bandwidth and gigabytes of storage on full blockchain validation and maintennance. - -### Ethereum Blockchain - -See also: http://ethereum.org/ethereum.html - -* **Serialization**: the process of converting a data structure into a sequence of bytes. Ethereum internally uses an encoding format called recursive-length prefix encoding (RLP), described [here](https://github.com/ethereum/wiki/wiki/RLP) -* **Patricia tree** (or **trie**): a data structure which stores the state of every account. The trie is built by starting from each individual node, then splitting the nodes into groups of up to 16 and hashing each group, then making hashes of hashes and so forth until there is one final "root hash" for the entire trie. The trie has the important properties that (1) there is exactly one possible trie and therefore one possible root hash for each set of data, (2) it is very easy to update, add or remove nodes in the trie and generate the new root hash, (3) there is no way to modify any part of the tree without changing the root hash, so if the root hash is included in a signed document or a valid block the signature or proof of work secures the entire tree, and (4) one can provide just the "branch" of a tree going down to a particular node as cryptographic proof that that node is indeed in the tree with that exact content. Patricia trees are also used to store the internal storage of accounts as well as transactions and uncles. See [here](http://easythereentropy.wordpress.com/2014/06/04/understanding-the-ethereum-trie/) for a more detailed description. -* **GHOST**: GHOST is a protocol by which blocks can contain a hash of not just their parent, but also hashes for stales that are other children of the parent's parent (called **uncles**). This ensures that stales still contribute to blockchain security, and mitigates a problem with fast blockchains that large miners have an advantage because they hear about their own blocks immediately and so are less likely to generate stales. -* **Uncle**: a child of a parent of a parent of a block that is not the parent, or more generally a child of an ancestor that is not an ancestor. If A is an uncle of B, B is a **nephew** of A. -* **Account nonce**: a transaction counter in each account. This prevents replay attacks where a transaction sending eg. 20 coins from A to B can be replayed by B over and over to continually drain A's balance. -* **EVM code**: Ethereum virtual machine code, the programming language in which accounts on the Ethereum blockchain can contain code. The EVM code associated with an account is executed every time a message is sent to that account, and has the ability to read/write storage and itself send messages. -* **Message**: a sort of "virtual transaction" sent by EVM code from one account to another. Note that "transactions" and "messages" in Ethereum are different; a "transaction" in Ethereum parlance specifically refers to a physical digitally signed piece of data that goes in the blockchain, and every transaction triggers an associated message, but messages can also be sent by EVM code, in which case they are never represented in data anywhere. -* **Storage**: a key/value database contained in each account, where keys and values are both 32-byte strings but can otherwise contain anything. -* **Externally owned account**: an account controlled by a private key. Externally owned accounts cannot contain EVM code. -* **Contract**: an account which contains, and is controlled by, EVM code. Contracts cannot be controlled by private keys directly; unless built into the EVM code, a contract has no owner once released. -* **Ether**: the primary internal cryptographic token of the Ethereum network. Ether is used to pay transaction and computation fees for Ethereum transactions. -* **Gas**: a measurement roughly equivalent to computational steps. Every transaction is required to include a gas limit and a fee that it is willing to pay per gas; miners have the choice of including the transaction and collecting the fee or not. If the total number of gas used by the computation spawned by the transaction, including the original message and any sub-messages that may be triggered, is less than or equal to the gas limit, then the transaction processes. If the total gas exceeds the gas limit, then all changes are reverted, except that the transaction is still valid and the fee can still be collected by the miner. Every operation has a gas expenditure; for most operations it is 1, although some expensive operations have expenditures up to 100 and a transaction itself has an expenditure of 500. - -### Non-blockchain - -* **EtherBrowser**: the upcoming primary client for Ethereum, which will exist in the form of a web browser that can be used to access both normal websites and applications built on top of the Ethereum platform -* **Whisper**: an upcoming P2P messaging protocol that will be integrated into the EtherBrowser -* **Swarm**: an upcoming P2P data storage protocol optimized for static web hosting that will be integrated into the EtherBrowser -* **Solidity**, **LLL**, **Serpent** and **Mutan**: prorgamming languages for writing contract code which can be compiled into EVM code. Serpent can also be compiled into LLL. -* **PoC**: proof-of-concept, another name for a pre-launch release - -### Surrounding concepts: applications and governance - -* **Decentralized application**: a program which is run by many people which either uses or creates a decentralized network for some specific purpose (eg. connecting buyers and sellers in some marketplace, sharing files, online file storage, maintaining a currency). Ethereum-based decentralized applications (also called Đapps, where the Đ is the Norse letter "eth") typically consist of an HTML/Javascript webpage, and if viewed inside the EtherBrowser the browser recognizes special Javascript APIs for sending transactions to the blockchain, reading data from the blockchain and interacting with Whisper and Swarm. A Đapp typically also has a specific associated contract on the blockchain, though Đapps that facilitate the creation of many contracts are quite possible. -* **Decentralized organization**: an organization that has no centralized leadership, instead using a combination of formal democratic voting processes and stigmergic self-organization as their primary operating principles. A less impressive but sometimes confused concept is a "geographically distributed organization", an organization where people work far apart from each other and which may even have no office at all; GDOs can still have formal centralized leadership. -* **Theseus criterion**: a test for determining how decentralized an organization is. The test is as follows: suppose the organization has N people, and aliens try to pick K people in the organization at a time (eg. once per week) and zap them out of existence, replacing each group with K new people who know nothing about the organization. For how high K can the organization function? Dictatorships fail at K = 1 once the dictator is zapped away; the US government does slightly better but would still be in serious trouble if all 638 members of the Senate and Congress were to disappear, where as something like Bitcoin or BitTorrent is resilient for extremely high K because new agents can simply follow their economic incentives to fill in the missing roles. A stricter test, the **Byzantine Theseus criterion**, involves randomly substituting K users at a time with malicious actors for some time before replacing them with new users. -* **Decentralized autonomous organization**: decentralized organizations where the method of governance is in some fashion "autonomous", ie. it's not controlled by some form of discussion process or committee. -* **No common language criterion**: a test for determining how autonomous an organization is. The test is as follows: suppose the N people in the organization speak N different languages, with none in common. Can the organization still function? -* **Delegative democracy** (or **liquid democracy**): a governance mechanism for DOs and DAOs where everyone votes on everything by default, but where individuals [can select specific individuals](http://en.wikipedia.org/wiki/Delegative_democracy) to vote for them on specific issues. The idea is to generalize the tradeoff between full direct democracy with every individual having equal power and the expert opinion and quick decision making ability provided by specific individuals, allowing people to defer to friends, politicians, subject matter experts or anyone else to exactly the extent that they want to. -* **Futarchy**: a governance mechanism [originally proposed](http://hanson.gmu.edu/futarchy.html) by Robin Hanson for managing political organizations, but which is actually extremely applicable for DOs and DAOs: rule by prediction market. Essentially, some easily measurable success metrics are chosen, and tokens are released which will pay out some time in the future (eg. after 1 year) depending on the values of those success metrics, with one such token for each possible action to take. Each of these tokens are traded against a corresponding dollar token, which pays out exactly $1 if the corresponding measure is taken (if the corresponding measure is not taken, both types of tokens pay $0, so the probability of the action actually being taken does not affect the price). The action that the market predicts will have the best results, as judged by the token's high price on its market, is the action that will be taken. This provides another, autonomous, mechanism for selecting for and simultaneously rewarding expert opinion. - -### Economics - -* **Token system**: essentially, a fungible virtual good that can be traded. More formally, a token system is a database mapping addresses to numbers with the property that the primary allowed operation is a transfer of N tokens from A to B, with the conditions that N is non-negative, N is not greater than A's current balance, and a document authorizing the transfer is digitally signed by A. Secondary "issuance" and "consumption" operations may also exist, transaction fees may also be collected, and simultaneous multi-transfers with many parties may be possible. Typical use cases include currencies, cryptographic tokens inside of networks, company shares and digital gift cards. -* **Namespace**: a database mapping names to values. In the simplest example anyone can register an entry if the name has not already been taken (perhaps after paying some fee). If a name has been taken then it can only be changed (if at all) by the account that made the original registration (in many systems, ownership can also be transferred). Namespaces can be used to store usernames, public keys, internet domain names, token systems or other namespaces, and many other applications. -* **Identity**: a set of cryptographically verifiable interactions that have the property that they were all created by the same person -* **Unique identity**: a set of cryptographically verifiable interactions that have the property that they were all created by the same person, with the added constraint that one person cannot have multiple unique identities -* **Incentive compatibility**: a protocol is incentive-compatible if everyone is better off "following the rules" than attempting to cheat, at least unless a very large number of people agree to cheat together at the same time. -* **Basic income**: the idea of issuing some quantity of tokens to every unique identity every period of time (eg. months), with the ultimate intent being that people who do not wish to work or cannot work can survive on this allowance alone. These tokens can simply be crafted out of thin air, or they can come from some revenue stream (eg. profit from some revenue-generating entity, or a government); in order for the BI to be sufficient for a person to live on it alone, a combination of revenue streams will likely have to be used. -* **Public good**: a service which provides a very small benefit to a very large number of people, such that no individual has a large effect on whether or not the good is produced and so no one has the incentive to help pay for it. -* **Reputation**: the property of an identity that other entities believe that identity to be either (1) competent at some specific task, or (2) trustworthy in some context, ie. not likely to betray others even if short-term profitable. -* **Web of trust**: the idea that if A highly rates B, and B highly rates C, then A is likely to trust C. Complicated and powerful mechanisms for determining the reliability of specific individuals in specific concepts can theoretically be gathered from this principle. -* **Escrow**: if two low-reputation entities are engaged in commerce, the payer may wish to leave the funds with a high-reputation third party and instruct that party to send the funds to the payee only when the product is delivered. This reduces the risk of the payer or payee committing fraud. -* **Deposit**: digital property placed into a contract involving another party such that if certain conditions are not satisfied that property is automatically forfeited to the counterparty -* **Hostage**: digital property placed into a contract such that if certain conditions are not satisfied that property is automatically either destroyed or donated to charity or basic income funds, perhaps with widely distributed benefit but necessarily with no significant benefit to any specific individual. diff --git a/pages/introduction/Home.md b/pages/introduction/Home.md deleted file mode 100644 index c4b23330b..000000000 --- a/pages/introduction/Home.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -name: Home -category: ---- - -# Welcome to the Ethereum Wiki - - -This is the community-maintained wiki covering all sorts of information on the next-generation peer-to-peer technology platform build by ÐΞV including **Ethereum**, _the generalized blockchain for smart contract development_, and **Whisper**, _the private low-level datagram communication platform_. - -Users signed in with GitHub can edit and add pages using the [browser](https://help.github.com/articles/editing-wiki-pages-via-the-online-interface) or [locally](https://help.github.com/articles/adding-and-editing-wiki-pages-locally). - -## Status - -### Frontier - -Version 1.0 of Ethereum aka Frontier was released on July 30th 2015! Development continues towards the versions named Homestead, Metropolis and Serenity (v1.1). Frontier is aimed at exchangers and [miners](https://github.com/ethereum/wiki/wiki/Mining). Homestead is aiming for [Ðapps developers](https://github.com/ethereum/wiki/wiki/Ethereum-Development-Tutorial), while Metropolis is aiming for end users with the release of the Mist browser. Serenity is meant to move from consensus through [Proof-of-Work](https://github.com/ethereum/wiki/wiki/Ethash) to [Proof-of-Stake](https://blog.ethereum.org/2015/08/01/introducing-casper-friendly-ghost/). - -## Getting started -To get the basic concepts of Ethereum visit the Ethereum homepage over at [http://ethereum.org](http://ethereum.org/). If you want to get a deeper understanding, start by read the [whitepaper](https://github.com/ethereum/wiki/wiki/White-Paper) and the [design rationale](https://github.com/ethereum/wiki/wiki/Design-Rationale). For a more formal review, read the [yellow paper](http://gavwood.com/Paper.pdf). See the [development tutorial](https://github.com/ethereum/wiki/wiki/Ethereum-Development-Tutorial) for quick start to developing smart contracts. - -## Don't get lost -Check the [Glossary](https://github.com/ethereum/wiki/wiki/Glossary) and our [FAQ](https://github.com/ethereum/wiki/wiki/FAQ). There are separate wikis for information relevant to the [C++](https://github.com/ethereum/cpp-ethereum/wiki) and [Go](https://github.com/ethereum/go-ethereum/wiki) implementations (Python and Javascript coming soon), - -## Downloads -Bleeding edge code can be cloned from the develop branch of their git repositories: -- https://github.com/ethereum/cpp-ethereum -- https://github.com/ethereum/go-ethereum -- https://github.com/ethereum/pyethapp -To see the state of the latest Ethereum builds, see the [build server](http://build.ethdev.com/console). diff --git a/pages/introduction/What-is-Ethereum.md b/pages/introduction/What-is-Ethereum.md deleted file mode 100644 index 0bb7ecfdd..000000000 --- a/pages/introduction/What-is-Ethereum.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -name: What is Ethereum? -category: ---- - -# What is Ethereum? - -Ethereum, like any advanced system, will mean different things to different people. As you read this section, some bits may not resonate with you or even make sense. That is fine, just skip to the next paragraph and hopefully that one will be more enlightening. If you reach the end of this section and still feel confused, then jump on a forum and start asking questions. - - -## A World Computer - ->"It is very possible that ... one machine would suffice to solve all the problems ... of the whole [world]" - Sir Charles Darwin, 1946* - -In a technical sense, Ethereum is a "world computer". Harking back to the days of the mainframe, and probably about as fast, Ethereum can be viewed as a single computer that the whole world can use. It notionally has only a single processor (no multi-threading or parallel execution), but as much memory as required. Anybody can upload programs to the Ethereum World Computer and anybody can request that a program that has been uploaded be executed. This does not mean that anyone can ask any program to do anything; on the contrary: the author of the program can specify that requests from anyone but themselves be ignored, for example. Also, in a very strong sense, every program has its own permanent storage that persists between executions. Furthermore, as long as it is in demand, the Ethereum World Computer will always be there: it can't be shut down or turned off. - -You may ask, "why would anyone use such a system?" and again there are many reasons. The main reason is because it makes what you want to do cheaper and easier. This statement needs to be broken down somewhat, which is what the following paragraphs explore. - - -## An Internet Service Platform - ->"Technology gives us the facilities that lessen the barriers of time and distance - the telegraph and cable, the telephone, radio, and the rest." - Emily Greene Balch - -In a more practical sense, Ethereum is an internet service platform for guaranteed computation. More than that, as a platform, it provides a set of integral features which are very useful to the developer: - - * user authentication, via seamless integration of cryptographic signatures - * fully customizable payment logic; easily create your own payment system without any reliance on third parties - * 100% ddos resistant up-time, guaranteed by being a fully decentralized blockchain-based platform - * no-fuss storage: forget about having to set up secure databases; Ethereum gives you as much storage as you want - * ultimate interoperability: everything in the Ethereum ecosystem can trivially interact with everything else, from reputation to custom currencies - * server free zone: your whole application can be deployed on the blockchain meaning no need for setting up or maintaining servers; let your users pay for the cost of their using your service. - -Over the last twenty years in particular, we have seen an acceleration in the development of services and infrastructure to make the overhead of working as a team or running businesses simpler and less expensive, mainly thanks to the internet. The likes of eBay, Drivy and Airbnb have made setting up a shop, car rental company or hotel much easier. These are platforms that allow people to realize their idea quickly, as long as the service they want to provide fits the template offered by the platform. Outside Ethereum, it is very costly to create a new platform if those that already exist do not fit your needs. Ethereum can be seen as a platform for platforms: it allows people to easily create the infrastructure to make it easy to set up new services on the internet. Furthermore, any infrastructure created on Ethereum sits alongside everyone else's creations, and so can interact with those other platforms in a guaranteed and seamless manner. Importantly, because there is not a company or indeed any entity in charge of or controlling Ethereum, the cost of running the infrastructure doesn't have to include any profit margin, so we are likely to see lower costs. - -With the coming of the Mix IDE and the Mist browser, the functionality of Ethereum as a deployment platform for internet services will become more clear. The take-home message from this section, however, is that Ethereum is poised to disrupt industries as diverse as finance and supply chains. - - -## Opt-in Social Contracts - -> "This is an era of organization" - Theodore Roosevelt, 1912** - -At a more abstract level, it is a facility for enabling smart organization, in the sense of groups of entities working together for a particular cause. In the simplest scenario, we have two people working together to achieve a trade. Ultimately, Ethereum could be used to run countries. Somewhere in between there are groups of people wanting to organize baby-sitting circles, film-making collectives, discussion groups, communal houses, etc, and they all have to decide the rules with which they will operate together. Arguably, the harder task is how to implement and enforce the rules, especially given the variety of characters, abilities and motivations that the human race provides. In other words, how do you stop Jo hogging the camera equipment, or Dave never doing his turn of the childcare? Ethereum provides a platform on which rules can be defined and, to an ever increasing degree as technology improves, see enforced. For example, the camera could be listening to the blockchain and only record if the film-making collective's DApp approves Jo's access code. - -Crowdfunding is a key example in the advancement organizational tools. It provides a couple of really important functions: a way for individuals to work together for a particular cause (in this case giving a wedge of cash to a person or group) and a mechanism for individuals to interact meaningfully with potentially large companies (such as a games studio). The first follows from the previous paragraph, but the second point is impressive also, because in general individuals can only communicate with large organizations on the organization's terms, which often default to "ignore"; in the same way you ignore the bacteria on your skin. As it stands, you might be disgruntled by the crowdfunding recipient taking your money and spending it in a wholey inappropriate and therefore inefficient manner. However, it's hard to get the operating company to act on your behalf against the recipient. After all, the crowdfunding service provider is likely to be a large company and there isn't a universal mechanism with which you can meaningfully communicate with it if it does not want you to. Ethereum can help by allowing you to define post-funding milestones or conditions to stage the payment of the total amount raised, and then enforce those conditions for you. As times goes on, we will get more creative in the ways in which Ethereum can interact with the real world and the ability of Ethereum to check that milestones have been completed will extend beyond the obvious such as "30% of the crowd that funded the project (by value) have voted that the milestone has been passed". - - -## Part of the Decentralization Revolution - ->"No matter who you vote for, the government always gets in" - The Bonzo Dog Doo-Dah Band, 1992 - -Philosophically, it is the next step in re-decentralizing the internet. A decentralized system is one that anyone can unilaterally join and participate in, one in which all participants contribute to the running and maintanence, and one in which any participant can unilaterally leave and when they do, the system continues regardless. In a decentralized system, there is no entity that can prevent participation or arbitrarily censor the content or usage. The internet was designed to be decentralized, but the way we use it has become increasingly centralized, to the point where censorship and exclusion are accepted and expected. Blockchain technology, introduced by Satoshi Nakamoto with the proof-of-concept implementation of a simple value transfer system known as bitcoin, represents the best digital system we have (after the internet itself) for administering multi-user interactions without any need for centralized coordination or oversight. Effectively, a decentralized system is its own authority for enforcing the rules (e.g. 'you can only spend your money once' in bitcoin, or 'whatever rule you programmed in to your smart contract' in Ethereum), so participants can be confident that the rules they expect to be enforced will be, without any danger of corruption, bribery, nepotism, political bias, exclusion, arbitrary exceptions, human oversight or absence of staff. - -Ethereum allows people to safely interact trustlessly by entering into neutrally enforceable agreements in a completely peer-to-peer fashion. Now, it must be remembered that Ethereum can only enforce within its own digital limits; Ethereum does not remove the need for an external authority for adjudication over disputes outside its realm---"the other party punched me in the face after putting in the Ethereum contract that he wouldn't" is non-sense, but rules exist elsewhere to cover this---but what Ethereum does do is allow us to push the boundary on what the digital realm can cover. - - -## Conclusion - -Gavin Wood has distilled the description of Ethereum to being a collection of non-localized singleton programmable data structures. What this means will depend on where you are coming from, but wherever you are, it's probably going to be better with Ethereum. - - -### Notes -*Copeland, Jack (2006). Colossus: The Secrets of Bletchley Park's Codebreaking Computers. Oxford University Press. p.109 - -Note that T.J.Watson, the former head of IBM, almost certainly never said, "I think there is a world market for maybe five computers", although for a time (late 1940s, early 1950s) it was indeed the case that there was, in the United States, a market for about five computers. - -**Presidential speech, Milwaukee, Wisconsin. diff --git a/pages/other-languages/[German]-Clearinghaus.md b/pages/other-languages/[German]-Clearinghaus.md deleted file mode 100644 index 66fc121c8..000000000 --- a/pages/other-languages/[German]-Clearinghaus.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -name: Clearinghaus -category: ---- - -### Einleitung -Bei manchen Finanzinstrumente wie ["Future"] (http://de.wikipedia.org/wiki/Future) (keine Geldtermingeschäfte) können sich die Parteien gegen Zahlungsausfälle gegenüber dem Geschäftspartner (i.d.R. bei einem Clearinghaus) absichern. Im Wesentlichen liefert eine Clearingstelle diese Garantie über ein Verfahren, bei dem die Gewinne und Verluste, die sich aus dem börslichen Handel dieser Features über die Vertragslaufzeit ergeben, durch tägliche Abrechnung in Bargeld umgewandelt werden. -### Tägliche Abrechnung -Wie erklärt, wird die "tägliche Abrechnung" von Gewinnen oder Verlusten in Bargeld konvertiert. Dieser Vorgang wird auch ** Marktbewertung ** bezeichnet und lässt sich am Besten über ein Beispiel veranschaulichen. -Angenommen zwei Parteien gehen einen Vertrag ein, einen [Vertragsgegenstand] (http://de.wikipedia.org/wiki/Underlying) zu einem vereinbarten Preis von 100 USD in einem Monat zu kaufen/verkaufen. Um diesen Vertrag einzugehen verlangt die Clearingstelle einen Vorschuss beider Partein, die diesen vorab begleichen müssen. Also die Partei, die den Vertragsgegenstand kaufen will [(** Halter der long position **)] (http://de.wikipedia.org/wiki/Long_und_Short) und die Partei, die den Vertragsgegenstand verkaufen will [(** Halter der short position **)] (http://de.wikipedia.org/wiki/Long_und_Short). -Die Vorschusszahlung möge 5 USD betragen und wird einbezahlt in einen **margin account** des Clearinghauses, gebunden an den spezifischen Vertrag. -Während der Laufzeit des Vertrags variiert der Betrag auf dem **margin account**. Die in dem Vertrag involvierten Parteien müssen das Guthaben des **margin account** über einem bestimmten Level halten, genannt **maintenance margin requirement**, der von dem Clearinghaus bestimmt wird und i.d.R. unterhalb der Höhe des Zahlungsvorschusses liegt. -Am Ende eines jeden Tages wird die Clearingstelle einen ** Abrechnungspreis ** bieten (in der Regel ein Durchschnittspreis aller Trades, die im Laufe des Tages passiert sind) um dann das ** Mark-to-Market-Verfahren ** (tägliche Abrechnungs) durchzuführen. -In unserem konkreten Beispiel nehmen wir an, dass die Höhe der Sicherheitsleistung, die nicht unterschritten werden darf (**maintenance margin requirement**) auf einen Betrag von 3 USD festgelegt wird und die kaufende Partei 10 Verträge eingeht. D.h. es wird eine Vorschusszahlung von 10 x 5 USD = 50 USD fällig. Wir gehen auch davon aus, dass das Geld von der Clearingstelle nicht zurückgebucht werden kann (z.B. Überschüsse). Der Initialpreis (des Future Contracts) beträgt 100 USD. -Ein vollständiges beispiel zeigt die folgende Tabelle. Es sei darauf hingeweisen, dass beide Tafeln die täglichen Salden beider Partein berichten (long position und short position). -#### Tafel A. Halter der Long Position von 10 Verträgen -|Tag (1)|Startsaldo (2)|Vorschusszahlung (3)|[Settlementpreis](http://boerse.ard.de/boersenwissen/boersenlexikon/settlement-preis-100.html) (4)| Änderung des Preises des (5)|Gewinn/Verlust (6)|Endsaldo (7)| -|:----------:|-------------:|------:|---:|---:|---:|---:| -|0|0|50|100.0| - | - |50| -|1|50|0|99.20| -0.80| -8|42| -|2|42|0|96.00| -3.20| -32|10| -|3|10|40|101.00|5.00|50|100| -|4|100|0|103.50|2.50|25|125| -|5|125|0|103.00| -0.50| -5|120| -|6|120|0|104.00|1.00|10|130| -#### Tafel B. Halter der Short Position von 10 Verträgen -|Tag (1)|Startsaldo (2)|Vorschusszahlung (3)|[Settlementpreis](http://boerse.ard.de/boersenwissen/boersenlexikon/settlement-preis-100.html) (4)| Änderung des Preises des (5)|Gewinn/Verlust (6)|Endsaldo (7)| -|:----------:|-------------:|------:|---:|---:|---:|---:| -|0|0|50|100.0| -| -|50 -|1|50|0|99.20| -0.80|8|58 -|2|58|0|96.00| -3.20|32|90 -|3|90|0|101.00|5.00| -50|40 -|4|40|0|103.50|2.50| -25| 15 -|5|15|35|103.00| -0.50| 5|55 -|6|55|0|104.00|1.00| -10|45|} -Der Tag des Vertragsabschlusses wird als'' Tag 0'' bezeichnet, an dem beide Parteien eine Vorschusszahlung von 50 USD hinterlegen. Wir nehmen an, dass am "Tag 1" der Preis des Futures auf 99,20 USD fällt, wie in Spalte 4 der Tafel A angegeben. In Spalte 5 können wir die Änderung des Preises des Futures sehen -0,80 USD (99,20 - 100) und dieser Betrag wird mit der Zahl der Verträge (10) multipliziert um in Spalte 6 den Gewinn/Verlust zu erhalten: -0,80 x 10 = - 8 USD. Der Endsaldo ist in Spalte 7 zu sehen, welcher dem Anfangssaldo des nächsten Tages entspricht. Der Endsaldo am Tag 1 für den Inhaber der Long-Position ist 42 USD und liegt somit über dem Mindestsaldo der Sicherheitsleistung (**maintenance margin**) von 3 x 10 USD = 30 USD, so dass keine Nachschuss erforderlich ist, um über diesen Wert zu kommen. -### Ethereum Clearinghaus Implementierung und Logik -* gilt es für alle Verträge? -* welches Falg muss gesetzt werden um die Clearinghaus zu ermöglichen? -* wie werden das Geld / Ether belastet / gutgeschrieben? Push oder Pull System? -* Normalerweise verwenden Clearinghäuser einen durchschnittlichen Tagespreis (nicht den Abschlusspreis). Wie ist das umsetzen? Dies ist wichtig um Preismanipulation zu VERMEIDEN! Ethereum würde noch mehr gefährdet sein als klassische Clearingstellen. -* Was passiert im Falle des Ausfalls (fehlerhafte Nachschussaufforderung)? Reputationssystem? -* viele Verträge benötigen einen externen Marktkurs (z.B. Goldpreis von CME oder LIBOR, kinssätze). Wie können sie damit gefüttert werden? -* kann Geld von der Clearingstelle zurückgebucht werden (z.B. überschüssige Mittel / Gewinne)? Es wäre einfacher, wenn dies nicht der Fall wäre. -* Was ist, wenn die Parteien wirklich den Vertragsgegenstand austauschen wollen? Z.B. keine Bargeld- / Ether- Abmachungen? (NICHT SUPPORTED VOM CLEARINGHAUS) -* Verluste / Gewinne werden durch durch die von der Clearingstelle zur Verfügung gestellten Hebel von Natur aus vergrößert. AKZEPTABEL FUER ETHERUEM? HINWEIS: OBWOHL DIE VOLLSTÄDIGE SUMME NICHT VORAB HINTERLEGT WERDEN BRAUCHT -### Code reference sample diff --git a/pages/other-languages/[Italian]-Impostare-il-proprio-ambiente-di-sviluppo-Ethereum.md b/pages/other-languages/[Italian]-Impostare-il-proprio-ambiente-di-sviluppo-Ethereum.md deleted file mode 100644 index 14537ccd2..000000000 --- a/pages/other-languages/[Italian]-Impostare-il-proprio-ambiente-di-sviluppo-Ethereum.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -name: Impostare il proprio ambiente di sviluppo Ethereum -category: ---- - -Lo sviluppo su Ethereum e’ stato concepito per essere estremamente facile da imparare per gli sviluppatori – e i linguaggi di programmazione sono abbastanza simili allo Javascript che chiunque conosca quel linguaggio dovrebbe acquisirne padronanza piuttosto velocemente. - -Ci sono tre programmi che ogni sviluppatore dovrebbe scaricare – Alethzero, Mist e Mix. - -* **Alethzero** e’ un client a interfaccia grafica con caratteristiche avanzate come chain private, force mining e una webkit suite completa. - -* **Mist** e’ il browser delle Dapp e il client per il mining nel quale gli utenti accederanno alle vostre Dapps. - -* Infine, **Mix** e’ un ambiente di sviluppo integrato – concepito appositamente per sviluppare e debuggare i contratti e i loro corrispettivi front-end. - -## Requisiti software: - -Impostare un ambiente di sviluppo dovrebbe essere abbastanza semplice per chiunque ha mai progettato una pagina web prima d’ora – abbiamo tre programmi specifici che dovreste scaricare: - -In primo luogo, [scaricate](https://github.com/ethereum/cpp-ethereum/wiki) l’ultima versione stabile di Alethzero, il nostro client scritto in C++, e installatelo sul vostro sistema operativo. Se avete problemi con l’ultima versione stabile di sviluppo, provate a passare alla versione cutting edge, che dovrebbe risolvere alcuni dei problemi. Se invece scegliete di fare un build della vostra versione, allora le istruzioni sono qui. - -In secondo luogo, installate [Mix](https://github.com/ethereum/cpp-ethereum/releases) il nostro ambiente di sviluppo integrato disponibile per Windows e Mac. Se utilizzate Linux, seguite le istruzioni qui per installare Mix. - -Infine, installate [Mist](https://github.com/ethereum/go-ethereum#automated-dev-builds) per testare le vostre Dapps e calibrare i vostri front-end a mano a mano che li sviluppate. - -## Extras - -Un text editor o Mix puo’ essere utilizzato per creare il codice backend dei contratti che scriveremo. Per il linguaggio Serpent vi suggeriamo di programmare il vostro editor affinche’ consideri i contratti scritti in Serpent e salvati con il suffisso ‘.se’ come sintassi python e per il linguaggio Solidity vi consigliamo di salvare i files con il suffisso ‘.sol’. - -Il live refresh non e’ raccomandato mentre lavorate sulla vostra front-end in html, dato che non e’ stato testato appieno. - -## Installare Alethzero - -Il nostro ambiente di sviluppo integrato Mix e’ al momento in constante sviluppo e nonostante alcune caratteristiche siano gia’ presenti in questo tutorial ci concentreremo principalmente sullo sviluppo dei contratti, e la costruzione dei frontend utilizzando il nostro client di sviluppo Alethzero. Alethzero ha un compilatore gia’ integrato, una console javascript, e gli strumenti necessari per dare un’occhiata allo stato della blockchain. - -A meno che non sia espressamente specificato, questo tutorial deve essere eseguito su Alethzero utilizzando una chain privata e senza connettersi alla rete – inserire contratti nella rete di test dovrebbe essere riservato a quei contratti che volete condividere con altri. Quando caricate alethzero in questa modalita’ e’ possibile che altri accedano alla vostra chain fintanto che utilizzano lo stesso nome e usano la funzione ‘connect-to-peer’ per connettersi direttamente. diff --git a/pages/other-languages/[Italian]-Introduzione-allo-sviluppo-su-Ethereum.md b/pages/other-languages/[Italian]-Introduzione-allo-sviluppo-su-Ethereum.md deleted file mode 100644 index 4bd0b33aa..000000000 --- a/pages/other-languages/[Italian]-Introduzione-allo-sviluppo-su-Ethereum.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -name: Introduzione allo sviluppo su Ethereum -category: ---- - -_traduzione in Italiano da [Dapps for beginners blog => Introduction to development on Ethereum](https://dappsforbeginners.wordpress.com/tutorials/introduction-to-development-on-ethereum/)_ - -# Ethereum – una rete di consenso decentralizzato - -Per la maggior parte degli sviluppatori imparare come utilizzare una nuova piattaforma, o un linguaggio di programmazione, o un nuovo framework rappresenta un compito familiare, probabilmente ripetuto dozzine di volte durante la loro carriera. Molto diverso e’ l’imparare a sviluppare per un paradigma completamente differente. La rete di consenso decentralizzato, la blockchain, e la sua implementazione piu’ conosciuta ‘bitcoin’ non sono ben compresi neppure dalla comunita’ degli sviluppatori e le sfumature di come questa tecnologia sia radicalmente diversa da cio’ che abbiamo utilizzato fino ad ora sono certamente ignote alla maggior parte del pubblico. - -Tenendo cio’ a mente, prima di procedere a costruire la nostra prima decentralised apps indicheremo l'insieme di quelle tecnologie principali che servono a creare un network di consenso decentralizzato, e la teoria dei giochi che fa uso di queste tecnologie per creare un network. - -## Tecnologie principali - -**[Crittografia a chiave pubblica (anche deta crittografia asimmetrica)](http://it.wikipedia.org/wiki/Crittografia_asimmetrica)** - -La crittografia asimmetrica e’ quell'insieme di metodi di criptazione che richiede la creazione di due chiavi separate; la “chiave privata” - che e’ nota solo al proprietario - e la “chiave pubblica” che e’ nota a chiunque. Questo tipo di crittografia possiede una serie di utili attributi, il primo e’ che chiunque e’ in grado di criptare dati con una chiave pubblica che possono essere decriptati solamente dalla chiave privata. - -Il secondo e’ l’abilita’ per il possessore della chiave privata di “firmare” qualsiasi informazione utilizzando la propria chiave privata, affinche' chiunque abbia la chiave pubblica possa verificare la firma, ma senza che si rilascino informazioni sulla chiave privata. Questo secondo attributo e’ usato per il sistema di account in un network di consenso decentralizzato, e sta alla base dell’invio delle transazioni. - -**[Funzione crittografica di hash](http://it.wikipedia.org/wiki/Funzione_crittografica_di_hash)** - -Una funzione di hash e’ una funzione che prende un segmento di informazione di qualsiasi dimensione e lo mappa su un altro segmento di dimensione fissa, e.g. un file di 1MB o di 500kb - se vengono sottoposti ad una funzione di hash - producono “hashes” di 128 bit di dimensione ciascuno. Una funzione crittografica di hash assolve a questo compito e lo fa anche rispettando tre importanti requisiti: 1) non viene fornita nessuna informazione su che tipo di dati abbiano prodotto l’hash (ovvero, la funzione e’ irreversibile), 2) una piccola variazione nel dato di input produce un hash estremamente differente, in modo che l’hash non puo’ essere calcolato se non utilizzando la funzione di hash (ovvero, niente scorciatoie!!), 3) c’e’ una probabilita’ estremamente bassa che due dati di input diversi producano lo stesso hash. - -**[Il networking peer-to-peer](http://it.wikipedia.org/wiki/Peer-to-peer)** - -A differenza del modello “Client-Server”, il modello “peer-to-peer” consiste di reti di computer connessi direttamente l’un l’altro, senza che questi inoltrino alcuna richiesta ad un server centrale. Tutti i computer che fanno parte della rete sono considerati “peers” (pari, in inglese) e mantengono l’un l’altro una posizione paritaria all’interno della rete stessa. Le reti "peer-to-peer" generalmente si basano sull’altruismo, ovvero ogni computer fornisce alla rete almeno lo stesso ammontare di risorse che trae dalla stessa. - -##Tecnologie della cripto-economia - -**[La Blockchain](http://it.wikipedia.org/wiki/Bitcoin#Tecnologia)** - -La Blockchain in tutte le sue incarnazioni e’ un tipo di database progettato specificatamente per essere utilizzato in una rete di consenso decentralizzato. Puo’ contenere qualsiasi informazione, e puo’ stabilire delle regole sulla maniera in cui l’informazione viene aggiornata. La sua caratteristica principale e’ che viene aggiornata a spezzoni chiamati “blocchi” che sono “incatenati” usando degli hashes del contenuto dei blocchi precedenti. Una blockchain contiene non solo l’informazione contenuta attualmente nel database, ma anche ogni cambiamento apportato al database nel corso della sua storia. Dati lo stato e le transazioni, la blockchain rappresenta un database con una storia completa che non puo’ essere alterata senza alterare ciascuno dei blocchi successivi. Una chiave privata crittografica firma ogni “transazione” o richiesta di cambiare lo stato del database, e la firma stessa e’ custodita nella blockchain. - -**[La Proof-of-work](http://it.wikipedia.org/wiki/Proof-of-work)** - -Pensato inizialmente come un sistema per prevenire lo spam, il sistema di proof of work e’ un semplice metodo per assicurarsi che tu abbia ***probabilmente*** compiuto una grande quantita’ di operazioni matematiche. E’ implementato nella maggior parte dei casi utilizzando una funzione di hash crittografica; dato un segmento di informazione arbitrario, (ad esempio come una lista di transazioni e l’intestazione di un blocco) devi trovare un secondo segmento di infromazione che, unito al primo, produce un hash che ha determinate caratteristiche (come ad esempio un certo numero di zeri consecutivi). Dato che e’ impossibile predirre quale e’ il secondo segmento di informazione che produrra’ l’hash richiesto, devi iterare casualmente attraverso tutti i dati possibili finche’ non trovi quel segmento di dati che produce l’hash di cui hai bisogno. - -## Tecnologie di Ethereum - -**La Ethereum Virtual Machine** - -La Ethereum Virtual Machine e’ l’innovazione principale del progetto Ethereum. Si tratta di una virtual machine progettata per essere eseguita da tutti i partecipanti in una rete peer-to-peer, puo’ leggere e scrivere su una blockchain sia codice eseguibile che dati, verificare firme digitali, e puo’ far girare codice in maniera quasi Turing-completa. Eseguira’ del codice solo quando riceve un messaggio verificato da una firma digitale, e quando l’infomazione che e’ contenuta nella blockchain le dira’ che e’ appropriato farlo. - -**La Rete di Consenso Decentralizzato e la Blockchain Generalizzata** - -Ethereum e’ una rete peer to peer dove ogni peer salva la stessa copia del database blockchain e fa girare una Ethereum virtual machine per mantenere ed alterare il suo stato. La Proof of work e’ integrata nella tecnologia blockchain facendo si’ che la creazione di un nuovo blocco richieda che tutti i membri del network realizzino la proof-of-work. Il consenso e’ ottenuto tramite l’incentivizzazione per i peer ad accettare sempre la sequenza piu’ lunga di blocchi nella blockchain mediante la distribuzione di un gettone di valore crittografico: l’ether. - -In questo modo abbiamo una nuova tecnologia che sicuramente non rientra nel modello client-server ma non si qualifica neppure all’interno di un tradizionale modello peer-to-peer in quanto la sua esistenza e’ incentivizzata, ovvero si puo’ ragionevolmente stare certi che provvedera’ un servizio deterministico consistente. - -Data la sua natura allargata e la sicurezza criptografica costruita al suo interno puo’ fungere da third party, capace di arbitrare senza fiducia e senza interferenza di parti esterne. Attraverso l’uso di decisioni tipiche del sistema di cryptocurrencies fatte dal software possiamo avere conseguenze finanziarie per le persone, le organizzazioni o persino per altro software. - -Cio’ da’ agli sviluppatori un nuovo modo per rendere possibili le interazioni tra le parti su internet. - -Mentre spiegheremo i vari temi dello sviluppo delle decentralized apps illustreremo il motivo del loro utilizzo e faremo del nostro meglio per spiegare l’importanza di ciascuna. - -### Ulteriori letture - -* [Libro Bianco di Ethereum - tradotto in Italiano ](https://github.com/ethereum/wiki/wiki/%5BItalian%5D-Libro-Bianco) -* [Yellow Paper di Ethereum, la specificazione formale - inglese](https://github.com/ethereum/yellowpaper) -* [Blog di Ethereum - inglese](https://blog.ethereum.org/) - -_traduzione di M.Terzi - @terzim - [LinkedIn](https://uk.linkedin.com/in/massimilianoterzi)_ diff --git a/pages/other-languages/[Italian]-Libro-Bianco.md b/pages/other-languages/[Italian]-Libro-Bianco.md deleted file mode 100644 index c5a8f20b2..000000000 --- a/pages/other-languages/[Italian]-Libro-Bianco.md +++ /dev/null @@ -1,503 +0,0 @@ ---- -name: Libro Bianco -category: ---- - -Ethereum: Libro Bianco - White Paper (di Leonardo Maria Pedretti: lm.pedretti@gmail.com) -[Linkedin](https://www.linkedin.com/in/leonardompedretti) - -### Una Piattaforma di Nuova Generazione per i Contratti Intelligenti e le Applicazioni Decentralizzate - -Quando Satoshi Nakamoto diede per primo inizio, nel Gennaio 2009, alla blockchain del Bitcoin, stava introducendo due concetti radicali e, fino ad allora, mai testati. Il primo è il "bitcoin", una moneta online peer-to-peer decentralizzata che mantiene un valore senza nessun supporto, [valore intrinseco](http://bitcoinmagazine.com/8640/an-exploration-of-intrinsic-value-what-it-is-why-bitcoin-doesnt-have-it-and-why-bitcoin-does-have-it/) o emittente centrale. Finora, il "Bitcoin", nella veste di unità monetaria, ha catalizzato la maggior parte dell'attenzione del pubblico, sia in termini di aspetti politici di una moneta senza una banca centrale, sia per l' estrema volatilità, verso l'alto e verso il basso, del prezzo. Comunque c'è anche un'altra, ugualmente importante, parte del grandioso esperimento di Satoshi: il concetto di una blockchain basata sul proof-of-work, che garantisce un pubblico consenso sul sistema delle transazioni. Il Bitcoin, nella veste di applicazione, può essere descritto come un sistema first-to-file: se un'entità ha 50 BTC, e simultaneamente invia gli stessi 50 BTC ad A e a B, solamente la transazione che viene confermata per prima sarà processata. Precedentemente non esisteva alcun modo intrinseco per determinare quale delle due transazioni fosse avvenuta prima, e per decenni ciò ha ostacolato lo sviluppo delle monete digitali decentralizzate. La blockchain di Satoshi era la prima soluzione decentralizzata. Attualmente, l'attenzione sta iniziando rapidamente a spostarsi verso questa secondo risvolto della tecnologia Bitcoin, ed, in particolare, come il concetto di blockchain possa essere utilizzato per qualcosa di più che il denaro. - -Tali nuove applicazioni, includono l'utilizzo di risorse digitali sulla blockchain per rappresentare valute personalizzate e strumenti finanziari (["monete colorate"](https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit)), la proprietà di un dispositivo fisico sottostante (["proprietà intelligente"](htups://en.bitcoin.it/wiki/Smart_Property)), assets non fungibili, quali nomi di dominio ("Namecoin") così come le più avanzate applicazioni tipo un exchange decentrallizzato, derivati finanziari, il gioco d'azzardo peer-to-peer ed il sistema di identità e di reputazione sulla blockchain. Un'altra importante area di indagine sono i "contratti intelligenti" - sistemi che trasferiscono automaticamente assets digitali, in accordo con regole pre-impostate. Per esempio, si potrebbe avere un contratto di tesoreria nella forma "A può trasferire a X alcune unità di moneta al giorno, B può trasferire a Y alcune unità di moneta al giorno, A e B insieme non possono trasferire niente, ed A può precludere l' "abilità di trasferire" di B. La logica estensione di ciò sono le [organizzazioni autonome decentralizzate](http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/) (DAOs) - contratti intelligenti a lungo termine che gestiscono assets e codificano lo statuto di un'intera organizzazione. Quello che Ethereum intende garantire è una blockchain con una linguaggio di programmazione di Turing, completo e costruito al suo interno, che può essere usato per creare "contratti" e per codificare le funzioni arbitrarie di transizione, permettendo agli utenti di creare uno dei sistemi sopra descritti, così come molti altri che ancora non abbiamo immaginato, semplicemente scrivendo la logica in poche righe di codice. - -### Tavola dei Contenuti - -* [Storia](#Storia) - * [Bitcoin come un Sistema di Transizione di Stato](#Bitcoin-come-un-Sistema-di-Transizione-di-Stato) - * [Mining](#mining) - * [Merkle Trees](#merkle-trees) - * [Applicazioni Alternative della Blockchain](#applicazioni-alternative-della-blockchain) - * [Scripting](#scripting) -* [Ethereum](#ethereum) - * [Portafogli Ethereum](#portafogli-Ethereum) - * [Messaggi e Transazioni](#messaggi-e-Transazioni) - * [Ethereum come un Sistema di Transizione di Stato](#ethereum-come-un-sistema-di-transizione-di-stato) - * [Esecuzione del Codice](#esecuzione-del-codice) - * [Blockchain e Mining](#blockchain-e-mining) -* [Applicazioni](#applicazioni) - * [Sistemi di Token](#sistemi-di-token) - * [Derivati Finanziari](#derivati-finanziari) - * [Sistema di Identità e Reputazione](#sistemi-di-identità-e-reputazione) - * [Storage Decentralizzato dei File](#storage-decentralizzato-dei-file) - * [Organizzazioni Decentralizzate Autonome](#organizzazioni-decentralizzate-autonome) - * [Ulteriori Applicazioni](#ulteriori-applicazioni) -* [Miscellanea e Relazioni](#miscellanea-e-relazioni) - * [Implementazione GHOST Modificata](#implementazione-ghost-modificata) - * [Commissioni](#commissioni) - * [Calcolo e Completezza di Turing](#calcolo-e-completezza-di-turing) - * [Moneta ed Emissione](#moneta-ed-emissione) - * [Centralizzazione del Mining](#centralizzazione-del-mining) - * [Scalabilità](#scalabilità) -* [Conclusioni](#conclusioni) -* [Riferimenti ed Ulteriori Letture](#riferimenti-ed-ulteriori-letture) - -## Introduzione al Bitcoin ed ai Concetti Esistenti - -### Storia - -Da decenni sta circolando l'idea di una moneta digitale decentralizzata, così come delle applicazioni alternative come i registri di proprietà. I protocolli anonimi di moneta digitale degli anni '80 e degli anni '90, dipendenti soprattutto su una crittografia primitiva conosciuta come Chaumian blinding, furono rilasciati da una moneta con un alto tasso di privacy, tuttavia questi fallirono principalmente per non essere riusciti a guadagnare terreno, a causa della loro dipendenza da un intermediario centralizzato. Nel 1998, Wei Dai's [b-money](http://www.weidai.com/bmoney.txt) divenne il primo progetto ad introdurre l'idea di creare una moneta attraverso la soluzione di puzzle computazionali assieme al consenso decentralizzato, tuttavia il progetto non offriva sufficienti dettagli su come questo consenso decentralizzato potesse essere concretamente attualizzato. Nel 2005, Hal Finney introdusse il concetto del "[proofs of work riutilizzabile](http://www.finney.org/~hal/rpow/)", un sistema che utilizza le idee provenienti dalla b-moneta, insieme ai puzzle computazionali Hashcash di Adam Back, per creare un concetto di criptomoneta, ma, ancora una volta, non si riuscii ad ottenere il suddetto fine, perché anche quest'ultimo progetto si basava su un calcolo computazionale garantito come back-end. - -Poiché la moneta è un'applicazione first-to-file, dove l'ordine delle transazioni è spesso di cruciale importanza, le monete decentralizzate richiedono una soluzione al consenso decentralizzato. L'innovazione fornita da Satoshi è l'idea di riuscire a combinare un protocollo molto semplice basato su dei nodi su cui avvengono le transazioni, che danno vita ad una sempre crescente blockchain, attraverso la creazione di "blocchi" ogni 10 minuti, con il proof of work come meccanismo attraverso cui i nodi guadagnano il diritto di partecipare al sistema. Mentre i nodi con una grande quantità di potenza di calcolo hanno proporzionalmente maggiore influenza, raggiungere più potenza computazionale rispetto l'intero network è più difficile rispetto al simulare milioni di nodi. Nonostante la crudezza e la semplicità del modello blockchain del Bitcoin, esso ha dimostrato di essere sufficientemente valido, e nel corso dei successivi cinque anni sarebbe diventato il fondamento di oltre duecento monete e protocolli di tutto il mondo. - -### Bitcoin come un Sistema di Transizione di Stato - -![statetransition.png](http://vitalik.ca/files/statetransition.png?2) - -Il libro mastro del Bitcoin può essere pensato, da un punto di vista tecnico, come un sistema di transizione di stato, dove c'è uno "stato" consistente nella proprietà dello status di tutti i Bitcoins esistenti e "la funzione di transizione di stato", che riceve uno stato ed una transizione e trasmette un nuovo stato che ne costituisce il risultato. Nel sistema bancario tradizionale, per esempio, lo stato è il documento costituente il saldo, una transazione è una richiesta di movimentare $X da A a B, e la funzione di transizione di stato sottrae un valore nel conto corrente di A equivalente $X ed incrementa il valore di $X nel conto corrente bancario di B. Se nel conto corrente di A ci sono meno che $X, la funzione di transizione di stato segnala un errore. Quindi, si può formalmente definire: - - APPLY(S,TX) -> S' or ERROR - -Nel sistema bancario definito in precedenza: - - APPLY({ Alice: $50, Bob: $50 },"send $20 from Alice to Bob") = { Alice: $30, Bob: $70 } - -Ma: - - APPLY({ Alice: $50, Bob: $50 },"send $70 from Alice to Bob") = ERROR - -Lo "stato" nel Bitcoin è la raccolta di tutte le monete (tecnicamente, "transazioni in uscita non spese" oUTXO) che sono state effettuate ma non ancora spese, con ogni UTXO che ha una denomoninazione ed un proprietario (definito da un indirizzo da 20-byte che è essenzialmente una chiave crittografica pubblica[1]). Una transazione contiene uno o più inputs, con ogni input che contiene un riferimento ad un UTXO esistente ed una firma crittografica prodotta da una chiave privata associata all'indirizzo del proprietario, ed uno o più outputs, con ogni outpout contenente un nuovo UTXO che deve essere aggiunto allo stato. - -1. Per ogni input in `TX`: - * Se il riferimento UTXO non è in `S`, si ha un errore. - * Se la firma provvista non combacia con il proprietario del UTXO, si ha un errore. -2. Se la somma dei valori di tutti gli input UTXO è inferiore alla somma dei valori di tutti gli outpout UTXO, si ha un errore. -3. Si ha `S` con tutti gli input UTXO meno tutti gli outpout UTXO aggiunti. - -La prima parte del primo step previene che i mittenti delle transazioni possano spendere monete che non esistono, la seconda del primo step previene ai mittenti delle transazioni di spendere monete di altre persone, ed il secondo step fa rispettare la conservazione del valore. Al fine di utilizzare ciò per il pagamento, il protocollo è il seguente. Supponiamo che Alice voglia inviare 11.7 BTC a Bob. Per primo, Alice controllerà di possedere un set di UTXO, che ammonta ad almeno 11.7 BTC. Realisticamente, Alice non sarà in grado di ottenere esattamente 11.7 BTC; si può dire che il valore più piccolo che può ottenere è 6+4+2=12. Lei poi crea una transazione con quei tre inputs ed i due outputs. Il primo output sarà 11.7 BTC con l'indirizzo che appartiene a Bob, ed il secondo output sarà il rimanente 0.3 BTC "scambiato", essendo Alice stessa il proprietario. - -### Mining - -![block_picture.jpg](http://vitalik.ca/files/block_picture.png) - -Se abbiamo avuto accesso a un servizio centralizzato di fiducia, ciò potrebbe essere banale da implementare; esso potrebbe essere codificato esattamente come descritto. Tuttavia, con i Bitcoin noi abbiamo provato a costruire un sistema monetario, combinando il sistema di transizione di stato con un sistema di consenso al fine di assicurare che ognuno sia d'accordo sull'ordine delle transazioni. Il processo di consenso decentralizzato del Bitcoin richiede l'esistenza dei nodi nel network, che continuamente tentano di produrre pacchetti di transazioni chiamati "blocchi". Il network è destinato a produrre all'incirca un blocco ogni dieci minuti, con ogni blocco che contiene una marca temporale, un numero, un riferimento a (ad esempio l'hash del) precedente blocco e una lista di tutte le transazioni che sono avvenute dal precedente blocco. Con il passare del tempo, questo crea una persistente, sempre crescente, "blockchain" che si aggiorna costantemente per rappresentare l'ultimo stato del libro mastro del Bitcoin. - -L'algoritmo per controllare la validità di un blocco, espresso in questo paradigma, è il seguente: - -1. Controllo se il blocco precedente esiste ed è valido. -2. Controllo se la marca temporale del blocco è più grande del blocco precedente[2] ed è inferiore di 2 ore nel futuro. -3. Controllo se il proof of work sul blocco è valido. -4. Sia `S[0]` lo stato alla fine del blocco precedente. -5. Si supponga `TX` la lista della transazione del blocco con `n` transazioni. Per tutti `i` in `0...n-1`, sia impostato `S[i+1] = APPLY(S[i],TX[i])` Se da qualsiasi applicazione risulti un errore, esce e ritorna falso. -6. Ritorna vero, e registra `S[n]` come uno stato alla fine del blocco. - -In definitiva, ogni transazione del blocco deve fornire una transazione di stato che sia valida. Si noti che ogni stato non è codificato, in nessun modo, nel blocco; esso è puramente una astrazione da ricordare per la validazione del nodo e può solo essere (in modo sicuro) computata, per qualsiasi nodo, iniziando dallo stato di genesi e applicata sequenzialmente ad ogni transazione in ogni nodo. Si noti che è importante l'ordine nel quale ogni miner include le transazioni nel blocco; se ci sono due transazioni A e B nel blocco tale che B impiega una UTXO creata da A, poi il blocco sarà validato se A viene prima di B ma non viceversa. - -La parte interessante dell'algoritmo di validazione del blocco è il concetto di "proof of work": la premessa è che l'hash SHA256 di ogni blocco, costituito come un numero di 256-bit, deve essere inferiore di un target regolato dinamicamente, che è al tempo di questo scritto approssimativamente 2192. Lo scopo di ciò è di rendere computazionalmente "difficile" la creazione di un blocco, prevenendo con ciò agli attacchi sibilla dal ricreare l'intera blockchain a loro favore. Poichè SHA256 è progettato per essere una funzione completamente imprevedibile e pseudo-randomica, l'unico modo di creare un blocco valido è semplicemente un test, con l'incremento ripetuto del numero controllando se il nuovo hash corrisponde. Al target corrente di 2192, questo significa un media di 264 tentativi; in generale, il target è ricalibrato dal network ogni 2016 blocchi in modo che, in media, un nuovo blocco è prodotto, ogni dieci minuti, da qualche nodo nel network. Nella prospettiva di compensare i miners per questo lavoro computazionale, ogni dieci minuti il miner è autorizzato ad includere una transazione donando a se stesso 25 BTC da nulla. In aggiunta, se qualche transazione ha un valore totale denominale più alto nei suoi inputs che ne suoi outputs, la differenza va al miner come "commissione di transazione". Incidentalmente, questo è pure l'unico meccanismo attraverso cui avviene l'emissione dei BTC; in assoluto lo stato di genesi non contiene alcuna moneta. - -Nella prospettiva di una migliore comprensione dello scopo del mining, esaminiamo il caso in cui avvenga un attacco criminoso. Visto che la crittografia implicita nel Bitcoin è nota per essere sicura, l'attaccante colpirà l'unica parte del sistema del Bitcoin che non è protetta direttamente dalla crittografia: l'ordine delle transazioni. La strategia dell'attaccante è semplice: - -1. Invio 100 BTC ad un commerciante in cambio di qualche prodotto (preferibilmente un bene digitale consegnabile rapidamente) -2. Attesa per la consegna del prodotto -3. Produzione di un'altra transazione che invia 100 BTC a se stesso -4. Tentativo di convincere il network che la sua transazione a se stesso era quella che è avvenuta per prima. - -Una volta avvenuto lo step (1), dopo qualche minuto qualche miner includerà la transazione nel blocco, ad esempio il blocco numero 270000. Dopo circa un'ora, cinque o più blocchi saranno aggiunti alla chain dopo quel blocco, con ognuno di questi blocchi che indirettamente indicano la transazione e quindi la "confermano". A questo punto, il commerciante accetterà il pagamento come finalizzato e consegnerà il prodotto; considerato che stiamo assumendo che questo sia un bene digitale, consegnato in un istante. Adesso, l'attaccante crea un'altra transazione inviando i 100 BTC a se stesso. Se l'attaccante semplicemente la rilascia, questa non sarà processato; i miners proveranno ad eseguire `APPLY(S,TX)` e prendere nota che `TX` consuma un UTXO che non è più nello stato. Invece, in questo modo, l'attaccante crea una "fork" della blockchain, iniziando a minare un'altra versione del blocco 270000 indirizzando il blocco 269999 come una antecedente ma con una nuova transazione che prende il posto di quella vecchia. Poiché i dati del blocco sono differenti, ciò richiede il rifacimento della "proof-of-work". Inoltre, la nuova versione del blocco 270000 dell'attaccante ha un hash differente, così i blocchi originali da 270001 a 270005 non "conducono" a quello; quindi, la chain originale e quella nuova dell'attaccante saranno completamente separate. La regola è che, nel caso di fork, la blockchain più lunga è considerata essere quella vera e così i legittimi minatori lavoreranno sulla chain del 270005, mentre l'attaccante sta lavorando da solo sulla chain del 270000. Affinché l'attaccante crei la blockchain più lunga, egli dovrebbe avere più potenza computazionale che il resto del network per ottenere (da quel momento, "51% attacco"). - -### Merkle Trees - -![SPV in bitcoin](https://raw.githubusercontent.com/ethereum/www/master-postsale/src/extras/gh_wiki/spv_bitcoin.png) - -_Sinistra: è sufficiente mostrare solo un esiguo numero di nodi in un Merkle tree per avere la prova della validità di un ramo._ - -_Destra: qualunque tentativo di modificare qualsiasi parte del Merkle tree porterà ad un'incongruenza da qualche parte a monte della chain._ - -Un'importante funzione della scalabilità del Bitcoin è che nel blocco è memorizzata una struttura di dati multi-livello. L' "hash" di un blocco è in realtà solo l'hash dell'intestazione del blocco, approssimativamente 200-byte di dati che contengono la marca temporale, un numero, hash del precedente blocco e l'hash principale della struttura dei dati chiamata Merkle tree che contiene tutte le transazioni del blocco. Un Merkle tree è un tipo di struttura binaria, composto da un set di nodi, con un grande numero di nodi dipendenti alla base della struttura, che contengono dati sottostanti, un insieme di nodi intermedi dove ogni nodo è l'hash dei suoi due figli, e alla fine un nodo singolo principale, anch'esso composto dall'hash dei suoi due "figli", che rappresenta l'apice della struttura. La finalità del Merkle tree è quello di consentire che i dati in un blocco siano consegnati in maniera frammentaria: un nodo può scaricare solo l'intestazione di un blocco da una sorgente, la piccola parte della struttura di loro interesse da un'altra sorgente, per assicurarsi che tutti i dati siano correnti. Il motivo per cui questo funziona è che gli hash si propagano verso l'alto: se un utente malevolo tenta di cambiare una transazione falsa verso il punto più basso del Merkle tree, ciò causerà un cambio sul nodo di sopra, e poi un cambio sul nodo sopra quest'ultimo, per cambiare, infine, la struttura principale e pertanto l' hash del blocco, causando che il protocollo registri questo come un blocco completamente differente (quasi certamente con un proof of work invalido). - -Il protocollo Merkle tree è, senza dubbio, essenziale per la sostenibilità a lungo termine. Un "nodo completo" nel Bitcoin network, uno che memorizza ed elabora l'interezza di ogni blocco, richiede all'incirca 15 GB di spazio sul disco nel Bitcoin network alla data di Aprile 2014, e sta crescendo di oltre un gigabyte al mese. Allo stato attuale, ciò è sostenibile per un computer desktop e non per i telefoni, e più in là con il tempo potranno partecipare solo le aziende e gli appassionati. Un protocollo conosciuto come "controllo semplificato del pagamento" (CSP) permette ad un'altra classe di nodi di esistere, chiamati "nodi leggeri", che scaricano le intestazioni del blocco, verificando la proof of work sulle intestazioni del blocco, e successivamente scaricano solo i "rami" associati con le transazioni che sono per loro rilevanti. Questo permette ai nodi leggeri di determinare con una forte garanzia di sicurezza quale sia lo status di una qualsiasi transazione Bicoin, ed il loro corrente bilancio, con soltanto il download di una piccolissima parte dell'intera. - -### Applicazioni Alternative della Blockchain - -L'idea di prendere spunto dalla tecnologia sottostate alla blockchain e di applicarla anche ad altri concetti ha una storia. Nel 2005, Nick Szabo propose il concetto di "[titoli di proprietà sicuri con l'autorizzazione del proprietario](http://szabo.best.vwh.net/securetitle.html)", un documento che descriveva come "nuovi progressi nella tecnologia di un database replicato" consentiranno ad un sistema basato sulla blockchain di conservare un registro di chi possegga una determinata terra, creando un quadro elaborato che include concetti come quello di autosufficienza economica, usucapione e le tasse sulla terra Georgiana. Tuttavia, sfortunatamente, non era disponibile all'epoca un sistema efficace di database replicato, ed il protocollo non fu mai implementato concretamente. Ciononostante, dal 2009 cominciò rapidamente ad emergere, dopo lo sviluppo del consenso decentralizzato del Bitcoin, un numero di applicazioni alternative. - -* **Namecoin** - creato nel 2010, [Namecoin](https://namecoin.org/) conosciuto come un sistema decentralizzato di database per la registrazione di nomi di dominio. Nei protocolli decentralizzati come Tor, Bitcoin e BitMessage, è necessario un modo di identificare gli account in modo che le persone possano interagire tra loro, ma in tutte le soluzioni esistenti l'unico tipo di identificatore disponibile è un hash pseudo casuale come `1LW79wp5ZBqaHW1jL5TCiBCrhQYtHagUWy`. Idealmente, qualcuno potrebbe avere un account con un nome come "george". Tuttavia, il problema è che se una persona può creare un account chiamato "george" poi qualcun altro potrà utilizzare lo stesso processo per registrare "george" per se stesso così come per impersonificare quell'altra persona. L'unica soluzione è il paradigma first-to-file, dove il primo registrante ha successo ed il secondo fallisce - un problema che si adatta perfettamente al protocollo di consenso del Bitcoin. Namecoin è la più vecchia, e di più successo, implementazione di un sistema di registrazione di dominio che utilizza una tale idea. -* **Monete colorate** - lo scopo delle [monete colorate](https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit) è quello di servire come un protocollo per consentire alle persone di creare le proprie valute digitali - o tokens digitali sulla Blockchain del Bitcoin, nel caso frequente e rilevante di una moneta con una sola unità. Nel protocollo delle monete colorate, una persona "emette" una nuova moneta assegnando pubblicamente un colore ad una UTXO specifica del Bitcoin, e il protocollo definisce ricorsivamente il colore dell'altra UTXO al fine che sia dello stesso colore degli inputs di quella transazione da cui deriva (qualche regola speciale si applica nel caso di inputs di colori di monete misti). Ciò permette agli utenti di conservare portafogli di monete che contengono solo una UTXO di uno specifico colore e di inviare questa in modo del tutto simile ai Bitcoins, attraverso lo studio della blockchain per determinare il colore di un qualsiasi UTXO che gli stessi hanno ricevuto. -* **Metacoins** - l'idea dietro un metacoin è quello di avere un protocollo che vive al vertice del Bitcoin, usando le transazioni Bitcoin per conservare le transazioni metacoin, ma avendo una differente funzione di transazione, `APPLY'`. Poiché il protocollo Metacoin non può prevenire che una transazione metacoin invalida sia visualizzata sulla blockchain del Bitcoin, si aggiunge una regola che se `APPLY'(S,TX)`ritorna come un errore, le impostazioni predefinite del protocollo sono`APPLY'(S,TX) = S`. Ciò fornisce un semplice meccanismo per la creazione di un protocollo arbitrario di criptomoneta con funzioni potenzialmente avanzate, che non possono essere implementate all'interno del Bitcoin stesso, ma con un costo di sviluppo molto basso visto che la complessità del mining e del networking sono già gestiti dal protocollo Bitcoin. - -Così, in generale, esistono due approcci per la costruzione di un protocollo di consenso: costruire un network indipendente, e costruire un protocollo sul modello di quello del Bitcoin. Il primo approccio è difficile da implementare, anche se ha avuto un buon successo in applicazioni come Namecoin; ogni implementazione individuale necessità una nuova ed indipendente blockchain, così come la costruzione ed il testing di tutta la transizione di stato ed il codice del network. Per di più, si ipotizza che il set di applicazioni per una tecnologia di consenso decentralizzato seguirà la "power law distribution" dove la maggior parte delle applicazioni sarebbe troppo piccola da garantire la loro propria blockchain, e si noti che esistono grandi classi di applicazioni decentralizzate, in particolare le organizzazioni autonome decentralizzate, che necessitano di interagire tra loro. - -D'altro canto, l'approccio basato sul Bitcoin, ha il difetto di non avere la funzione di verificazione semplificata del Bitcoin. SPV funziona per il Bitcoin perché può impiegare la grandezza della Blockchain come un proxy per la validità; ad un certo punto, una volta che le transazioni precedenti ad un'altra saranno sufficientemente validate, si potrà confermare la legittimità a far par dello stato. I meta-protocolli basati sulla Blockchain, d'altro canto, non possono forzare quest'ultima a non includere le transazioni che non sono valide all'interno del contesto del loro stesso protocollo. Da ciò, un'implementazione di un meta-protocollo SPV altamente sicuro necessiterebbe di analizzare tutte le transazioni fino all'inizio della Blockchain del Bitcoin per determinare quali siano le transazioni valide e quali quelle invalide. Allo stato attuale, tutta la "luce" di implementazioni di meta-protocolli basati sul Bitcoin si basano su un server di fiducia per fornire i dati; probabilmente questo è uno dei migliori risultati possibili soprattutto quando uno degli scopi principali di una Criptovaluta è quello di eliminare la necessità di fiducia. - -### Scripting - -Attualmente il protocollo del Bitcoin, perfino senza nessuna estensione, facilita una debole versione del concetto di "smart contracts". UTXO in Bitcoin può essere posseduta non solo come chiave pubblica, ma anche da uno script più complesso espresso in un semplice linguaggio di programmazione stack-based. In questo paradigma, una spesa di transazione che UTXO deve fornire un dato che soddisfa lo script. Infatti, il meccanismo basico della proprietà della chiave pubblica è implementato con uno script: lo script impiega una firma a curva ellittica come input, confrontando questa con la transazione e l'indirizzo che possiede la UTXO, e ritorna 1 se la verificazione è andata a buon fine altrimenti 0 in caso contrario. Altri scripts più complessi esistono per i più svariati casi. Per esempio, si può costruire uno script che richiede firme da due delle tre chiavi private impiegate per validare ("multisig"), un setup utile per conti delle società, che mettono al sicuro i conti correnti e che forniscono ai commercianti funzioni di escrow. Gli scripts possono anche essere usati per pagare premi per la soluzione di problemi computazionali, e si può perfino costruire uno script che affermi qualcosa come "questo Bitcoin UTXO è tuo se sei in grado di dare prova di un SPV che tu mi invii una transazione di Dogecoin di questo valore", consentendo essenzialmente un cambio tra cripto-monete. - -Tuttavia, il linguaggio di scripting, così come implementato nel Bitcoin, presenta alcune importanti limitazioni: - -* **Manca di completezza del linguaggio di Turing**- vale a dire, mentre esiste un grande sottoinsieme di calcolo che il linguaggio di scripting del Bitcoin supporta, quest'ultimo non supporta quasi tutto. La categoria principale che viene meno è il loop. Questo è reso possibile per evitare cicli infiniti durante la verifica delle transazioni; teoricamente ciò è un ostacolo sormontabile per il programmatori di script, visto che qualsiasi loop può essere simulato semplicemente ripetendo il codice sottostante tante volte con un'istruzione "if", implicando scripts inefficienti dal punto di vista dello storage. Per esempio, l'implementazione di un algoritmo alternativo di firma a curva ellittica necessiterebbe 256 rounds di moltiplicazioni ripetute e tutte incluse individualmente nel codice. -* **Cecità-del-valore** - non c'è un modo per un UTXO di fornire un controllo a setaccio sull'ammontare ritirabile. Per esempio, un buon caso di studio può consistere in un contratto oracolo con un contratto sottostante, dove A e B mettere in valore di $ 1000 di BTC e dopo 30 giorni lo script invia il controvalore di $1000 in BTC ad A ed il resto a B. Ciò necessiterebbe di un oracolo per determinare il valore di 1 BTC in USD, ma anche in questo caso c'è un incremento esponenziale, sia in termini di fiducia che di infrastruttura necessaria, per soluzioni, attualmente disponibili, completamente centralizzate. Tuttavia, poiché UTXO sono tutte-o-nessuna, l'unico modo per raggiungere questo risultato è attraverso l'inefficiente hack di avere molte UTXO di varie denominazioni (es. una UTXO di 2k per ogni k fino a 30) e avendo O scelta dove UTXO spedisce ad A e quindi a B. -* **Mancanza di stato** - UTXO può essere sia speso che non speso; non c'è possiblità per contratti o scripts multi-stage che mantengono qualche altro stato interno oltre questo. Ciò rende difficile creare contratti di opzioni multi-stage, cambi decentralizzati, che offrono protocolli crittografici, a due fasi, dedicati (necessari per premi computazionali sicuri). Questo inoltre significa che UTXO può essere soltanto usata per costruire, contratti unici e un non più complessi contratti "stateful" come le organizzazioni decentralizzate, e creare meta-protocolli difficili da implementare. Lo stato binario, combinato con la cecità-del-valore, significa anche che un'altra importante applicazione, come i limiti al prelievo, risulti impossibile. -* **Cecità-della-Blockchain** - UTXO è cieca alla blockchain come il nonce dell'hash precedente. Questo pregiudica applicazioni nel gioco d'azzardo, e altre molte categorie, privando il linguaggio di scripting di una fonte potenzialmente preziosa di casualità. - -Quindi, esistono tre approcci per costruire applicazioni avanzate sull'apice della criptomoneta: costruire una nuova Blockchain, usando scripting sull'apice del Bitcoin, e costruire un meta-protocollo sull'apice del Bitcoin. Costruire una nuova Blockchain permette una illimitata libertà nel costruire un set di funzionalità, comportando del tempo per lo sviluppo e delle criticità relative alla fase iniziale e a quella di messa in sicurezza del sistema. Usare lo scripting è semplice da implementare e standardizzare, ma implica delle limitazioni nelle sue capacità; al contrario i meta-protocolli, ma soffrono di difetti di scalabilità. Con Ethereum, noi intendiamo costruire un framework alternativo, che fornisce benefici ancora maggiori in termini di semplicità di sviluppo e ancora più forti proprietà di leggerezza per i client, permettendo allo stesso tempo alle applicazioni di condividere un ambiente economico e la sicurezza della Blockchain. - -## Ethereum - -Lo scopo di Ethereum è quello di creare un protocollo alternativo per la costruzione di applicazioni decentralizzate, fornendo un insieme eterogeneo di possibilità che, dal nostro punto di vista, saranno molto utili per una larga classe di applicazioni decentralizzate, in particolar modo nelle situazioni dove sono essenziali: un tempo rapido di sviluppo, la sicurezza per applicazioni utilizzate di rado, e la capacità di far interagire tra loro, in modo molto efficace, applicazioni differenti. Ethereum permette tutto ciò attraverso la costruzione di quello che in sostanza è il definitivo protocollo astratto e fondante: una Blockchain con un linguaggio di programmazione, costruito al suo interno e Turing-complete, che permette ad ognuno di scrivere -Smart Contracts ed applicazioni decentralizzate dove stabilire le proprie regole arbitrarie per la proprietà, i formati delle transazioni e le funzioni di transizione di stato. Una scarna versione di Namecoin può essere scritta in due linee di codice, e gli altri protocolli, come le criptomonete e i sistemi di reputazione, possono essere costruiti al di sotto delle venti linee. Gli smart contracts, i "boxes" crittografici che contengono valore, possono essere sbloccati solo se si verificano certe condizioni, inoltre possono essere anche costruiti sull'apice di della piattaforma, con degli strumenti molto più efficaci di quelli offerti dallo scripting del Bitcoin, grazie agli strumenti offerti dalla completezza del linguaggio di Turing, consapevolezza del valore, dello stato e della blockchain. - -### Ethereum Accounts - -In Ethereum, lo stato è costituito da oggetti chiamati "accounts", in cui ogni account ha un indirizzo di 20-byte e le transizioni di stato sono trasferimenti diretti del valore e dell'informazione tra gli accounts. Un account Ethereum account contiene quattro campi: - -* Il **nonce**, un contatore utilizzato per assicurarsi che ogni transazione può essere elaborata una sola volta -* Il conto corrente dell'account **bilancio ether** -* Il **contract code** dell'account, se presente -* Lo **storage** dell'account (vuoto da default) - -"Ether" è l'interno e principale crypto-carburante di Ethereum, e viene usato per pagare le commissioni di transazione. In generale, esistono due tipi di account: **accounts posseduti dall'esterno**, controllati da chiavi private, e **gli accounts contratto**, controllati dal loro codice di contratto. Un account posseduto dall'esterno non ha codice, e si possono mandare messaggi esterni dall'account posseduto esternamente creando e firmando una transazione; in un account contratto, ogni volta che questo riceve un messaggio, il suo codice si attiva, permettendo a questo di leggere e scrivere verso uno storage interno e spedire altri messaggi o creare contratti a sua volta. - -Si noti che i "contratti" in Ethereum non dovrebbero essere visti come qualcosa da "riempire" o "da complilare con"; piuttosto, essi sono più come "agenti autonomi", che vivono all'interno dell'ambiente di esecuzione di Ethereum, eseguendo sempre una porzione specifica di codice che viene "colpita" da un messaggio o da una transazione, e avendo il controllo diretto sul proprio conto di ether e sulla propria chiave/valore di store, al fine di tenere traccia delle variabili persistenti. - -### Messaggi e Transazioni - -Il termine "transazione" è utilizzato in Ethereum per riferirsi al pacchetto di dati firmati, che contengono un messaggio da inviare da un account posseduto dall'esterno. Le Transazioni contengono: - -* Il destinatario del messaggio -* Una firma che identifica il mittente -* L'ammontare di ether da trasferire al destinatario -* Un campo dati opzionale -* Un valore`STARTGAS`, che rappresenta il massimo numero di steps computazionali che l'esecuzione della transazione può impiegare -* Un valore`GASPRICE`, che rappresenta la commissione che il mittente paga per lo step computazionale - -i primi tre sono campi standard previsti in qualsiasi criptovaluta. Il campo dati non ha nessuna funzione da default, ma la virtual machine ha un codice operativo con cui un contratto può accedere ai dati; come caso di esempio, se un contratto sta funzionando come un servizio di registrazione di dominio basato sulla blockchain, allora può desiderare di interpretare i dati che vengono passati ad esso come contenenti due "campi ", il primo campo essendo un dominio da registrare ed il secondo essendo l'indirizzo IP da registrare. Il contratto dovrebbe leggere questi valori dai dati del messaggi e collocarli appropriatamente nello storage. - -I campi `STARTGAS` e`GASPRICE` sono cruciali per il modello di servizio anti-denial di Ethereum. Al fine di prevenire loops infiniti, accidentali o ostili, o altro spreco computazionale di codice, ad ogni transazione è richiesto di impostare un limite per l'uso di steps computazionali di codice di esecuzione. L'unità fondamentale di computazione è il "gas"; di solito, uno step computazionale costa 1 gas, ma alcune operazioni richiedono più unità di gas, perché esse sono computazionalmente più complesse, o richiedono un numero più elevato di dati che devono essere conservati come una parte dello stato. C'è anche una commissione di gas per ogni byte nei dati della transazione. L'obiettivo del sistema di commissione è quello di richiedere ad un aggressore di pagare proporzionalmente per ogni risorsa che essi consumano, includendo la computazione, larghezza di banda, e storage; quindi, qualsiasi transazione che comporta che il network consumi una quantità più grande di qualsiasi di queste risorse deve avere una commissione gas grosso modo proporzionale alla grandezza dell'incremento. - -### Messaggi - -I contratti hanno l'abilità di inviare "messaggi" ad altri contratti. I messaggi sono oggetti virtuali che non vengono mai serializzati ed esistono solo nell'ambiente di esecuzione di Ethereum. Un messaggio contiene: - -* Il mittente del messaggio (implicito) -* Il destinatario del messaggio -* L'ammontare di ether da inviare attraverso il messaggio -* Un campo dati opzionale -* Un valore `STARTGAS` - -Essenzialmente, un messaggio è come una transazione, eccetto che esso viene prodotto da un contratto e non da un attore esterno. Un messaggio è prodotto quando un contratto che sta eseguendo il codice fa effettua una operazione `CALL`, che produce ed esegue un messaggio. Come una transazione, un messaggio comporta che l'account del destinatario esegua il proprio codice. Quindi, i contratti possono avere relazioni con altri contratti esattamente alla stesso modo che avviene con degli attori esterni. - -Si noti che la quantità di gas, che serve ad una transazione o ad un contratto, si applica alla totalità del gas consumato da quella transazione e da tutte le sub-esecuzioni. Per esempio, se un attore esterno A trasmette una transazione a B con 1000 gas, e B consuma 600 gas prima di inviare il messaggio a C, e l'esecuzione interna di C consuma 300 gas prima di ritornare, poi B può spendere altri 100 gas prima di rimanere a corto di gas. - -### La Funzione di Transizione di Stato di Ethereum - -![ethertransition.png](http://vitalik.ca/files/ethertransition.png?1) - -La funzione di transizione di stato di Ethereum, `APPLY(S,TX) -> S'` può essere definita come segue: - -1. Controlla se la transazione è ben impostata (ie. ha il giusto numero di valori), la firma è valida, e il nonce corrispode a quello dell'account del mittente. In caso contrario, si ha un errore. -2. Calcola la commissione di transazione come `STARTGAS * GASPRICE`, e determina l'indirizzo del mittente dalla firma. Sottrae la commissione dal bilancio dell'account del mittente e incrementa il nonce del mittente. Se non c'è un bilancio sufficiente da spendere, si ha un errore. -3. Inizializza `GAS = STARTGAS`, e toglie una certa quantità di gas per byte per pagare i byte nella transazione. -4. Trasferisce il valore della transazione dall'account del mittente all'account del destinatario. Se l'account del destinatario non esiste ancora, lo crea. Se l'account del ricevente è un contratto, esegue il codice del contratto sia per il completamento o fino a quando l'esecuzione finisce il gas. -5. Se il valore di trasferimento fallisce perché il mittente non ha abbastanza soldi, il code di esecuzione finisce il gas, ripristina tutti i cambiamenti di stato, tranne il pagamento delle commissione , e aggiunge le commissioni sul conto del minatore . -6. Altrimenti, risarcisce al mittente le commissioni per il gas rimanente, ed invia le commissioni pagate per il gas e consumate al miner. - -Per esempio, si supponga che il codice del contratto è: - - se !self.storage[calldataload(0)]: - self.storage[calldataload(0)] = calldataload(32) - -Si noti che in realtà il codice del contratto è scritto in un codice EVM di basso livello; questo esempio è scritto in Serpent, che, per essere chiari, è uno dei nostri linguaggi di alto livello, può essere compilato fino al codice EVM. Si supponga che lo storage del contratto sia inizialmente vuoto, e la transazione è inviata con un valore di 10 ether, 2000 gas, al prezzo di 0.001 ether gas, e 64 bytes di dati, con bytes 0-31 che rappresentano il numero `2` e i bytes 32-63 che rappresentano la stringa `CHARLIE`. Il processo per la funzione di transizione di stato è in questo caso come segue: - -1. Controlla che la transizione è valida è ben impostata. -2. Controlla che il mittente abbia almeno 2000 * 0.001 = 2 ether. If it is, quindi sottrae 2 ether dall'account del mittente. -3. Inizializza gas = 2000; assumendo che la transazione è lunga 170 bytes e la commissione di byte è 5, sottrae 850 così che c'è 1150 gas che rimane. -3. Sottrae altri 10 ether dall'account del mittente, e li aggiunge all'account del contratto. -4. Esegue il codice. In questo caso, questo è semplice: esso controlla che lo storage del contratto all'indice `2` sia usato, prende nota che non lo è, e così imposta lo storage all' index `2` al valore `CHARLIE`. Si supponga che questo impieghi 187 gas, così l'ammontare rimante di gasi sia 1150 - 187 = 963 -5. Aggiunge 963 * 0.001 = 0.963 di nuovo sul conto del mittente, e ritorna lo stato risultante. - -Se non ci fosse alcun contratto alla fine di ricezione della transazione, quindi il totale della commissione di transazione sarebbe semplicemente uguale al `GASPRICE` provvisto moltiplicato per la lunghezza della transazione in bytes, ed i dati inviati per mezzo della transazione sarebbero irrilevanti. - -Si noti che i messaggi lavorano in maniera equivalente alle transazioni in termini di ripristino: se un messaggio in esecuzione finisce il gas, quindi l'esecuzione del messaggio, e tutte le altre esecuzioni innescate da questa esecuzione, tornano indietro, ma le esecuzioni precedenti non hanno bisogno di farlo. Questo significa che è "sicuro" per un contratto di richiamare un altro contratto, se A chiama B con G di gas poi l'esecuzione di A è garantita per perdere al massimo G. Alla fine, si noti che c'è un codice operativo, `CREATE`, che crea un contratto; il proprio meccanismo di esecuzione è generalmente simile a `CALL`, con l'eccezione che questo output di esecuzione determina il codice di un contratto recentemente creato. - -### Esecuzione del Codice - -Il codice nel contratti Ethereum è scritto in un linguaggio di basso livello, linguaggio bytecode a cascata, denominato "codice virtual machine Ethereum" o"codice EVM". Il codice consiste in una serie di bytes, dove ogni byte rappresenta un'operazione. In generale, l'esecuzione del codice è un loop infinito che consiste nel realizzare ripetutamente l'operazione al contatore del programma attuale (che inizia con zero) e incrementando il contatore del programma di uno, fino a che si ottiene la fine del codice od un errore o `STOP` o è rilevato l'istruzione `RETURN`. Le operazioni hanno accesso a tre tipi di spazio nel quale registrare i dati: - -* Lo **stack**, un last-in-first-out contenitore nel quale i valori possono essere spinti e spuntati -* **Memoria**, un array di byte espandibile all'infinito -* Il lungo-termine del contratto **storage**, una chiave/valore di store. A differenza dello stack e della memoria, che si resettano dopo la fine del calcolo, lo storage persiste per un lungo periodo. - -Il codice può anche accedere al valore, mittente e dati del messaggio in arrivo, così come ai dati in testata al blocco, e il codice può anche ritornare come un'array di dati come output. - -Il modello di esecuzione formale del codice EVM è sorprendentemente semplice. Mentre la virtual machine di Ethereum funziona, tutto il suo stato computazionale può essere definito dall'insieme di dati `(stato_del_blocco, transazione, messaggio, codice, memoria, stack, pc, gas)`, dove `stato-del_blocco` è lo stato globale che contiene tutti gli accounts e include i bilanci e lo storage. All'inizio di ogni turno di esecuzione, l'istruzione corrente viene trovata prendendo il `pc`th byte del `codice` (o 0 se `pc >= len(codice)`), e ogni istruzione ha la sua propria definizione in termini di come interagisce con l'insieme di dati. Per esempio, `ADD` espelle due oggetti fuori dallo stack e spinge la loro somma, riduce `gas` di 1 e incrementa `pc` by 1, e `SSTORE` espelle i due oggetti all'apice fuori dallo stack ed inserisce il secondo oggetto nello storage del contratto all'indice specificato dal primo oggetto. Sebbene ci sono molti modi di ottimizzare l'esecuzione della virtual machine di Ethereum attraverso una pronta compilazione, un'implementazione basica di Ethereum can in poche centinaia di righe di codice. - -### Blockchain e Mining - -![apply_block_diagram.png](http://vitalik.ca/files/apply_block_diagram.png) - -La blockchain di Ethereum è in molti modi simile a quella del Bitcoin, seppur con qualche differenza. La differenza princiale tra Ethereum e Bitcoin con riguardo all'architettura della blockchain, è che, contrariamente al Bitcoin, i blocchi di Ethereum contengono una copia sia dell'elenco delle transazioni sia lo stato più recente. A parte questo, gli altri due valori, il numero di blocco e la difficoltà, vengono memorizzati nel blocco. L'algoritmo di validazione del blocco alla base in Ethereum funziona in questo modo: - -1. Controlla se il se il precedente blocco di riferimento esiste ed è valido. -2. Controlla se la marca temporale del blocco è più grande di quella del blocco di riferimento precedente ed inferiore di 15 minuti nel futuro. -3. Controlla che il numero del blocco, difficoltà, l'origine della transazione, la transazione derivata ed il limite del gas ( vari e specifici concetti di basso-livello di Ethereum) sono validi. -4. Controlla se il proof of work sul blocco sia valido. -5. Sia `S[0]` lo stato alla fine del blocco precedente. -6. Sia`TX` la lista delle transazioni del blocco, con `n` transazioni. Per tutti in `0...n-1`, set `S[i+1] = APPLY(S[i],TX[i])`. Se qualsiasi applicazioni dà errore, o se il gas totale è consumato nel blocco fino a che questo punto eccede il `GASLIMIT`, anche questo, dà errore. -7. Sia `S_FINAL` `S[n]`, ma aggiungendo la ricompensa per il blocco pagata al miner. -8. Controlla che lo stato originario del Merkle tree `S_FINAL` sia uguale allo stato finale originario fornito nell'intestazione del blocco. In tal caso, il blocco è valido; in caso contrario, quest'ultimo non è valido. - -L'approccio può sembrare molto inefficiente a prima vista, perché questo necessita di registrare l'intero stato di ogni blocco, ma in realtà l'efficienza dovrebbe essere comparabile a quella del Bitcoin. La ragione sta nel fatto che lo stato è registrato in una struttura ad albero, e dopo ogni blocco una piccola parte dell'albero necessita di essere cambiata. Quindi, in generale, tra due blocchi adiacenti la grande maggioranza dell'albero dovrebbe essere la stessa, e quindi i dati possono essere registrati una sola volta e consultati due volte usando i puntatori (ad es. gli hash degli alberi inferiori). Un tipo speciale di albero conosciuto come "Patricia tree" viene usato per raggiungere questo risultato, includendo una modifica del concetto del Merkle tree, che permette ai nodi di essere inseriti e cancellati, e non solo cambiati, in maniera efficiente. Per di più, poiché tutta l'informazione sullo stato è una parte dell'ultimo blocco, non c'è bisogno di registrare tutta la storia della blockchain - una strategia che, se applicata al Bitcoin, può consentire un risparmio di spazio di 5-20x. - -Un quesito comune che viene posto è "dove" il codice del contratto viene eseguito, in termini di hardware fisico. Questa è una risposta semplice: il processo di esecuzione del codice del contratto è una parte della definizione dello funzione di transizione di stato, che è una parte dell'algoritmo di validazione del blocco, così che se una transazione è aggiunta al blocco `B` l'esecuzione del codice generata da questa transazione sarà eseguita da tutti i nodi, nel presente e nel futuro, scaricando e validando il blocco `B`. - -## Applicazioni - -In generale, ci sono tre tipi di applicazioni costruite su Ethereum. La prima categoria sono le applicazioni finanziarie, che forniscono agli utenti molteplici e più potenti modi di gestire ed usufruire i contratti attraverso l'uso dei proprio soldi. Questo include le sub-monete, i derivati finanziari, ci contratti di hedging, i libretti di risparmio, i testamenti, e per ultimo perfino qualche genere di contratto collettivo di lavoro. -La seconda categoria consiste nelle applicazioni quasi finanziarie, dove è coinvolto il denaro, ma c'è anche un lato non monetario importante per quello viene fatto; un esempio perfetto è l'auto-assegnazione di premi per le soluzioni di problemi computazionali. Infine, ci sono applicazioni come il voto online e il governo decentralizzato che non sono assolutamente finanziarie. - -### Sistema dei Tokens - -Il sistema dei tokens basato sulla blockchain ha molte applicazioni che vanno dalle sub-monete che rappresentano assets come USD o gold di azioni di società, tokens individuali che rappresentano smart property, che assicurano coupons non falsificabili, e perfino sistemi di token senza nessun legame con un valore convenzionale, utilizzati come sistemi di punti di incentivazione. I sistemi di Token sono sorprendentemente semplici da implementare in Ethereum. Il punto chiave è che tutte queste monete, o sistema di token, sono fondamentalmente un database che funzione con una operazione: sottrae X unità da A e conferisce X unità a B, con la condizione che (i) X aveva almeno X unità prima che la transazione e la (2) tansazione sia approvata da A. Tutto quello che serve per implementare un sistema di tokens consiste nell'implementare questa logica in un contratto . - -Il codice basico per implementare un sistema di token attraverso Serpent è come segue: - - def send(to, value): - if self.storage[msg.sender] >= value: - self.storage[msg.sender] = self.storage[msg.sender] - value - self.storage[to] = self.storage[to] + value - -Questa è sostanzialmente un'implementazione letterale della funzione di stato del "sistema bancario" descritta in precedenza in questo documento. Poche altre linee di codice devono essere aggiunte per fornire lo step iniziale per la distribuzione delle unità di moneta nel primo luogo ed in altri casi limite, ed idealmente una funzione sarebbe aggiunta per lasciare agli altri contratti di domandare il saldo di un indirizzo. Ma questo è tutto ciò di cui c'è bisogno. Teoricamente, i sistemi di token basati su Ethereum, che fungono da sub-monete, possono potenzialmente includere un'altra importante caratteristica basata sulla mancanza di meta-monete sulla chain del Bitcoin: l'abilità di pagare le commissioni di transazione direttamente in quella moneta. Il modo in cui questo potrebbe essere implementato consiste che quel contratto manterrebbe un saldo di ether con cui risarcire gli ether usati per pagare le commissioni al mittente, e ricaricherebbe questo saldo raccogliendo le unità di moneta interne che esso impiega in commissioni e rivendendo queste in una costante vendita all'asta. Gli utenti avrebbero bisogno di "attivare" i loro accounts con ether, ma una volta che ether è là esso sarebbe riusabile perché il contratto lo risarcirebbe ogni volta. - -### Derivati Finanziari e Monete dal Valore Stabile - -I derivati finanziari sono la più comune applicazioni di uno "smart contract", e tra i più semplici da implementare nel codice. La sfida più grande nell'implementare i contratti finanziari è che la maggioranza di questi richiede un collegamento ad un indice di prezzo esterno; per esempio, un applicazione molto utile è uno smart contract che assicura dalla volatilità dell'ether (od un altra another criptomoneta) con riferimento ai dollari americani, ma questo richiede al contratto di sapere quale sia il valore tra ETH/USD. Il modo più semplice per farlo è attraverso un contratto "data feed" mantenuto da una parte specifica (eg. NASDAQ) progettato in modo che tale parte ha la possibilità di aggiornare il contratto , se necessario, e fornendo un'interfaccia che permette altri contratti di inviare un messaggio a questo contratto e fornire una risposta che procura il prezzo. - -Avendo fatto queste premesse, il contratto di hedging sarebbe come segue: - -1. Attende la parte A per l'input di 1000 ether. -2. Attende la parte B per l'input di 1000 ether. -3. Registra il controvalore in USD di 1000 ether, calcolato interrogando in contratto di data feed, nello storage, sostenendo che questo è $x. -4. Dopo 30 giorni, viene permesso ad A o B di "riattivare" il contratto al fine di inviare il controvalore $x di ether (calcolato dalla nuova interrogazione del contratto di data feed al fine dell'ottenimento nel nuovo prezzo) ad A ed il resto a B. - -Questo tipo di contratto ha un pontenziale significativo nel commercio in criptomoneta. Uno dei principali problemi riguardo la criptomoneta è la volatilità; tuttavia molti utenti e commercianti potrebbero preferire la sicurezza e la convenienza di trattare gli asset crittografici, senza l'eventualità di prospettare una perdita del 23% del valore dei loro fondi in un unico giorno. Fino ad ora, la soluzione più comune proposta è stata quella degli assets garantiti dall'emittente; l'idea è che un emittente crei una sub-moneta in cui ha diritto di emettere o revocare unità, e fornire un'unità della moneta a chiunque le procuri (offline) un'unità di un asset sottostante (ad es. oro, USD). L'emittente successivamente promette di fornire un'unità dell'asset sottostante a chiunque le reinvii un'unità del crypto-asset. Questo meccanismo permette a qualsiasi asset non crittografico di "elevarsi" ad asset crittografico, fornito dall'emittente fidato. - -In pratica, tuttavia, gli emittenti non sono sempre fidati, e in qualche caso l'infrastruttura della banca è troppo debole, o troppo ostile, affinché esista ogni servizio. I derivati finanziari forniscono un'alternativa. Qui, al contrario del caso in cui il singolo emittente che fornisce i fondi per garantire un asset, fa la sua parte un mercato decentralizzato di speculatori, scommettendo che il prezzo dell'asset di riferimento (ad. es. ETH) salirà. A differenza degli emittenti, gli speculatori non hanno opzioni di default dalla loro parte del patto, poiché il contratto trattiene i loro fondi in un escrow. Si noti che con questo approccio non è pienamente decentralizzato, perché una risorsa fidata è ancora necessaria al fine di fornire l'indice del prezzo, anche se probabilmente perfino questo è un miglioramento enorme in termini di riduzione dei requisiti dell'infrastruttura (a differenza dall'essere un emittente, diramare un feed del prezzo non richiede license e può essere classificato come libertà di pensiero) diminuendo il potenziale per frode. - -### Sistemi di Identità e Reputazione - -La prima criptomoneta alternativa in assoluto, [Namecoin](http://namecoin.org/), ha tentato di utilizzare una blockchain tipo quella del Bitcoin al fine di fornire un sistema di registrazione di nomi di dominio, dove gli utente possono registrare i loro nomi di dominio in un database pubblico insieme ad altri dati. Il più importante caso d'uso citato è per un sistema [DNS](http://en.wikipedia.org/wiki/Domain_Name_System) , che collega i nomi di dominio come "bitcoin.org" (o, nel caso di Namecoin, "bitcoin.bit") ad un indirizzo IP. Altri casi d'uso includono l'autenticazione nell'email e potenzialmente sistemi di reputazione più avanzati. Qui c'è un contratto basico che fornisce un sistema di registrazione di nome di dominio tipo tipo Namecoin attraverso Ethereum: - - def register(name, value): - if !self.storage[name]: - self.storage[name] = value - -Il contratto è molto semplice; tutto questo è un database che può essere inserito all'interno del network di Ethereum, ma non modificato o rimosso. Chiunque può registrare un nome di dominio con qualche valore, e questa registrazione rimane per sempre. Un contratto di registrazione di nomi di dominio più sofisticato avrà anche una "clausola di funzione" che permette agli altri contratti di interrogarlo, così come un meccanismo per il "proprietario" (ad es. il primo registrante) di un nome di dominio di modificare i dati o trasferire la proprietà. Un individuo può perfino aggiungere, sull'apice, un sistema di reputazione ed una funzionalità web-della-fiducia. - -### Storage Decentralizzato di Files - -Nel corso degli ultimi anni, sono emerse un numero di startups popolari che si occupano dello storage online dei files, tra cui la più importante è divenuta Dropbox, che permette agli utenti di fare un backup tramite upload dei loro hard disk, di avere un servizio di storage del backup e quindi accedervi in cambio di un abbonamento mensile. Tuttavia, oggi giorno il mercato dello storage dei files è allo stato relativamente inefficiente; un rapido excursus alle varie [soluzioni esistenti](http://online-storage-service-review.toptenreviews.com/) mostra che, con particolare riferimento alla "strana valle" al livello di 20-200 GB, alla quale né abbonamenti gratuiti né quelli di livello aziendale danno soluzione, i costi sostenuti mensilmente per i servizi più celebri di file storage sono maggiori, con riferimento alla finestra temporale di un singolo mese di abbonamento, rispetto a quelli relativi all'acquisto di un intero hard disk. I contratti in Ethereum permettono lo sviluppo di un ecosistema decentralizzato di file storage, dove i singoli utenti possono guadagnare piccole somme di denaro dall'affitto dei propri hard disks ed in cui lo spazio inutilizzato può essere impiegato per spingere verso il basso i costi di archiviazione dei files. - -Il punto chiave di tale dispositivo sarebbe quello che abbiamo chiamato "il contratto Dropbox decentralizzato". Questo contratto funziona come segue. Per primo, vengono divisi i dati desiderati in blocchi, crittografando ogni blocco per questioni di privacy, costruendo un Merkle tree al di fuori di questo. Quindi viene definito un contratto con la regola che, ogni N blocchi, il contratto possa scegliere un indice randomico nel Merkle tree (usando l'hash del blocco precedente, accessibile dal codice del contratto, come generatore di causualità), e vengono dati X ether alla prima entità per fornire una transazione con un un sistema semplificato di verificazione del pagamento come la "prova di proprietà" del blocco con quel particolare indice nel tree. Quando gli utenti vogliono ri-scaricare i loro files, possono usare un protocollo di micropagamento (ad es. pagando 1 szabo per 32 kilobytes) per recuperare il file; l'approccio più efficiente in termini di commissione è per il pagante quella di non rendere pubblica la transazione fino alla fine, ma di sostituire la transazione con una più lucrativa con lo stesso nonce dopo ogni 32 kilobytes. - -Un'importante caratteristica del protocollo è che, sebbene può sembrare che un nodo si stia affidando a diversi nodi randomici per non rischiare di dimenticare il file, uno può ridurre, quasi a zero, questo rischio attraverso la frammentazione del file in molte parti attraverso una condivisione segreta, ed osservare i contratti al fine di controllare se ogni frammento è ancora nel possesso del nodo. Se un contratto sta ancora trasmettendo del denaro, questo fornisce una prova crittografica che qualcuno al di fuori di sta ancora conservando il file. - -### Organizzazioni Autonome Decentralizzate - -Il concetto generale delle "organizzazione autonome decentralizzate" è che un'entità virtuale ha un certo numero di membri o azionisti che, probabilmente con una maggioranza del 67%, abbia il diritto di spendere i fondi dell'entità e modificare il proprio statuto. I membri potrebbero collettivamente decidere su come l'organizzazione dovrebbe allocare i propri fondi. I Metodi per allocare una i fondi di una OAD (DAO) potrebbero spaziare da premi, salari e perfino consistere in meccanismi più particolari come un una moneta interna per premiare un lavoro. Questo replica essenzialmente i crismi legali di una compagnia tradizionale o di una non profit a differenza che, per l'attuazione, si usa una sola tecnologia blockchain crittografica. Fino ad oggi gran parte del discorso circa i DAO è stato attorno il modello "capitalistico" di una "società autonoma decentralizzata" SAD (DAC) con la suddivisione dei dividendi delle azioni e azioni negoziabili; un'alternativa, probabilmente descritta come una "comunità autonoma decentralizzata", potrebbe conferire a tutti i suoi membri un'azionariato egualitario al fine di decidere di ottenere che il 67% dei membri esistenti accettino e rimuovano un membro. Il requisito che una persona possa essere solo un unico membro potrebbe quindi essere imposta collettivamente dal gruppo. - -Un profilo generale per come codificare un DAO è il seguente. Il design più semplice consiste nella parte di un codice che si auto modifica che cambia se due terzi dei membri concordano su un cambiamento. Sebbene il codice è teoricamente immutabile, un soggetto può facilmente aggirare questo ostacolo ed ottenere una mutabilità de facto avendo frammenti di codice in contratti distinti, e avendo l'indirizzo dei contratti per richiamare i dati archiviati nello storage modificabile. In una semplice implementazione di questo come un contratto DAO, ci sarebbero tre tipi di transazioni, distinte dai dati forniti nella transazione: - -* `[0,i,K,V]` per registrare una proposta con indice `i` per cambiare l'indirizzo all'indice dello storage `K` al valore `V` -* `[0,i]` per registrare un voto in favore di una proposta `i` -* `[2,i]` per finalizzare la proposta `i` se sono stati fatti sufficienti voti - -Il contratto potrebbe avere quindi clausole per ognuna di queste. Esso potrebbe mantenere una registrazione di tutti i cambiamenti aperti dello storage, insieme ad un elenco di chi ha votato per essi. Inoltre esso potrebbe avere una lista di tutti i membri. Quando qualsiasi cambiamento dello storage raggiunge due terzi dei membri che votano per esso, una transazione conclusiva potrebbe eseguire il cambiamento. Una più sofisticata intelaiatura potrebbe anche avere un'opzione di voto costruita al suo interno per caratteristiche come l'invio di una transazione, l'aggiunta o la rimozione dei membri, e potrebbe perfino essere utile per [Liquid Democracy](http://en.wikipedia.org/wiki/Delegative_democracy)-style vote delegation (ad es. ognuno può assegnare a qualcuno di votare per lui, e l'assegnazione è transitiva così se A assegna a B e B assegna a C quindi C determina il voto di A). Questo design potrebbe consentire alla DAO di svilupparsi organicamente come una comunità decentralizzata, che consenta alle persone, in caso, di delegare il compito di filtrare chi sia un membro agli specialisti, sebbene diversamente dal "sistema corrente" gli specialisti possono facilmente immettere e cancellare nel tempo come i membri individuali di una comunità cambiano i loro allineamenti. - -Un modello alternativo per una società decentralizzata, dove qualsiasi account può avere zero o più azioni, e dove due terzi delle azioni sono necessarie per prendere una decisione. Un'intelaiatura completa potrebbe coinvolgere la funzionalità della gestione degli asset, l'abilità di fare un'offerta per comprare o vendere le azioni, e l'abilità di accettare offerte (preferibilmente con un meccanismo di matching dell'ordine all'interno del contratto). La delega potrebbe anche esiste come una Democrazia di tipo liquido, estendendo il concetto della "board of directors". - -### Ulteriori Applicazioni - -**1. Portafogli di risparmio**. Si supponga che Alice vuole tenere al sicuro i suoi fondi, ma è preoccupata circa il fatto che lei li perderà o qualcuno eseguirà un hack della sua chiave privata. Lei attraverso ether stipula un contratto con Bob, una banca, come segues: - -* Alice può in maniera autonoma ritirare, ogni giorno, al massimo l'1% dei fondi. -* Bob può in maniera autonoma ritirare, ogni giorno, al massimo l'1% dei fondi, ma Alice ha la possibilità di eseguire una transazione con la sua chiave impedendo questa possibilità. -* Alice e Bob insieme possono ritirare qualsiasi quantità di fondi. - -Normalmente, l' 1% è sufficiente per Alice, e se Alice vorrà ritirare di più di quanto lei può, potrà contattare per un aiuto Bob. Se La chiave di Alice viene hackerata, lei chiede soccorso a Bob per movimentare i fondi su un nuovo contratto. Se lei perde la sua chiave, alla fine Bob avrà i fondi al di fuori. Se risulterà che Bob sarà dannoso, Alice potrà quindi disattivare l'abilità di ritirare fondi di Bob. - -**2. Assicurazione sul raccolto**. Un soggetto può facilmente creare contratti di derivati finanziari usando un data feed delle condizioni meterologiche al posto dell'indice del prezzo. Se un agricoltore in Iowa acquista un derivato che paga in maniera inversamente proporzionale alla precipitazione in Iowa, il contadino riceverà automaticamente, nel caso in cui segua una siccità, i soldi e se ci sarà pioggia a sufficienza lui sarà soddisfatto perché i suoi raccolti saranno andati bene. Questo ragionamento può essere applicato generalmente anche alle assicurazione sui disastri naturali. - -**3. Un data feed decentralizzato**. A differenza dei contratti finanziari, sarebbe possibile attualmente decentralizzare il data feed tramite un protocollo denominato "[SchellingCoin](http://blog.ethereum.org/2014/03/28/schellingcoin-a-minimal-trust-universal-data-feed/)". Sostanzialmente SchellingCoin funziona come segue: tutte le N controparti inseriscono nel sistema il valore di un dato fornito (ad es. il prezzo ETH/USD), i valori vengono scelti, e ognuno tra il 25% e il 75% ottiene un token come premio. Ciascuno ha l'incentivo di fornire una risposta che tutti gli altri forniranno, e l'unico valore su cui un vasto numero di utenti potrà realisticamente concordare è l'ovvio predefinito: la verità. Questo crea un protocollo decentralizzato che può in teoria fornire qualsiasi numero di valori, incluso il prezzo di ETH/USD, la temperatura in Berlino o perfino una calcolo particolarmente difficile. - -**4. Un escrow smart multifirma**. Bitcoin permette la multifirma nelle transazione dei contratto dove, per esempio, tre di un totale di cinque chiavi possono spendere i fondi. Ethereum permette più livello di dettaglio; per esempio, quattro di un totale di cinque chiave possono spendere qualsiasi quantità di fondi, tre di cinque possono spendere fino ad un totale del 10% al giorno, e due di cinque possono spendere fino al 0.5% al giorno. In più, la multifirima in Ethereum è asincrona - due soggetti possono registrare, in tempi differenti, le loro firme sulla blockchain e l'ultima firma invierà automaticamente la transazione. - -**5. Cloud computing**. La tecnologia EVM può essere inoltre usata per creare una sistema di computing verificabile, permettendo agli utenti di chiedere agli altri di effettuare le computazioni e, nel caso, di chiedere, a certi checkpoints scelti randomicamente, le prove che queste computazioni siano avvenute correttamente. Questo consente la creazione di un mercato di cloud computing dove ogni utente può partecipare con il suo desktop, laptop o server specializzato, e dove controlli spot con depositi cauzionali possono essere usati per assicurare che il sistema sia meritevole di fiducia (ad es. i nodi non possono imbrogliare in maniera profittevole). Tuttavia questo tipo di sistema può non essere utile per tutti i compiti; per es. quelli che richiedono un alto livello di computazione tra processi non possono facilmente essere fatti su un grande cloud di nodi. Ciononostante le altre richieste sono più facili da essere messe in parallelo; progetti come SETI@home, folding@home e algoritmi generici possono essere facilmente implementati all'apice di queste piattaforme. - -**6. Gioco peer-to-peer**. Qualsiasi numero di protocolli di gioco peer-to-peer, come quelli di Frank Stajano e Richard Clayton [Cyberdice](http://www.cl.cam.ac.uk/~fms27/papers/2008-StajanoCla-cyberdice.pdf), possono essere implementati sulla blockchain di Ethereum. Il protocollo di gioco più semplice è ad oggi un semplice contratto per la differenza sul prossimo hash di blocco, e dei più avanzati protocolli che possono essere costruiti da lì, creando servizi di gioco, con commissioni vicine allo zero, che non hanno la possibilità di imbrogliare. - -**7. Mercati predittivi**. Fornito un oracolo o SchellingCoin, i mercati predittivi sono anch'essi semplici da implementare, ed essi insieme a SchellingCoin possono dimostrare di essere la prima applicazione su larga scala della [futarchy](http://hanson.gmu.edu/futarchy.html) come un protocollo per l'amministrazione delle organizzazioni decentrallizzate. - -**8. Mercati decentralizzati sulla blockchain**, che usano il sistema basato sull'identità e sulla reputazione. - -## Altre questioni - -### Implementazione GHOST modificata - -Il protocollo "Greedy Heavist Observed Subtree" (GHOST) è un'innovazione introdotta per la prima volta da Yonatan Sompolinsky e Aviv Zohar nel [Dicembre 2013](http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf). La motivazione dietro il GHOST è che le blockchain con tempi di conferma veloci soffrono, allo stato attuale, di una sicurezza ridotta dovuta ad un elevato tasso di latenza- perchè i blocchi impiegano determinati tempi per propagarsi attraverso il network, se il miner A elabora un blocco e successivamente il miner B elabora un altro blocco prima che il blocco del miner A sia propagato a B, il blocco del miner B andrà sprecato e non contribuirà alla sicurezza della rete. Inoltre, esiste un problema di centralizzazione: se il miner A è una pool di mining con una potenza di hash del 30% ed il miner B ne ha una del 10%, A avrà un rischio di produrre un blocco latente pari al 70% delle volte (visto che, nell'altro 30% dei casi, A ha prodotto l'ultimo blocco e quindi otterrà i dati di mining immediatamente) mentre B correrà il rischio di produrre un blocco latente il 90% dei casi. Quindi l'intervallo del blocco è abbastanza breve affinchè il grado di latenza sia alto e A sarà sostanzialmente più efficiente semplicemente in virtù delle sue dimensioni. Con il combinato di questi due effetti, le blockchains che producono blocchi velocemente corrono fortemente il rischio di convogliare verso una mining pool, che ha una percentuale di potenza di hash sul network abbastanza elevata, arrivando in tal modo al controllo del processo di mining. - -Come descritto da Sompolinsky e Zohar, GHOST risolve il primo problema della perdita di sicurezza della rete attraverso l'inclusione dei blocchi latenti nel computo di quale "chain" sia la "più lunga"; vale a dire, non solo il blocco precedente, o quelli ancora più vecchi, rispetto ad un blocco, ma anche quelli latenti e discendenti da un blocco più vecchio (nel gergo Ethereum "zii") sono aggiunti nel computo di quale blocco ha il più grande proof of work che lo sostiene. Per risolvere la seconda questione della faziosità della centralizzazione, noi andiamo al di là del protocollo descritto da Sompolinsky e Zohar, e forniamo i premi del blocco ai blocchi latenti: un blocco latente riceve lo 87.5% del proprio premio base, e il "nipote" che include il blocco latente riceve il restante 12.5%. Tuttavia, le commissioni di transazione, non vengono assegnate agli "zii". - -Ethereum implementa una versione semplificata del GHOST che va in profondità nel limite di soli sette livelli. In particolare, esso è definito come segue: - -* Il blocco A deve specificare un genitore, e specificare 0 o più zii -* Uno zio, incluso nel blocco B, deve avere le seguenti proprietà: - * Deve essere un figlio diretto della k generazione antenata di B, dove 2 <= k <= 7. - * Esso non può essere un antenato di B - * Uno zio deve essere un valido header del blocco, ma non necessita di essere verificato in precedenza o perfino un blocco valido - * Uno zio deve essere diverso da tutti gli zii inclusi nei blocchi precedenti e da tutti gli altri zii inclusi nello stesso blocco (inclusione non doppia) -* Per ogni zio U nel blocco B, il miner di B riceve un addizionale 3.125% aggiunto al premio della propria coinbase e il miner di U riceve il 93.75% come premio standard della coinbase. - -Questa versione limitata di GHOST, con gli "zii" che possono essere inclusi fino a 7 generazioni, è stata impiegata per due ragioni. La prima, un GHOST illimitato potrebbe includere troppe complicazioni nel computo di quali "zii", per un certo blocco, siano validi. Il secondo, un GHOST illimitato, con il compromesso raggiunto in Ethereum, elimina l'incentivo per un miner di effettuare operazioni di mining su una "chain" di un attaccante, ma, al contrario, di effettuarle sulla "chain" principale. - -### Commissioni - -Poiché ogni transazione pubblicata nella blockchain impone al network il costo del download e la verifica della stessa, c'è il bisogno, al fine di prevenire un abuso, di qualche meccanismo di regolazione, che solitamente coinvolge le commissioni di transazione. L'approccio standard, usato in Bitcoin, consiste in quello di avere commissioni prettamente volontarie, contando sul fatto che i miners agiscono come custodi ed impostano minimi dinamici. Questo approccio è stato recepito in maniera molto favorevole nella community Bitcoin poichè, in particolare, è "basato sul mercato", permettendo, tra i miners, domanda e offerta e che i mittenti della transazione possano determinare il prezzo. Il problema con questa impostazione di ragionamento è, tuttavia, che il processo di transazione non è un mercato; anche se è intuitivamente interessante interpretare l'elaborazione delle transazioni come un servizio che il miner sta offrendo al mittente, in realtà ogni transazione che un miner include necessiterà di essere processata da ogni nodo del network, così che la maggior parte del costo del processo di una transazione è a carico di terzi e non del miner che sta prendendo una decisione se includere o meno questa. Quindi, è molto probabile che si verifichi la Tragedia-dei-beni-comuni. - -Tuttavia, come si scopre questo difetto nel meccanismo di mercato, quando viene fornita, per semplificazione, una premessa particolarmente inaccurata, magicamente si elimina da sola. L'argomento è il seguente. Supponiamo che: - -1. Una transazione comporta `k` operazioni, offrendo un premio `kR` a qualsiasi miner che la includa dove `R` è impostato dal mittente e `k` e `R` sono (approssimativamente) visibili in anticipo dal minatore. -2. Un'operazione ha un costo di processo di `C` verso qualsiasi nodo (ad es. tutti i nodi hanno la stessa efficienza) -3. Ci sono `N` nodi di mining, ognuno dei quali con una potenza di processamento uguale (ad es. `1/N` del totale) -4. Non esistono nodi pieni che non eseguono operazioni di mining. - -Un miner potrebbe desiderare di processare una transazione nella prospettiva che il possibile premio sia superiore al costo. Quindi, la ricompensa prevista è `kR/N` visto che il miner ha `1/N` chance di processare il blocco successivo, ed il costo di processamento per il miner è semplicemente `kC`. Quindi, i miners includeranno le transazioni dove `kR/N > kC`, e il costo di processamento o `R > NC`. Si noti che `R` è la commissione dovuta dal mittente ad ogni operazione, ed è perciò inferiore della soglia minina di vantaggio che il mittente ha dall'operazione, e `NC` è tutto il costo dell'intero network per il processamento di un operazione. Quindi, i miners hanno l'incentivo di includere solo quelle transazioni per cui il vantaggio complessivo è maggiore del costo. - -Tuttavia, in realtà, ci sono importanti deroghe da questi presupposti: - -1. Il miner paga un costo più alto per processare la transazione rispetto ad un altro che verifica i nodi, visto che il tempo di verifica in più ritarda la propagazione del blocco e quindi aumenta la chance che il blocco diventi latente. -2. Esistono nodi pieni che non processano operazioni di mining. -3. La distribuzione del potere di mining potrebbe generare in concreto una ineguaglianza. -4. Gli speculatori, i nemici politici ed i soggetti insensati la cui funzione di utilità incorpora causando un danneggiamento al network dove essi esistono, e possono abilmente creare contratti il ​​cui costo è molto inferiore al costo pagato dagli altri nodi di verifica. - -(1) sia fornita una predisposizione per il miner ad includere meno transazioni, e (2) si incrementi `NC`; quindi, questi due effetti si elidono, almeno parzialmente, a vicenda. (3) e (4) sono i maggiori problemi; per risolverli istituiamo semplicemente un tetto limite: nessun blocco può avere più operazioni che `BLK_LIMIT_FACTOR` rispetto la media esponenziale a lungo termine. Nello specifico: - - blk.oplimit = floor((blk.parent.oplimit * (EMAFACTOR - 1) + floor(parent.opcount * BLK_LIMIT_FACTOR)) / EMA_FACTOR) - -`BLK_LIMIT_FACTOR` e `EMA_FACTOR` sono costanti che saranno impostate a 65536 e 1.5 per il momento, ma probabilmente saranno oggetto di cambiamenti dopo un'ulteriore analisi. - -C'è un altro fattore che si pone come disincentivo alla grandezza dei grandi blocchi in Bitcoin: i blocchi che sono grandi impiegheranno più tempo a propagarsi, e quindi avranno una maggiore probabilità di diventare latenti. In Ethereum, i blocchi che consumano una larga quantità di gas possono anche impiegare più tempo a propagarsi sia perchè essi sono fisicamente più grandi e sia perchè impiegano più tempo affinché la transizione della transazione di stato sia validata. Il disincentivo del ritardo è un'importante considerazione in Bitcoin, ma di meno in Ethereum a causa del protocollo GHOST; perciò, si produce uno standard più stabile bansandosi su limiti di blocco regolati. - -### Computazione e completezza di Turing - -Un'importante osservazione è che Ethereum virtual machine è Turing-complete; questo significa che il codice EVM può codificare qualsiasi computazione, compresi loops infiniti, che possa essere teoricamente adempiuta. Il codice EVM permette il loop in due modi. Per primo, c'è un'istruzione `JUMP` che consente al programma di tornare indietro a un punto precedente nel codice, ed un'istruzione `JUMPI` per eseguire, a certe condizioni, dei salti, permettendo asserzioni come `while x < 27: x = x * 2`. In seconda istanza, i contratti possono, permettendo potenzialmente loops tramite ricorsione, chiamare altri contratti. Naturalmente da ciò può derivare un problema: possono, nella pratica, utenti malevoli far spegnere i miners e i nodi completi, fornzandoli ad entrare in un loop infinito? La problematica nasce a causa di un problema noto nella computer science come quello della terminazione: in generale non c'è modo di chiedere se un programma terminerà mai. - -La nostra soluzione, come è stato illustrato nella sezione della transizione di stato, funziona attraverso la richiesta ad una transazione di impostare un numero massimo di fasi di computazione impiegabili, e se un'esecuzione impiega una computazione più lunga, essa viene fatta tornare indietro, mentre le commissioni dovranno essere lo stesso pagate. I messaggi funzionano allo stesso modo. Per mostrare la motivazione che sta dietro la nostra soluzione, si considerino i seguenti esempi: -* Un attaccante crea un contratto che esegue un loop infinito, e quindi invia una transazione che attiva questo loop presso il miner. Quest'ultimo processerà la transazione, eseguendo il loop infinito, aspettando che questo esaurisca il gas. Perfino se l'esecuzione termina il gas e si ferma a metà, la transazione sarà ancora valida ed il miner potrà ancora richiedere dall'attaccante la commissione per ogni fase computazionale. -* Un attaccante crea un loop infinito molto lungo al fine di forzare il miner di eseguire una computazione per il tempo sufficientemente lungo affichè la computazione, nel termine dell'uscita di pochi blocchi, termini e non sarà possibile per il miner includere la transazione per richiedere la commissione. Tuttavia, l'attaccante potrà domandare di sottoscrivere un valore per `STARTGAS`, limitando il numero di steps computazionali che l'esecuzione può richiedere, cosi che il miner saprà in anticipo se la computazione impiegherà un numero eccessivamente grande di fasi. -* Un attaccante esamina un contratto con un codice di qualche forma come `send(A,contract.storage[A]); contract.storage[A] = 0`, ed invia una transazione con solo gas a sufficienza per far funzionare il primo step, ma non il secondo(ad es. facendo un ritiro ma non facendo diminuire il saldo). L'autore del contratto non necessita di preoccuparsi riguardo la protezione contro questi tipi di attacchi, poichè se l'esecuzione termina a metà strada, questa viene ripristinata attraverso delle modifiche. -* Un contratto finanziario funziona prendendo la media di nove data feed al fine di minimizzare il rischio. Un attaccante sfrutta uno dei data feed, che è pensato per essere modificabile attraverso il meccanismo chiamata-indirizzo-variabile descritto nella sezione dei DAO, e lo converte per eseguire un loop infinito, cercando di forzare con ciò ogni tentativo di richiedere i fondi dal contratto finanziario per far terminare il gas. Comunque, il contratto finanziario può impostare un limite di gas sul messaggio per prevenire questo problema. -L'alternativa alla completezza di Turing è l'incompletezza di Turing, dove `JUMP` e `JUMPI` non esistono e solo dove ad una sola copia di ogni contratto è permesso di esistere nella chiamata nel mucchio in un dato tempo. Con questo sistema, il sistema di commissione descritto e le incertezze attorno l'efficacia della nostra soluzione potrebbero non essere necessarie, come il costo di esecuzione di un contratto potrebbe essere delimitato dalle sue dimensioni, l'incompletezza di Turing non è ancora un grosso limite; di tutti gli esempi di contratto che abbiamo ideato all'interno, finora solo uno richiede un loop, e perfino questo potrebbe essere rimosso eseguendo 26 ripetizioni su una parte di codice di una linea. Fornite le importanti implicazioni della completezza di Turing, e il limitato beneficio, perchè non avere semplicemente un linguaggio di Turing incompleto? In realtà, comunque, la non completezza di Turing è lontana da una soluzione nitida del problema. Per capire il motivo, si considertino i seguenti contratti: - - C0: call(C1); call(C1); - C1: call(C2); call(C2); - C2: call(C3); call(C3); - ... - C49: call(C50); call(C50); - C50: (esegue uno step di un programma e registra il cambiamento nello storage) - -Adesso, si invii una transazione ad A. Quindi, in 51 transazioni, noi abbiamo un contratto che impiega 250 steps computazionali. I Miners potrebbero tentare di scoprire, prima del tempo, tali bombe logiche, mantenendo un valore accanto ad ogni contratto, specificando il numero massimo di steps computazionali che esso può impiegare, e calcolando questo per i contratti che chiamano altri contatti in maniera ricorsiva, ma questo potrebbe richiedere ai miners di proibire i contratti che creano altri contratti (visto che la creazione e l'esecuzione di tutti i 26 contratti di cui sopra potrebbe essere facilmente convogliata in un contratto singolo). Un altro punto problematico è che il campo dell'indirizzo di un messaggio è una variabile, così in generale potrebbe non essere perfino possibile dire quali altri contratti, un certo contratto, avrà chiamato anzitempo. Quindi, complessivamente, noi giungiamo ad una sorprendente conclusione: la completezza di Turing è sorprendentemente facile da gestire, e l'assenza di questa è allo stesso modo difficile da amministrare a meno che siano assegnati gli stessi identici controlli - ma in questo caso perché non permettere al protocollo di essere Turing-complete? - -### Valuta ed Emissione - -Il network di Ethereum include una valuta costruita al suo interno, ether, che ha il duplice scopo di fornire uno strato di primario di liquidità per permettere un exchange efficiente tra due tipi di assets digitali e, principalmente, di fornire un meccanismo per pagare le commissioni di transazione. Per comodità e per evitare possibili futuri frantendimenti (si veda il presente dibattito mBTC/uBTC/satoshi in Bitcoin), le denominazioni vengono assegnate prima: - -* 1: wei -* 1012: szabo -* 1015: finney -* 1018: ether - -Ciò dovrebbe essere considerato come un'analogia con il concetto di "dollari" e "centesimi" o "BTC" e "satoshi". Nel futuro prossimo, ci aspettiamo che "ether" sia impiegato per le transazioni ordinarie, "finney" per le microtransazioni e "szabo" e "wei" per discussioni tecniche riguardo l'implementazione del protocollo; le rimanenti denominazioni potrebbe diventare utili più avanti e non dovrebbero essere, al momento, incluse nei clients. - -Il modello di emissione sarà come segue: - -* Ether sarà rilasciato in una vendita di moneta al prezzo di 1000-2000 ether per BTC, un meccanismo che intende finanziare l'organizzazione Ethereum e pagare per lo sviluppo come è successo in altre piattaforme come Mastercoin e NXT. I primi compratori beneficeranno di grandi sconti. I BTC raccolti dalla vendita saranno interamente usati per pagari i salari per i premi agli sviluppatori e investiti per vari progetti profit e non profit in Ethereum e nell'ecosistema delle criptomonete. -* 0.099x del totale dell'ammontare venduto (60102216 ETH) sarà allocato all'organizzazione per compensare i primi contributori e pagare le spese denominate in ETH prima del blocco di genesi. -* 0.099x del totale dell'ammontare venduto sarà conservato come una riserva a lungo termine. -* 0.26x del totale dell'ammontare venduto sarà conferito ai miners ogni anno dopo questo momento. - -| Group | Al lancio | Dopo 1 anno | Dopo 5 anni -| ------------- | ------------- |-------------| ----------- | -| Unità di moneta | 1.198X | 1.458X | 2.498X | -| Compratori | 83.5% | 68.6% | 40.0% | -| Riserva spesa prima della vendita | 8.26% | 6.79% | 3.96% | -| Riserva usata dopo la vendita | 8.26% | 6.79% | 3.96% | -| Miners | 0% | 17.8% | 52.0% | - -**Tasso di Crescita a Lungo-Termine (in percentuale)** - -![SPV in bitcoin](https://blog.ethereum.org/wp-content/uploads/2013/12/issuance-model.jpg) - -_Tuttavia, nonostante l'emissione di valuta lineare, il tasso di crescita dell'offerta, proprio come avviene nel Bitcoin, tende, con il passare del tempo, a zero_ - -Le due principali scelte nel suddetto modello sono (1) l'esistenza e i limiti dell'emissione monetaria, e (2) l'esistenza di un'offerta che cresce costantemente in maniera lineare, al contrario di una fornitura limitata come in Bitcoin. La giustificazione della limitatezza dell'emissione monetaria è la seguente. Se quest'ultima non esistesse, e l'emissione lineare si riducesse a 0.217x per fornire lo stesso tasso di inflazione, quindi la quantità totale di ether potrebbe essere 16.5% di meno e così ogni unità il 19.8% più costosa. Quindi, con l'equilibrio del 19.8% sarebbero acquistati più ether nella vendita, così ogni unità avrebbe di nuovo lo stesso valore di prima. L'organizzazione potrebbe poi avere anche 1.198x di BTC, che potrebbe considerare di dividere in due parti: i BTC originali, e l'addizionale 0.198x. Perciò, questa situazione è esattamente equivalente all'emissione monetaria limitata, ma con un'importante differenza: l'organizzazione conserva soltanto i BTC, e non è incentivata a sostenere il valore di ogni singola unità ether. - -La modello di crescita, che si sviluppa in modo lineare, riduce il rischio di quello che qualcuno vede come un eccessiva concentrazione di ricchezza in Bitcoin, e garantisce agli individui di oggi e di domani una giusta chance di acquistare unità di valuta, mentre allo stesso tempo fornisce un grande incentivo ad ottenere e conservare ether a causa della tasso di crescita della domanda come una percentuale che tende, nel tempo, comunque a zero. Noi anche teoirizziamo ciò perché le monete vengono sempre perse, nel corso del tempo, a causa di incuria, morte, etc, e i soldi persi possono essere immaginati come una percentuale della fornitura totale per un anno, di quella totale quantità di moneta in circolazione, che infine sarà, nei fatti, stabilizzata al valore uguale all'emissione annua diviso il tasso di perdita (ad es. al tasso di perdita dell' 1%, una volta che la fornitura raggiunge il 26X poi 0.26X sarà minata e il 0.26X persa ogni anno, creando un equilibrio). - -Si osservi che nel futuro, è probabile che Ethereum convergerà sul modello del proof-of-stake per la sicurezza, riducendo i requisiti di emissione verso qualcosa tra lo zero e il 0.05X per anno. Lasciamo aperto un "contratto sociale", nel caso in cui l'organizzazione di Ethereum perda i fondi o per qualsiasi altra ragione questi spariscano: chiunque ha il diritto di creare una possibile versione futura di Ethereum, con l'unica sola condizione che la quantità di ether debba essere al massimo pari a `60102216 * (1.198 + 0.26 * n)` dove `n` è il numero di anni dopo dopo il blocco di genesi. I creatori sono liberi, per pagare lo sviluppo, di vendere ad una moltitudine o altrimenti assegnare, qualche parte o tutta la differenza tra la maggior fornitura derivante dal PoS e quella massima possibile. Gli aggiornamenti presentati, che non sono conformi con il contratto sociale, potrebbero giustificamente essere deviati in versioni compatibili. - -### Centralizzazione del Mining - -L'algoritmo di minining del Bitcoin funziona attraverso l'elaborazione da parte dei miner, che si ripete milioni di volte, dello SHA256 su versioni leggermente modificate del'intestazione del blocco, fino a che emerge un nodo la cui versione ha un hash inferiore a quello del bersaglio (attualmente circa 2192). Comunque, questo algoritmo di mining è vulnerabile a due forme di centralizzazione. La prima: l'ecosistema di mining ha finito per essere dominato da ASIC (application-specific integrated circuits), chips per computer disegnati per questo scopo, e quindi migliaia di volte più efficienti per il compito specifico del mining del Bitcoin. Questo significa che il mining del Bitcoin non ha più un alto livello di decentralizzazione ed un fine egualitario, poiché richiede milioni di dollari di capitale per parteciparvi concretamente. In seconda istanza: attualmente la maggior parte dei miners di Bitcoin non eseguono la validazione del blocco in locale; invece, essi fanno conto su una mining pool centralizzata che fornisce le intestazioni di blocco. Questo problema è forse il peggiore: al tempo di questo scritto, le principali tre mining pools controllano indirettamente circa il 50% della potenza di calcolo nel network del Bitcoin, sebbene questo sia mitigato dal fatto che i miners possono migrare verso altre mining pools se una, o un gruppo, di queste tentano un attacco al 51%. - -Lo scopo attuale di Ethereum è quello di impiegare un algoritmo di mining dove i miners sono tenuti a recuperare dati randomici dallo stato, elaborare qualche transazione selezionata a caso dagli ultimi N blocchi nella blockchain, e fornire come risultato un hash. Questo ha due importanti benefici. Il primo, i contratti Ethereum, possono includere qualsiasi tipo di computazione cosi che un ASIC in Ethereum potrebbe essenzialmente essere uno valido per una computazione generica - ad es. una migliore CPU. Secondariamente, il mining richiede accesso all'intera blockchain, forzando i miners a conservare l'intera blockchain e ad almeno essere in grado di verificare ogni transazione. Questo elimina la necessità della centralizzazione delle mining pools; sebbene le mining pools possono sempre essere utili per il legittimo ruolo per livellare la casualità della distribuzione del premio; comunque questa funzione può essere svolta altrettanto bene dalle pools peer-to-peer pools con nessun controllo centrale. - -Questo modello non è testato, e ci potrebbero essere delle difficoltà lungo il cammino nell'evitare certe ingegnose ottimizzazioni quando si usa un'esecuzione del contratto come algoritmo di mining. Comunque, una funzione particolarmente interessante di questo algoritmo è che permette a chiunque di "screditare", attraverso l'introduzione di un vasto numero di contratti progettati per ostacolare certi ASIC, nella blockchain. Gli incentivi economici sussistono per i produttori di ASIC al fine di impiegare questo tipo trick per attaccarsi tra di loro. Perciò, la soluzione che stiamo sviluppando è in definitiva una economia che si adatta all'essere umano piuttosto che una puramente tecnica. - -### Scalabilità - -Una problematica comune su Ethereum è quella della scalabilità. Come Bitcoin, Ethereum soffre del difetto che ogni transazione necessiti di essere processata da ogni nodo della rete. Con Bitcoin, la grandezza dell'attuale blockchain è all'incirca di 15 GB, crescendo di un 1 MB all'ora. Se il network Bitcoin dovesse processare le 2000 transazioni al secondo di quello di Visa, esso crescerebbe di un 1 MB ogni tre secondi (1 GB per ora, 8 TB all'anno). Ethereum rischia di soffrire di un simile modello di crescita, e, per di più, con l'aggravio che ci saranno molte applicazioni che funzioneranno, invece che solo una moneta come nel caso di Bitcoin, sull'apice della blockchain di Ethereum. Tuttavia, in Ethereum vi è la miglioria derivante dal fatto che i pieni nodi di questo necessitano di conservare, piuttosto che l'intera cronistoria della blockchain, solamente lo stato. - -Il problema sottostante ad una blockchain così grande è il rischio di centralizzazione. Se la grandezza di questa aumenta di, ad es., 100 TB, lo scenario che si prospetterebbe sarebbe quello che solo un limitato numero di business di grandi dimensioni potrebbero elaborare nodi pieni, con tutti gli utenti normali che usano i nodi SPV. In questo tipo di situazione, crescerebbe la potenziale preoccupazione che i nodi pieni potrebbero lavorare nella stessa direzione e concordare tutti per imbrogliare al fine di avere una serie di vantaggi ( ad es. cambiare il premio del blocco, e dare a loro stessi BTC). I nodi leggeri non avrebbero nessun modo di accorgersi, nell'immediato, di ciò. Naturalmente ci sarebbe, nel caso, almeno un nodo pieno che continuerebbe a fare legittimamente il suo lavoro e solamente dopo poche ore sarebbe scoperta la frode attraverso canali come Reddit, ma a quel punto potrebbe essere troppo tardi: spetterebbe agli utenti ordinari di organizzarsi per creare una lista nero dei blocchi forniti, uno sforzo di coordinazione enorme e probabilmente irrealizzabile sima massive and likely infeasible coordination problem sulla stessa scala di quella di ottenere un attacco al 51% di successo. Nel caso di Bitcoin, questo è attualmente un problema, ma esiste una modifica alla blockchain [suggested by Peter Todd](http://sourceforge.net/p/bitcoin/mailman/message/31709140/) che mitigherà questo problema. - -Nel breve termine, Ethereum impiegherà due strategie addizionali per far fronte a questa questione. La prima consiste nel fatto che, gli algoritmi di minining basati sulla blockchain forzeranno ogni miner a creare almeno un nodo pieno, creando un limite inferiore al numero di nodi pieni. Tuttavia, in seconda istanza ed in maniera più importante, noi includeremo una tree root intermedia nello stato della blockchain dopo il processamento di ogni transazione. Perfino se la validazione del blocco è centralizzata, finché esiste un nodo di verifica onesto, il problema della centralizzazione può essere eluso tramite un protocollo di verificazione. Se un miner pubblica un blocco invalido, quel blocco deve essere mal formattato, o lo stato `S[n]` deve essere non corretto. Dato che`S[0]` è noto per essere corretto, ci deve essere qualche primo stato `S[i]` che è corretto dove `S[i-1]` è corretto. Il nodo di verifica fornirebbe l'indice `i`, insieme a una "prova di invalidità" consistente nel sottoinsieme dei nodi del Patricia tree che necessitano di essere processati `APPLY(S[i-1],TX[i]) -> S[i]`. I nodi sarebbero in grado di usare quei nodi per eseguire quella parte della computazione, ed osservare che `S[i]` generato non corrisponde al `S[i]` fornito. - -Un ulteriore, e più sofisticato, attacco coinvolgerebbe i miners malevoli che pubblicano i blocchi incompleti, in modo tale che non sia necessaria tutta l'informazione per determinare quali blocchi siano validi e quali invalidi. La soluzione a questo è un protocollo che risponde-ad-una-sfida: i nodi di verificazione emettono "sfide" con l'obiettivo di andare a colpire gli indici delle transazioni, e fino alla ricezione di un nodo pieno, uno non completo considera il blocco come non attendibile finché un altro nodo pieno, sia del miner che di un altro verificatore, fornisce un sottoinsieme di nodi Patricia come prova di validità. - -## Conclusioni - -Il protocollo Ethereum è stato originariamente concepito come una versione aggiornata di una criptomoneta, che fornisce caratteristiche avanzate come un escrow sulla blockchain, limiti ai prelievi, contratti finanziari, mercati del gioco e simili attraverso un linguaggio di programmazione gambling markets and the like via a tutto raggio. Il protocollo Ethereum non "supporterà" direttamente alcun tipo di applicazione, ma l'esistenza di un linguaggio di programmazione Turing-complete significa che possono teoricamente essere creati dei contratti arbitrari per qualsiasi tipo di transazione o applicazione. Tuttavia, la cosa più interessante in Ethereum, è che il suo protocollo comprende molto di più che una valuta. I protocolli sullo storage decentralizzato di file, computazione decentralizzata e mercati predittivi decentralizzati, ed altre decine di concetti di questo tipo, hanno il potenziale di aumentare sensibilmente l'efficienza dell'industria relativa al calcolo computazionale, e firnire una spinta enorme agli altri protocolli peer-to-peer aggiungendo per la prima volta un protocollo economico. Infine, c'è anche una consistente gamma di applicazione che non hanno nulla a che vedere con i soldi. - -Il concetto di una funzione arbitraria di transizione di stato come implementata nel procollo di Ethereum con una piattaforma dal potenziale unico; piuttosto che essere una del tipo chiuso, con un protocollo che ha un solo fine inteso per un'unica speficica gamma di applicazioni nello storage dei dati, gioco o finanza, Ethereum ha un design aperto a tutti, e noi crediamo che sia molto adatta per servire, negli anni che verranno, da protocollo fondante per un grande numero di protocolli sia finanziari che non finanziari. - -## Note e Approfondimenti - -#### Note - -1. Un lettore più esperto potrebbe notare che, in effetti, un indirizzo Bitcoin è l' hash di una chiave pubblica dalla curva ellettica, e non la stessa chiave pubblica. Tuttavia, nella practica, è perfettamente legittimo, in termini di terminologia crittografica, riferirsi alla chiave pubblica dell'hash come la stessa chiave pubblica. Questo poiché la crittografia del Bitcoin può essere considerata come un algoritmo di firma digitale personalizzata, dove la chiave pubblica consiste nell' hash della ECC pubkey, la firma consiste nell' ECC pubkey concatenata con la firma ECC, e l'algoritmo di verificazione coinvolge il controllo della ECC pubkey nella firma sull'hash della ECC pubkey fornita come chiave pubblica e quindi verificando la firma dell'ECC sulla pubkey ECC. -2. Tecnicamente, la media degli 11 blocchi precedenti. -3. Internamente, 2 e "CHARLIE" sono entrambi numeri, mentre quest'ultimo è una rappresentazione big-endian base 256. I numeri possono almeno essere 0 o al massimo 2256-1. - -#### Approfindimenti - -1. Intrinsic value: http://bitcoinmagazine.com/8640/an-exploration-of-intrinsic-value-what-it-is-why-bitcoin-doesnt-have-it-and-why-bitcoin-does-have-it/ -2. Smart property: https://en.bitcoin.it/wiki/Smart_Property -3. Smart contracts: https://en.bitcoin.it/wiki/Contracts -4. B-money: http://www.weidai.com/bmoney.txt -5. Reusable proofs of work: http://www.finney.org/~hal/rpow/ -6. Secure property titles with owner authority: http://szabo.best.vwh.net/securetitle.html -7. Bitcoin whitepaper: http://bitcoin.org/bitcoin.pdf -8. Namecoin: https://namecoin.org/ -9. Zooko's triangle: http://en.wikipedia.org/wiki/Zooko's_triangle -10. Colored coins whitepaper: https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit -11. Mastercoin whitepaper: https://github.com/mastercoin-MSC/spec -12. Decentralized autonomous corporations, Bitcoin Magazine: http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/ -13. Simplified payment verification: https://en.bitcoin.it/wiki/Scalability#Simplifiedpaymentverification -14. Merkle trees: http://en.wikipedia.org/wiki/Merkle_tree -15. Patricia trees: http://en.wikipedia.org/wiki/Patricia_tree -16. GHOST: http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf -17. StorJ and Autonomous Agents, Jeff Garzik: http://garzikrants.blogspot.ca/2013/01/storj-and-bitcoin-autonomous-agents.html -18. Mike Hearn on Smart Property at Turing Festival: http://www.youtube.com/watch?v=Pu4PAMFPo5Y -19. Ethereum RLP: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP -20. Ethereum Merkle Patricia trees: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree -21. Peter Todd on Merkle sum trees: http://sourceforge.net/p/bitcoin/mailman/message/31709140/ \ No newline at end of file diff --git a/pages/other-languages/[Japanese]-Cryptocurrency-Current-Problems.md b/pages/other-languages/[Japanese]-Cryptocurrency-Current-Problems.md deleted file mode 100644 index c99a19859..000000000 --- a/pages/other-languages/[Japanese]-Cryptocurrency-Current-Problems.md +++ /dev/null @@ -1,512 +0,0 @@ ---- -name: Cryptocurrency Current Problems -category: ---- - -暗号学において、形式であり、かつシステマティックなThe science of cryptography, which has existed to some degree for millennia but in a formal and systematized form for less than fifty years, can be most simply defined as the study of communication in an adversarial environment. In a similar vein, we can define cryptoeconomics as a field that goes one step further: the study of economic interaction in an adversarial environment. To distinguish itself from traditional economics, which certainly studies both economic interaction and adversaries, cryptoeconomics generally focuses on interactions that take place over network protocols. Particular domains of cryptoeconomics include: - -1. オンライン上の信頼と評価のシステム - -2. 暗号化されたトークンと暗号通貨と、より一般的なデジタルのアセット - -3. 自動執行されるスマートコントラクト - -4. コンセンサスアルゴリズム - -5. アンチスパム・アンチ市民アタックのアルゴリズム - -6. コンピューターのリソース売買のための利益が循環するマーケットプレイス - -7. 分散形の社会福祉システム、互助システム - -8. 分散形の政府(営利または非営利) -* Online trust and reputation systems -* Cryptographic tokens / cryptocurrencies, and more generally digital assets -* Self-executing "smart" contracts -* Consensus algorithms -* Anti-spam and anti-sybil attack algorithms -* Incentivized marketplaces for computational resources -* Decentralized systems for social welfare / mutual aid / basic income -* Decentralized governance (for both for-profit and non-profit entities) - -The increasing prominence of cryptoeconomics in the last five years is to a large extent the result of the growth of cryptocurrencies and digital tokens, and brings a new, and interesting, dimension to cryptography. While before cryptography was, by and large, a purely computational and information-theoretic science, with strong guarantees built on security assumptions that are close to absolute, once money enters the picture the perfect world of mathematics must interact with a much more messy reality of human social structures, economic incentives, partial guarantees and known vulnerabilities that can only be mitigated, and not outright removed. While a cryptographer is used to assumptions of the form "this algorithm is guaranteed to be unbreakable provided that these underlying math problems remain hard", the world of cryptoeconomics must contend with fuzzy empirical factors such as the difficulty of collusion attacks, the relative quantity of altruistic, profit-seeking and anti-altruistic parties, the level of concentration of different kinds of resources, and in some cases even sociocultural circumstances. - -In traditional applied cryptography, security assumptions tend to look something like this: - -伝統的な暗号学では、セキュリティでは、これらのことを考えている。 -1. 誰も 2^79移譲のコンピューターステップを行うことが出来ない。 - -2. - -3. nをルートとして持つモジュロのコンポジットを取ることは困難であること。 - -4. 楕円曲線暗号のアルゴリズムの問題を2n/2 時間以上より速く解くことが出来ないこと。 - -1. No one can do more than 279 computational steps -2. Factoring is hard (ie. superpolynomial) -3. Taking nth roots modulo composites is hard -4. The elliptic curve discrete logarithm problem cannot be solved faster than in 2n/2 time - -暗号学に基づく経済では、一方で基本的なセキュリティに対しての要件に加えて: -1. どの個人も、全てのコンピュータリソースの25%以上を持って、システムを壊すことが出来ない -2. どの個人も、全ての資産の25%以上を持ってシステムを壊すことが出来ないこと。(Proof of stake) -3. ある種の保証を行うためのコンピュータリソースの総量に対して支払われるべき費用の総額が、納得できる額を遥かに超えてしまわないこと - -4. 互助主義者や、間抜けものや、政治的、個人的にシステムに反対するものがいることは否定できないが、大多数のユーザーは、論理的に経済的な合理性を中心として行動するであろうこと。l -5. The number of users of a system is large, and users can appear or disappear at any time, although at least some users are persistent -6. Censorship is impossible, and any two nodes can send messages to each other relatively quickly. -7. It is trivial to generate a very large number of IP addresses, and one can purchase an unlimited amount of network bandwidth -8. Many users are anonymous, so negative reputations and debts are close to unenforceable - -There will also be additional security assumptions specific to certain problems. Thus, quite often it will not even be possible to definitively say that a certain protocol is secure or insecure or that a certain problem has been solved. Rather, it will be necessary to create solutions that are optimized for particular empirical and social realities, and continue further and further optimizing them over time. - - -## 技術面について -## Technology - -The decentralized consensus technology used in Bitcoin is impressive to a very large extent because of its simplicity. A 30-year-old problem in computer science was solved via a mechanism which is simple to implement, and so simple to understand that even some semi-technical teenagers can describe the entirety of how it works. However, at the same time the technology in its current form is very limited. The scalability in Bitcoin is very crude; the fact that every full node needs to process every transaction is a large roadblock to the future success of the platform, and a factor preventing its effective use in micropayments (arguably the one place where it is the most useful). Timestamping is flawed, and proof-of-computation algorithms are very limited in the types of computation that they can support. The fact that the original solution was so "easy", however, suggests that there is still a large opportunity to improve, and there are a number of directions in which improvement could be directed. - -### 1. Blockchain Scalability -### 1. ブロックチェーンのスケーラビリティ - -現在最も大きなブロックチェーンの問題は、 -One of the largest problems facing the cryptocurrency space today is the issue of scalability. It is an often repeated claim that, while mainstream payment networks process something like 2000 transactions per second, in its current form the Bitcoin network can only process seven. On a fundamental level, this is not strictly true; simply by changing the block size limit parameter, Bitcoin can easily be made to support 70 or even 7000 transactions per second. However, if Bitcoin does get to that scale, we run into a problem: it becomes impossible for the average user to run a full node, and full nodes become relegated only to that small collection of businesses that can afford the resources. Because mining only requires the block header, even miners can (and in practice most do) mine without downloading the blockchain. - -The main concern with this is trust: if there are only a few entities capable of running full nodes, then those entities can conspire and agree to give themselves a large number of additional bitcoins, and there would be no way for other users to see for themselves that a block is invalid without processing an entire block themselves. Although such a fraud may potentially be discovered after the fact, power dynamics may create a situation where the default action is to simply go along with the fraudulent chain (and authorities can create a climate of fear to support such an action) and there is a coordination problem in switching back. Thus, at the extreme, Bitcoin with 7000 transactions per second has security properties that are essentially similar to a centralized system like Paypal, whereas what we want is a system that handles 7000 TPS with the same levels of decentralization that cryptocurrency originally promised to offer. - -Ideally, a blockchain design should exist that works, and has similar security properties to Bitcoin with regard to 51% attacks, that functions even if no single node processes more than `1/n` of all transactions where `n` can be scaled up to be as high as necessary, although perhaps at the cost of linearly or quadratically growing secondary inefficiencies and convergence concerns. This would allow the blockchain architecture to process an arbitrarily high number of TPS but at the same time retain the same level of decentralization that Satoshi envisioned. - -**Problem**: create a blockchain design that maintains Bitcoin-like security guarantees, but where the maximum size of the most powerful node that needs to exist for the network to keep functioning is substantially sublinear in the number of transactions. - -**Additional Assumptions and Requirements**: - -* There exist a large number of miners in the network -* Miners may be using specialized hardware or unspecialized hardware. Specialized hardware should be assumed to be more powerful than unspecialized hardware by a large (eg. 10000) constant factor at specific tasks. -* Ordinary users will be using unspecialized hardware -* Ideally, after some number of blocks (perhaps logarithmic in the total size of the network) every transaction should require 51% of network hashpower to reverse. However, solutions where transactions can pay very small fees for a lower "level" of security are acceptable, though one should take care to avoid situations where an attacker can profit by performing one attack to reverse very many small transactions at the same time -* Ideally, the solution should work for and maintain as many properties as possible of a generalized account-based blockchain (eg. Ethereum), though solutions specific to currency, domain registrations or other specialized use caes are acceptable - -### 2. Timestamping -### 2. タイムスタンプ - - -An important property that Bitcoin needs to keep is that there should be roughly one block generated every ten minutes; if a block is generated every day, the payment system becomes too slow, and if a block is generated every second there are serious centralization and network efficiency concerns that would make the consensus system essentially nonviable even assuming the absence of any attackers. To ensure this, the Bitcoin network adjusts difficulty so that if blocks are produced too quickly it becomes harder to mine a new block, and if blocks are produced too slowly it becomes easier. - -However, this solution requires an important ingredient: the blockchain must be aware of time. In order to solve this problem, Bitcoin requires miners to submit a timestamp in each block, and nodes reject a block if the block's timestamp is either (i) behind the median timestamp of the previous eleven blocks, or (ii) more than 2 hours into the future, from the point of view of the node's own internal clock. This algorithm is good enough for Bitcoin, because time serves only the very limited function of regulating the block creation rate over the long term, but there are potential vulnerabilities in this approach, issues which may compound in blockchains where time plays a more important role. - -**Problem**: create a distributed incentive-compatible system, whether it is an overlay on top of a blockchain or its own blockchain, which maintains the current time to high accuracy. - -**Additional Assumptions and Requirements** - -* All legitimate users have clocks in a normal distribution around some "real" time with standard deviation 20 seconds. -* No two nodes are more than 20 seconds apart in terms of the amount of time it takes for a message originating from one node to reach any other node. -* The solution is allowed to rely on an existing concept of "N nodes"; this would in practice be enforced with proof-of-stake or non-sybil tokens (see #9). -* The system should continuously provide a time which is within 120s (or less if possible) of the internal clock of >99% of honestly participating nodes. Note that this also implies that the system should be self-consistent to within about 190s. -* The system should exist without relying on any kind of proof-of-work. -* External systems may end up relying on this system; hence, it should remain secure against attackers controlling < 25% of nodes regardless of incentives. - -### 3. Arbitrary Proof of Computation -### 3. 人為的なコンピュテーションの証拠 -Perhaps the holy grail of the study zero-knowledge proofs is the concept of an arbitrary proof of computation: given a program P with input I, the challenge is to create a zero-knowledge proof that you ran P with input I and received output O, such that the proof can be verified quickly (ie. in polylogarithmic or ideally constant time) even if the original computation took a very large number of steps to complete. In an ideal setup, the proof would even hide the value of I, just proving that you ran P with some output with result O, and if I needs to be made public it can be embedded into the program. Such a primitive, if possible, would have massive implications for cryptocurrency: - -1. ブロックチェーンのスケーラビリティは、マイナーが一連のトランザクションを含めねければ、一層簡単に解くことが出来る。 -このようにして、コンピュテーションを行っているあらゆるノードにおいて、承認されなければならない。 -コンピュテーションを証明するだけでなく、その証拠が新しい状態で合ったとして受け入れなければならない。 -これは完全な解決策ではない、何故なら、それでもなお、データを出力する必要があるが、問題は強力な構成されたブロックよりも簡単に解決される。 - -1. The blockchain scalability problem would be much easier to solve. Instead of miners publishing blocks containing a list of transactions, they would be publishing a proof that they ran the blockchain state updater with some list of transactions and produced a certain output; thus, instead of transactions needing to be verified by every node in the network, they could be processed by one miner and then every other miner and user could quickly verify the proof of computation and if the proof turns out correct they would accept the new state. This is not a complete solution, because there would still be a need to transmit data, but the problem would be much easier with this powerful building block. -2. The blockchain privacy problem would be much easier to solve. The blockchain scalability solution above would hide the details behind individual transactions; it would only reveal the fact that all of them are legitimate, so transactions would be hidden from everyone but the sender and the receiver. -3. It would become computationally viable to use a Turing-complete consensus network as a generic distributed cloud computing system; if you have any computation you wanted done, you would be able to publish the program for miners and miners would be able to run the program for you and deliver the result alongside a proof of its validity. - -There is a large amount of existing research on this topic, including a protocol known as "SCIP" (Succinct Computational Integrity and Privacy) that is already working in test environments, although with the limitation that a trusted third party is required to initially set up the keys; use of this prior work by both its original developers and others is encouraged. - -**Problem**: create programs `POC_PROVE(P,I) -> (O,Q)` and `POC_VERIFY(P,O,Q) -> { 0, 1 }` such that `POC_PROVE` runs program `P` on input `I` and returns the program output `O` and a proof-of-computation `Q` and `POC_VERIFY` takes `P`, `O` and `Q` and outputs whether or not `Q` and `O` were legitimately produced by the `POC_PROVE` algorithm using `P`. - -**Requirements And Additional Assumptions** - -* The runtime of `POC_PROVE` should be in `O(n*polylog(n))` where `n` is the number of steps required to run the program. -* The runtime of `POC_VERIFY` should be either constant or logarithmic in the number of steps, and at most linear in the maximum memory usage of the program. -* The protocol should require no trusted third parties. If TTPs are required, the protocol should include a mechanism for simulating one efficiently using secure multiparty computation. - -### 4. Code Obfuscation -### 4. コードの不明瞭さ -どのようにシンプルに冗長に、双方のキーの暗号化のために、よくテストされたアルゴリズムに暗号化するかについては、 -古くから我々は良く知ってきた。同じキーは暗号化と復号化に必要とされる場所で、そして、公開鍵暗号では、 -同じ鍵は -しかしながら、他の種類の暗号化が潜在的にとても有用になりうる、しかし、現在我々は伝わる形のアルゴリズム、暗号化のためのプログラムだ。 - -2007年には、完璧なブラックボックスとなる暗号化が不可能であることが証明された。 -ブラックボックス化されたアクセスをプログラムに対して持つことと、ブラックボックス化されたコードをプログラムに対してもつことには、違いがある。どれだけコードを難読化しようとも、難読化に対して抵抗のあるプログラムを創りあげることは出来る。 -しかしながら、それは弱いレベルの難読化であり、難読化に対して区別ができるかどうか0としてを定義するのであれば、 -もし同じインプットとアウトプットを持つプログラムが有るならば、0(A) = P と O(B)= Q であり、何もコンピューターリソースとして、 -外部の世界のでのアクセスなしに -PがAから来たのかBから北のかを分かることは出来ない。 - -このような難読化の形式はより一層制限されているように見えるかもしれない、しかしながら多くのアプリケーションにとっては十分である。 -発見的な引数について、 - -**問題**: 合理的に十分である難読化のアルゴリズムを作成することが難しいこと -**追加の前提と必要条件** -* 2^80以上のランタイムが必要とされる -* アルゴリズムは、標準的な楕円曲線暗号化、もしくは10^8のコンピュテーションパワーに耐えうるAESの暗号化 - - -For many years now we have known how to encrypt data. Simple, robust and well-tested algorithms exist for both symmetric key encryption, where the same key is needed to encrypt and decrypt, and public key encryption, where the encryption key and decryption key are different and one cannot be derived from the other. However, there is another kind of encryption that can potentially be very useful, but for which we currently have no viable algorithm: the encryption of programs. The holy grail is to create an obfuscator `O`, such that given any program P the obfuscator can produce a second program `O(P) = Q` such that `P` and `Q` return the same output if given the same input and, importantly, `Q` reveals no information whatsoever about the internals of `P`. One can hide inside of `Q` a password, a secret encryption key, or one can simply use `Q` to hide the proprietary workings of the algorithm itself. - -## 5 Hash-Based Cryptography -暗号通貨の境界線にみ -量子コンピューターの問題である。現在、量子コンピュータは余りにも実現困難であるようにも見えなくなってきている。 -全ての量子コンピューターもしくは"断熱型の量子コンピューター",は、 -極端に限られたプログラムを極めて速い速度で解くことを得意としている。 -しかしながら、起こりにくいこととはいえ、米軍は既に量子コンピューターを手に入れているかもしれない。 -耐量子暗号化を目指す事が幾分高い優先度を持つと考えられる。 - -これまでは、全ての格子上の構造を必要とする有るごリムは、 -個々のメンバーの長さよりも、合計がとても短く -しかしながら、その他のアルゴリズムは耐量子性がある、ハッシュのアルゴリズムだ -古典的なLANポート署名では164 nodes のマークルツリーを作成し、ルートを出版する。そしてハッシュの文書に基づいて選ばれた匿名の82 nodes のマークルツリーの証明を結合させる。 -この署名は、一回の処理でmバルク処理である。 - -ここでの疑問は、より良い方法はないだろうかということだ。 -ハッシュのはしごのように知られている、420バイトまでの署名のサイズを許容するアプローチや、 -他の海藻でのマークルツリーを用いることに依って、署名の数を増やすアルゴリズム、 -そして、 - -しかしながら、これらの方法は不完全であり、もしハッシュに基づく暗号化が、競争力があるアルゴリズムのプロパティであるならば、より良いプロパティを得るために多大に改善する必要がある。 - -**問題** 署名のアルゴリズムは、セキュリティにおいての前提ではなく、ランダムな信頼出来るオラクルのプロパティに依拠している。 -それは、古典的なコンピューター引退しての160bitsのセキュリティを維持しているプロパティである。 -(例えば 80 vs 量子 Groverのアルゴリズムによって)最適化されたサイズと、他のプロパティとである。 - -**前提条件と、付加される前提** -* 224以下に違いない署名を作り出すコンピューターパワーの努力、ハッシュが28 -* 署名のアルゴリズムがスケーラブルであるべきであり、ユーザー数の最大の増加で2xの増加ごとに定数のバイトを署名毎に追加することを犠牲に、もし可能であるならば、そのセットアップに掛かる時間は使用回数に対して直線的であるべきだ。 - -### 6. ASIC-Resistant Proof of Work -問題を解決するための一つの方法は、 -特定化するのがとても困難であるコンピュテーションのタイプに基づいたProof of work のアルゴリズムを作成するということだ -あるアイディアでは、ハッシュのファンクションを"メモリー上に"生成し、より一層ASICが並行稼動することを難しくすることがある。 -このアイディアはとてもシンプルだが、根本的に限られている。もし、関数がメモリー上でのみ動くのであれば、それはメモリーでしか承認出来ない。加えて、平行化を超えたアルゴリズムには -他のアプローチとしては、ランダムで、マニングのファンクションをブロックごとに生成いs,特定性を -ASICが理想的には、任意のコンピュテーションをシンプルなCPUである -**問題** 2つの `PoWProduce(data, diff) - > nonce` and `PoWVerify(datam nonce, diff) - > {0, 1}` をハッシュキャッシュの代わりとなるように提供することによって、経済的にメリットのない`PoWを作り出す`ためのASICを生み出すことに繋がってしまった。 - -**追加の前提条件と必要条件** : -* `PoWの生成` `diff`に対してランタイムで直線的で無ければならない。 -* `PoWの承認` `diff`に対して出来る限り多態的に対数的なランタイムを持たなければならない。 -* `PoWの生成`を走らせることは`1`を返す値を生成し、それを`PoWの承認`を行う際に -最も効率的でなければならない、もしくは、最も効率的である状態に近くなければならない。 -+ - - -### 8. Proof of Stake -マイニングの中央集権化の解決策の他のアプローチには、マイニングを一切行わないことがある、そしてそれぞれのノードの重さを図る他のメカニズムによってコンセンサスに至る。 -現在最も有名な代替案はProof of Stake である。即ち、"CPUパワーの1つのユニット"としてのコンセンサスのモデルを扱う代わりに、 -1つの投票が、1津の通貨のユニットとしての1つのボートとなる。 - -とてもシンプルなProof of Stakeのアルゴリズムは、マイナーがマイニングする際に、 -コインを持っているアドレスの秘密鍵を使って署名を行うことをマイナーに求める。ブロックが有効であったならば`sha256(PREVHAS + ADDRESS + TIMESTAMP) < = 2^256 * BALANCE / DIFFICULTY ` where Prevhashがハッシュの前のブロックにある。`Address`は、BalanceとTime stampを持つ署名者のアドレスであり、それは、秒単位での現在のunixtime を表示する。そして`DIfficulty`は署名が成功する度合いを規定するための調整可能なパラメーターである。 - -1見すると、このアルゴリズムは、基本的に全てのマイナーが秒単位でランダムな成功の機会をもっている、そして、あなたのアドレスはが2倍の金額を持っていれば、2倍の成功の確率を得ることが出来る。 - -しかしながらこのアルゴリズムには、1つの大きな欠点がある。: -それが`Nothing At Stake`問題だ。このフォークのイベントの後に、フォークが偶然であれ、悪意を持って過去の歴史に書き加えようとしたのであれ、そしてトランザクションをリバースさせようとしたのであれ、 -全てのマイナーにとって最適化された戦略は、全てのチェーンをマインすることになる。すると、マイナーはどのフォークがブロックチェーンとして勝ったとしても、報酬を得ることが出来る。 -このようにして、経済的に興味のあるマイナーの大多数がいたとしても、攻撃者はなにかの電子的な商品と引き換えにしてトランザクションを送ることが出来る。(通例は他の暗号通貨).そして商品を受け取ると、 -その商品の売買のトランザクションの1つ前に有るブロックからフォークを始める。 -誰もが全てのブロックを採掘しているが故に、全体のStakeの1%を所持している攻撃者であったとしても、攻撃が成功するかもしれない。 - -他にはLong-range attacksと呼ばれる問題が上がっている。 -マイナーがメインチェーンの先頭の5つか10つ前のブロックをフォークを始めようとしているところ、よく起こることだ、しかし何百何千ものブロックを遡る。 -もしアルゴリズムが不適切であるならば、攻撃者がとても前のブロックから始めることが出来るかもしれない。そして何十億ものブロックを将来のブロックとして彫り、(何故ならばProof of Workは必要ないため) - - -In 2007, it was proven that perfect "black box" encryption is impossible; essentially, the argument is that there is a difference between having black-box access to a program and having the code to that program, no matter how obfuscated, and one can construct certain classes of programs that resist obfuscation. However, there is also a weaker notion of obfuscation, known as indistinguishability obfuscation, that appears to be quite possible. The definition of an indistinguishability obfuscator `O` is that if you take two equivalent (ie. same inputs -> same outputs) programs `A` and `B` and calculate `O(A) = P` and `O(B) = Q`, then there is no computationally feasible way for an outsider without access to `A` or `B` to tell whether `P` came from `A` or `B`. - -This type of obfuscation may seem more limited, but it is nevertheless sufficient for many applications. For a heuristic argument why, consider two programs `F` and `G` where `F` internally contains and simply prints out that 32-byte string which is the hash of "12345", whereas G actually computes the hash of "12345" and prints it out. By the indistinguishability obfuscation definition, there is no computationally feasible way to tell `O(F)` from `O(G)` apart. Hence, if one can feasibly recover "12345" from `O(G)`, then for `O(G)` and `O(F)` to be indistinguishable one would also need to be able to feasibly recover "12345" from `O(F)` - a feat which essentially entails breaking the preimage resistance of a cryptographic hash function. - -Recently, a discovery was made by Craig Gentry, Amit Sahai et al on an algorithm which uses a construction known as "multilinear jugsaw puzzles" in order to accomplish this. Their algorithm, described here, claims to satisfy the indistinguishability obfuscation property, although at a high cost: the algorithm requires the use of fully homomorphic encryption, a highly inefficient construction that incurs roughly a one-billion-fold computational overhead. - -If this construction can be made better, the potential benefits are massive. The most interesting possibility in the world of cryptocurrency is the idea of an on-blockchain contract containing private information. This basically allows for the scripting properties of Turing-complete blockchain technologies, such as Ethereum, to be exported into any other financial or non-financial system on the internet; for example, one can imagine an Ethereum contract which contains a user's online banking password, and if certain conditions of the contract are satisfied the contract would initiate an HTTPS session with the bank, using some node as an intermediary, and log into the bank account with the user's password and make a specified withdrawal. Because the contract would be obfuscated, there would be no way for the intermediary node, or any other player in the blockchain, to modify the request in-transit or determine the user's password. The same trick can be done with any other website, or much more easily with a "dumb" blockchain such as Bitcoin. - -**Problem**: create a reasonably efficient indistinguishability obfuscation algorithm. - -**Additional Assumptions and Requirements** - -* Successful attacks must have an expected runtime above 2^80 -* The algorithm should be sufficiently fast that a standard ECDSA signature or an AES encryption should be feasible within 108 computational steps (more specifically, 108 gas in the Ethereum VM) - -### 5. Hash-Based Cryptography - -One of the looming threats on the horizon to cryptocurrency, and cryptography in general, is the issue of quantum computers. Currently, the problem does not seem too severe; all quantum computers are either "adiabatic quantum computers", effective at only an extremely limited set of problems and perhaps not even better than classical computers at all, or machines with a very small number of qubits not capable of factoring numbers higher than 35. In the future, however, quantum computers may become much more powerful, and the recent revelations around the activities of government agencies such as the NSA have sparked fears, however unlikely, that the US military may control a quantum computer already. With this in mind, the movement toward quantum-proof cryptography has become a somewhat higher priority. - -To date, all quantum-proof schemes fall into one of two categories. First, there are algorithms involving lattice-based constructions, relying on the hardness of the problem of finding a linear combination of vectors whose sum is much shorter than the length of any individual member. These algorithms appear to be powerful, and relatively efficient, but many distrust them because they rely on complicated mathematical objects and relatively unproven assumptions. However, there is also another class of algorithms that are quantum-proof: hash-based algorithms. One example of this is the classic Lamport signature: create a Merkle tree of 164 nodes (a figure chosen specifically to match 160 bits of security), publish the root, and then have the signature of a document be the combined Merkle tree proof of a subset of 82 nodes pseudorandomly chosen based on the hash of the document. This signature is one-time, and bulky (~3000 bytes), but fulfils the purpose. - -The question is, can we do better? There is an approach known as hash ladders, allowing the size of a signature to be brought down to 420 bytes, and one can use Merkle trees on another level to increase the number of signatures possible, although at the cost of adding 100-300 bytes to the signature. However, even still these approaches are imperfect, and if hash-based cryptography is to be competitive the properties of the algorithms will need to be substantially improved in order to have nicer properties. - -**Problem**: create a signature algorithm relying on no security assumption but the random oracle property of hashes that maintains 160 bits of security against classical computers (ie. 80 vs. quantum due to Grover's algorithm) with optimal size and other properties. - -**Requirements And Additional Assumptions** - -* The computational effort of producing a signature should be less than 224 computational steps, assuming a hash takes 28 steps (a reasonable assumption due to hardware optimizations and in the future hashing ASICs built into chips) -* The size of a signature should be as small as possible -* The size of a public key should be as small as possible -* The signature algorithm should be scalable to add any number of uses, although likely at the cost of adding a constant number of bytes per signature for every 2x increase in the maximum number of uses, and if possible the setup time should be sublinear in the number of uses. - -## Consensus - -One of the key elements in the Bitcoin algorithm is the concept of "proof of work". In any Byzantine-fault-tolerant system, the security level is often defined as the minimum percentage of hostile nodes - for example, in the context of secret sharing, the Berlekamp-Welch algorithm with 2x redundancy is guaranteed to provide the correct output assuming that the total number of hostile nodes does not exceed 25% of the network, and in the context of Bitcoin mining the requirement is that the size of the set of honest nodes exceeds the size of any individual hostile coalition. However, all of these security guarantees have one important qualification: there must be some way to define what an individual node is. Before Bitcoin, most fault-tolerant algorithms had high computational complexity and assumed that the size of the network would be small, and so each node would be run by a known individual or organization and so it is possible to count each node individually. - -With Bitcoin, however, nodes are numerous, mostly anonymous, and can enter or leave the system at any time. Unless one puts in careful thought, such a system would quickly run into what is known as a Sybil attack, where a hostile attacks simply creates five times as many nodes as the rest of the network combined, whether by running them all on the same machine or rented virtual private server or on a botnet, and uses this supermajority to subvert the network. In order to prevent this kind of attack, the only known solution is to use a resource-based counting mechanism. For this purpose, Bitcoin uses a scheme known as proof-of-work, which consists of solving problems that are difficult to solve, but easy to verify. The weight of a node in the consensus is based on the number of problem solutions that the node presents, and the Bitcoin system rewards nodes that present such solutions ("miners") with new bitcoins and transaction fees. - -Bitcoin's proof of work algorithm is a simple design known as Hashcash, invented by Adam Back in 1995. The hashcash function works as follows: - - def hashcash_produce(data, difficulty): - nonce = random.randrange(2**256) - while sha256(data + str(nonce)) > 2**256 / difficulty: - nonce += 1 - return nonce - - def hashcash_verify(data, nonce, difficulty): - return sha256(data + str(nonce)) <= 2**256 / difficulty - -Note that in the actual Bitcoin protocol nonces are limited to 32 bits; at higher difficulty levels, one is required to also manipulate transaction data in the block as a sort of "extranonce". - -Originally, the intent behind the Bitcoin design was very egalitarian in nature. Every individual would mine on their own desktop computer, producing a highly decentralized network without any point of control and a distribution mechanism that spread the initial supply a BTC across a wide number of users. And for the first 18 months of Bitcoin's existence, the system worked. In the summer of 2010, however, developers released a Bitcoin miner that took advantage of the massive parallelization offered by the graphics processing unit (GPU) of powerful computers, mining about 10-50 times more efficiently than CPUs. In 2013, specialization took a further turn, with the introduction of devices called "application-sepcific integrated circuits" - chips designed in silicon with the sole purpose of Bitcoin mining in mind, providing another 10-50x rise in efficiency. CPU and GPU mining are now completely unprofitable, and the only way to mine is to either start a multimillion-dollar ASIC manufacturing company or purchase an ASIC from one that already exists. - -Another related issue is mining pool centralization. Theoretically, the legitimate function of a mining pool is simple: instead of mining on their own and receiving a small chance of earning the block reward of 25 BTC, miners mine for a pool, and the pool sends them a proportionate constant payout (eg. 0.002 BTC per block). There are centralized mining pools, but there are also P2P pools which serve the same function. However, P2P pools require miners to validate the entire blockchain, something which general-purpose computers can easily do but ASICs are not capable of; as a result, ASIC miners nearly all opt for centralized mining pools. The result of these trends is grim. Right now, nearly 25% of all new ASIC hashpower is produced in a single factory in Shenzhen, and nearly 50% of the network is controlled by a single mining pool. - -The second problem is easy to alleviate; one simply creates a mining algorithm that forces every mining node to store the entire blockchain. The first problem, that of mining centralization, is much harder. There is the possibility that the problem will solve itself over time, and as the Bitcoin mining industry grows it will naturally become more decentralized as room emerges for more firms to participate. However, that is an empirical claim that may or may not come to pass, and we need to be prepared for the eventuality that it does not. Furthermore, the wasted energy and computation costs of proof of work as they stand today may prove to be entirely avoidable, and it is worth looking to see if that aspect of consensus algorithms can be alleviated. - -### 6. ASIC-Resistant Proof of Work - -One approach at solving the problem is creating a proof-of-work algorithm based on a type of computation that is very difficult to specialize. One specific ideas involves creating a hash function that is "memory-hard", making it much more difficult to create an ASIC that achieves massive gains through parallelization. This idea is simple, but fundamentally limited - if a function is memory-hard to compute, it is also generally memory-hard to verify. Additionally, there may be ways to specialize hardware for an algorithm that have nothing to do with hyperparallelizing it. Another approach involves randomly generating new mining functions per block, trying to make specialization gains impossible because the ASIC ideally suited for performing arbitrary computations is by definition simply a CPU. There may also be other strategies aside from these two. - -Ultimately, perfect ASIC resistance is impossible; there are always portions of circuits that are going to be unused by any specific algorithm and that can be trimmed to cut costs in a specialized device. However, what we are looking for is not perfect ASIC resistance but rather economic ASIC resistance. Economic ASIC resistance can be defined as follows. First of all, we note that in a non-specialized environment mining returns are sublinear - everyone owns one computer, say with N units of unused computational power, so up to N units of mining cost only the additional electricity cost, whereas mining beyond N units costs both electricity and hardware. If the cost of mining with specialized hardware, including the cost of research and development, is higher per unit hashpower than the cost of those first N units of mining per user then one can call an algorithm economically ASIC resistant. - -For a more in-depth discussion on ASIC-resistant hardware, see [https://blog.ethereum.org/2014/06/19/mining/](https://blog.ethereum.org/2014/06/19/mining/) - -**Problem**: Create two functions, `PoWProduce(data,diff) -> nonce` and `PoWVerify(data,nonce,diff) -> { 0, 1 }`, to serve as alternatives to Hashcash such that it is economically unattractive to produce an ASIC for `PoWProduce` - -**Additional Assumptions And Requirements**: - -* `PoWProduce` must have expected runtime linear in `diff` -* `PoWVerify` must have runtime at most polylogarithmic in `diff` -* Running `PoWProduce` should be the most efficient, or very close to the most efficient, way to produce values that return `1` when checked with `PoWVerify` (ie. no software optimization) -* `PoWProduce` must not be superlinear in computational power or time; that is to say, the expected number of successful `PoWProduce` computations for a node with `N` dollars worth of hardware after `t` seconds should be bounded by `kNt` for some `k`. Furthermore, the linearity should kick in quickly; ie. $1000 worth of mining hardware should function with over 90% efficiency. -* It should be shown with reasonably rigorous technological and economic analysis that the algorithm is economically ASIC resistant. - -### 7. Useful Proof of Work - -Another related economic issue, often pointed out by detractors of Bitcoin, is that the proof of work done in the Bitcoin network is essentially wasted effort. Miners spend 24 hours a day cranking out SHA256 (or in more advanced implementations Scrypt) computations with the hopes of producing a block that has a very low hash value, and ultimately all of this work has no value to society. Traditional centralized networks, like Paypal and the credit card network, manage to get by without performing any proof of work computations at all, whereas in the Bitcoin ecosystem about a million US dollars of electricity and manufacturing effort is essentially wasted every day to prop up the network. - -One way of solving the problem that many have proposed is making the proof of work function something which is simultaneously useful; a common candidate is something like Folding@home, an existing program where users can download software onto their computers to simulate protein folding and provide researchers with a large supply of data to help them cure diseases. The problem is, however, that Folding@home is not "easy to verify"; verifying the someone did a Folding@home computation correctly, and did not cut corners to maximize their rounds-per-second at the cost of making the result useless in actual research, takes as long as doing the computation oneself. If either an efficiently verifiable proof-of-computation for Folding@home can be produced, or if we can find some other useful computation which is easy to verify, then cryptocurrency mining could actually become a huge boon to society, not only removing the objection that Bitcoin wastes "energy", but even being socially beneficial by providing a public good. - -Note that there is one major concern with this approach that has been identified: if the useful PoW is implemented incorrectly, it can potentially reduce the cost of an attack on the network. If the useful PoW is useful in such a way that it is sometimes economically viable for certain very large entities to perform the computation even without the currency incentive, then those entities have an incentive to launch attacks against the network at no cost, since they would be performing the computations anyway. One simple, though crude and imperfect, way of addressing this problem is to make the PoW a half-and-half mix between useful and useless, making the cost of an attack at least 50% of what it would be in a useless-PoW environemnt. In practice, the overhead of making PoW verifiable may well introduce over 2x inefficiency unintentionally. Another economic solution is to make the computation a "pure" public good such that no individual entity derives a significant benefit from it. Proposed solutions to this problem should include a rigorous analysis of this issue. - -**Problem**: Create two functions, `PoWProduce(data,diff) -> nonce` and `PoWVerify(data,nonce,diff) -> { 0, 1 }`, to serve as alternatives to Hashcash such that the outputs of `PoWProduce` are independently useful. - -**Requirements** - -* `PoWProduce` must have expected runtime linear in `diff` -* `PoWVerify` must have expected runtime at most polylogarithmic in `diff` -* Running `PoWProduce` should be the most efficient way to produce values that return `1` when checked with `PoWVerify` -* `PoWProduce` must not be superlinear in computational power or time; that is to say, the expected number of successful `PoWProduce` computations for a node with `N` dollars worth of hardware after `t` seconds should be bounded by `kNt` for some `k`. Furthermore, the linearity should kick in quickly; ie. $1000 worth of mining hardware should function with over 90% efficiency. -* `PoWProduce` must produce a public good, such that the total value to everyone of the public good produced is greater than the cost of all resources invested into the mining process. -* The system must be able to exist without a trusted third party, but it is reasonable to allow a trusted third party to serve as a data source for useful computations. If the trusted third party acts maliciously in any way, the public good may be negated but the blockchain mining should not be compromised. - -### 8. Proof of Stake - -Another approach to solving the mining centralization problem is to abolish mining entirely, and move to some other mechanism for counting the weight of each node in the consensus. The most popular alternative under discussion to date is "proof of stake" - that is to say, instead of treating the consensus model as "one unit of CPU power, one vote" it becomes "one currency unit, one vote". - -A very simple proof of stake algorithm requires the miner mining the block to sign it with the private key to the address holding their coins, where the block is valid if `sha256(PREVHASH + ADDRESS + TIMESTAMP) <= 2^256 * BALANCE / DIFFICULTY` where `PREVHASH` is the hash of the previous block, `ADDRESS` is the signer's address with balance `BALANCE`, `TIMESTAMP` is the current Unix time in seconds and `DIFFICULTY` is an adjustable parameter to regulate the frequency of successful signatures. At first glance, this algorithm has the basic required properties: every miner has some random chance per second of succeeding, and if your address has twice as much money in it then you have double the chance of success. - -However, this algorithm has one important flaw: there is "nothing at stake". In the event of a fork, whether the fork is accidental or a malicious attempt to rewrite history and reverse a transaction, the optimal strategy for any miner is to mine on every chain, so that the miner gets their reward no matter which fork wins. Thus, assuming a large number of economically interested miners, an attacker may be able to send a transaction in exchange for some digital good (usually another cryptocurrency), receive the good, then start a fork of the blockchain from one block behind the transaction and send the money to themselves instead, and even with 1% of the total stake the attacker's fork would win because everyone else is mining on both. - -Another problem to keep in mind is the issue of so-called "long-range attacks" - attacks where the miner attempts to start a fork not five or ten blocks behind the head of the main chain, as happens normally, but hundreds of thousands of blocks back. If an algorithm is designed incorrectly, it may be possible for an attacker to start from that far back, and then mine billions of blocks into the future (since no proof of work is required), and new users would not be able to tell that the blockchain with billions of blocks more is illegitimate. This can generally be solved with timestamping, but special corner cases do tend to appear in overcomplicated designs. - -The Slasher algorithm, described [here](http://blog.ethereum.org/2014/01/15/slasher-a-punitive-proof-of-stake-algorithm/) and implemented by Zack Hess as a proof-of-concept [here](https://github.com/zack-bitcoin/slasher), represents my own attempt at fixing the nothing-at-stake problem. The core idea is that (1) the miners for each block are determined ahead of time, so in the event of a fork a miner will either have an opportunity to mine a given block on all chains or no chains, and (2) if a miner is caught signing two distinct blocks with the same block number they can be deprived of their reward. The algorithm is viable and effective, but it suffers from two flaws of unknown significance. First, if all of the miners for a given block learn each other's identities beforehand, they can meet up and collude to shut down the network. Second, the nothing-at-stake problem remaing for attacks going back more than 3000 blocks, although this is a smaller issue because such attacks would be very obvious and can automatically trigger warnings. - -For a more in-depth discussion on proof of stake, see [https://blog.ethereum.org/2014/07/05/stake/](https://blog.ethereum.org/2014/07/05/stake/) - -**Problem**: create a proof-of-stake algorithm that solves the nothing-at-stake problem and long-range attack problems, without introducing new collusion risks that require less than 25% of stakeholders to succeed. - -**Additional Requirements And Assumptions** - -* The expected return from mining should be bounded by `k` times the miner's stake for some `k`, and assuming $1 billion total participating stake a stake of $1000 should be able to reach 90% of this maximum efficiency. -* The algorithm should be fully incentive-compatible, addressing the double-voting issue defined above and the collusion issue defined above at both short and long range. - -### 9. Proof of Storage - -A third approach to the problem is to use a scarce computational resource other than computational power or currency. In this regard, the two main alternatives that have been proposed are storage and bandwidth. There is no way in principle to provide an after-the-fact cryptographic proof that bandwidth was given or used, so proof of bandwidth should most accurately be considered a subset of social proof, discussed in later problems, but proof of storage is something that certainly can be done computationally. An advantage of proof-of-storage is that it is completely ASIC-resistant; the kind of storage that we have in hard drives is already close to optimal. - -The most simple algorithm for proving that you own a file with `N` blocks is to build a Merkle tree out of it, publish the root, and every `k` blocks publish a Merkle tree proof of the `i`th block where `i` is the previous block hash mod `N`. However, this algorithm is limited because it is only a simple building block, not a complete solution. In order to turn this into a currency, one would need to determine which files are being stored, who stores whose files, to what extent and how the system should enforce redundancy, and if the files come from the users themselves how to prevent compression optimizations and long-range attacks. - -Currently, the latest work in this area are two projects called Permacoin and Torcoin, which solve some of the problems in proof of storage with two insights. First, users should not be able to choose which files they store. Instead, files should be randomly selected based on their public key and users should be required to store ALL of the work assigned or else face a zero reward. This idea, provided in the context of proof of bandwidth in the case of Torcoin, prevents attacks involving users only storing their own data. Second, a Lamport-like signature algorithm can be used that requires users to have their private key and store their file locally; as a result; uploading all of one's files to the cloud is no longer a viable strategy. This, to some degree, forces redundancy. - -However, the problem with Permacoin is that it leaves unclear what files should be stored; cryptocurrency issuance can theoretically pay for billions of dollars of work per year, but there is no single static archive whose storage is worth billions. Ideally, the system would allow for new files to be added, and perhaps even allow users to upload their own files, but without introducing new vulnerabilities. - -**Problem**: create a currency that uses proof-of-storage as its consensus and distribution algorithm. - -**Additional Assumptions And Requirements** - -* The currency must be future-proof, being able to expand the amount of data stored over time; the system should not eventually fall into some failure state if hard disk space continues to get cheaper and more efficient. -* The currency should ideally be maximally useful. At the least, the currency should allow people to upload their own files and have them stored, providing an uploading network with minimal cryptographic overhead, although ideally the currency should select for files that are public goods, providing net total value to society in excess of the number of currency units issued. -* The expected return from mining should be at most slightly superlinear, ie. it must be bounded by `ks/(1-s)` for some `k`, where `s` is the miner's share of the total network, although perfect linearity is ideal. -* The system should be maximally resistant against mining pool centralization as a result of any small degree of superlinearity. -* The system should be secure against nothing-at-stake and long-range attacks. -* The system should be secure against attacker involving users uploading specially formatted files or storing their own data. - -## Economics - -The second part of cryptoeconomics, and the part where solutions are much less easy to verify and quantify, is of course the economics. Cryptocurrencies are not just cryptographic systems, they are also economic systems, and both kinds of security need to be taken into account. Sometimes, cryptographic security may even be slightly compromised in favor of an economic approach - if a signature algorithm takes more effort to crack than one could gain from cracking it, that is often a reasonable substitute for true security. At the same time, economic problems are also much more difficult to define. One cannot usually definitively know whether or not a problem has been solved without extensive experimentation, and the result will often depend on cultural factors or the other organizational and social structures used by the individuals involved. However, if the economic problems can be solved, the solutions may often have reach far beyond just cryptocurrency. - -### 10. Stable-value cryptoassets - -One of the main problems with Bitcoin is the issue of price volatility. The value of a bitcoin often experiences very large fluctuations, rising or falling by as much as 25% in a single day and 3x in a month. The main economic reason behind this is that the supply of bitcoins is fixed, so its price is directly proportional to demand (and therefore, by efficient market hypothesis, the expected discounted future demand), and demand is very unpredictable. It is not known if Bitcoin will be simply a niche payment method for transcations requiring a high degree of privacy, a replacement for Western Union, a mainstream consumer payment system or the reserve currency of the world, and the expected value of a bitcoin differs over a thousandfold between these various levels of adoption. Furthermore, the utility of the Bitcoin protocol is heavily dependent on the movements of the Bitcoin price (ie. people are interested in Bitcoin more if the price is going up), creating a positive feedback loop, which has arguably been responsible for both Bitcoin's great meteoric rises and its many-month-long periods of rapid decline. - -To solve this problem, there are generally two paths that can be taken. The first is to have the network somehow detect its current level of economic usage, and have a supply function that automatically increases supply when usage increases. This reduces uncertainty; even though the expected future level of adoption of the protocol may have a variance of 10-100x, the circumstance where adoption increases 100x will also have 100x more supply and so the value of the currency will remain the same. There is a problem that if usage decreases there is no way to remove units from circulation, but even still the lack of upward uncertainty should reduce upward volatility, and downward volatility would also naturally reduce because it is no longer bad news for the value of the currency when an opportunity for increased usage is suddenly removed. Furthermore, in the long term the economy can be expected to grow, so the zero-supply-growth floor may not even ever be reached in practice. - -The problem is that measuring an economy in a secure way is a difficult problem. The most obvious metric that the system has access to is mining difficulty, but mining difficulty also goes up with Moore's law and in the short term with ASIC development, and there is no known way to estimate the impact of Moore's law alone and so the currency cannot know if its difficulty increased by 10x due to better hardware, a larger user volume or a combination of both. Other metrics, such as transaction count, are potentially gameable by entities that want the supply to change in a particular direction (generally, holders want a lower supply, miners want a higher supply). - -Another approach is to attempt to create a currency which tracks a specific asset, using some kind of incentive-compatible scheme likely based on the game-theoretic concept of Schelling points, to feed price information about the asset into the system in a decentralized way. This could then be combined with a supply function mechanism as above, or it can be incorporated into a zero-total-supply currency system which uses debts collateralized with other cryptographic assets to offset its positive supply and thus gain the ability to grow and shrink with changes to usage in either direction. The problem here is constructing the scheme in such a way that there is no incentive for entities to feed in false price information in order to increase or decrease the supply of the asset in their favor. - -**Problem**: construct a cryptographic asset with a stable price. - -**Requirements** - -* The expected root-mean-square daily change in the logarithm of the price of the asset should be less than 25% of that of Bitcoin under similar conditions. Ideally, the asset should be guaranteed to almost always maintain a value within 10% of an arbitrary cryptographic or real-world asset for which price information is easily accessible -* The expectation analysis should take into account black swan risks (ie. systems where the variance is 0% 99% of the time but 10x in a day the other 1% of the time are unacceptable) -* The solution must come with a model, including parameters such as short-term-consumption purchases, medium-term purchases, speculative purchases, positive and negative media, adoption and regulatory events, irrational actors and actors with political motives, show that their model well fits the history of Bitcoin and potentially major altcoins without overfitting, and show that under the model the other two requirements hold -* Zero-total-supply assets, ie. assets where each unit is balanced by a collateralized debt of a unit, are allowed, although such systems must include a robust margin-calling mechanism because it is assumed that most users are anonymous and can therefore trivially run away from debts - -### 11. Decentralized Public Goods Incentivization - -One of the challenges in economic systems in general is the problem of "public goods". For example, suppose that there is a scientific research project which will cost $1 million to complete, and it is known that if it is completed the resulting research will save one million people $5 each. In total, the social benefit is clear: if everyone contributes $1, then each individual person will see a benefit of $5 - $1 = $4 for $4 million total. However, the problem is that from the point of view of each individual person contributing does not make sense - whether or not you contribute has close to zero bearing on whether enough money will be collected, so everyone has the incentive to sit out and let everyone else throw their money in, with the result that no one does. - -So far, most problems to public goods have involved centralization; some large organization, whether a big company or a government, agrees to offer some of its private services only to those individuals who participate in paying for the public good. Often this is done implicitly: for example, some of the money from each purchase of an iPad goes toward research and development (some of which is a public good, and some of which is an excludable "club good"). At other times, it's more explicit, as in the case of taxation. In order for decentralized economic systems (we'll refer to decentralized economic systems that somehow rely on cryptography and/or cryptocurrency as "cryptoeconomic systems") to be effective, ways of incentivizing production of public goods relevant to that system are required. A few possible approaches include: - -* **Assurance contracts** - the idea behind an assurance contract is that `N` people may or may not put their funds into a pool, where that pool pays to produce a public good if and only if at least $X in total is contributed. Otherwise, the pool pays everyone back. If the pool creator acts optimally, the tipping point will be right at the top of the bell curve that is the probability distribution for how much other people might contribute, meaning that the chance that one user with their contribution of `X/N` will be pivotal should, by central limit theorem, approach `~1/sqrt(N)`, creating a `sqrt(N)`-sized amplifying effect on their donation. -* **Dominant assurance contracts** - a special type of assurance contract, called a dominant assurance contract, involves an entrepreneur that pays all contributors back slightly more than 100% of what they put in if the fund fails to reach its target (and takes profits if the fund succeeds); this provides an incentive for someone to create optimally targeted assurance contracts. -* **Currency issuance** - a cryptoeconomic system can contain its own currency or token system which is somehow necessary or useful in some part of the system. These currency units can then either be generated by the system and then sold or directly assigned to reward contribution. This approach gets around the free-rider problem because no one needs to pay the $1 explicitly; the value arises out of the emergent value of the network which is does not cost people to support. -* **Status goods issuance** - a status good can be defined as a good that confers only relative benefit to its holder and not absolute benefit to society; for example, you may stand out in the public if you wear an expensive diamond necklace, but if everyone could trivially obtain such a necklace the situation would be very similar to a world with no diamond necklaces at all. A cryptoeconomic system can release its own status goods, and then sell or award them. One example of a status good is a "badge"; some online forums, for example, show a special badge beside users that have contributed funds to support the forum's development and maintenance. Another important example of a status good is a namespace; for example, a decentralized messaging protocol may be able to fund itself by selling off all of the 1-4 letter usernames. -* **Recursive rewarding** - this is in some ways a mirror image of the concept of "recursive punishment" that arguably underlies a large number of social protocols. For example, consider the case of tax-funded police forces. In natural circumstances, there often arise opportunities to take actions which are beneficial to the perpetrator, but ultimately harmful to society as a whole (eg. theft). The most common solution to this problem is punishment - an act which is harmful in itself, but which shifts the incentives so that attacking is no longer beneficial to the perpetrator. However, there is a problem: there is no incentive to participate in the punishment process. This is solved by making punishment obligatory, with non-participation (in modern society by paying taxes) itself punishable by the same mechanism. Recursive rewarding is a mirror image of this strategy: here, we reward a desirable action, and people who partivipate in the rewarding mechanism (eg. by giving reward recipients a discount in shops) are themselves to be rewarded. - -Many of these approached can arguably be done in concert, or even simultaneously within one mechanism. - -**Problem**: come up with and implement methods for incentivizing public goods production in a decentralized environment. - -**Additional Assumptions And Requirements** - -* A fully trustworthy oracle exists for determining whether or not a certain public good task has been completed (in reality this is false, but this is the domain of another problem) -* The agents involved can be a combination of individual humans, teams of humans, AIs, simple software programs and decentralized cryptographic entities -* A certain degree of cultural filtering or conditioning may be required for the mechanism to work, but this should be as small as possible -* No reliance on trusted parties or centralized parties should be required. Where some kind of "supernode" role does exist, the protocol should provide a way for anyone to participate in that function with a mechanism for rewarding those who do it well -* The mechanism should ideally be able to handle both public goods which everyone values and public goods which are only valued by a small portion of the population (eg. the production of a freely available book or video on a specific topic) - -### 12. Reputation systems - -A concept which can arguably be considered to be a mirror image of currency is a reputation system. A reputation system serves three functions. First of all, it provides a mechanism for filtering honest people from dishonest people. Different people have different moral preference profiles, and so individuals who cheat less in one context are less likely to cheat in another context. Second, it provides an incentive not to cheat. If an individual can be said to possess a reputation of value `R`, and he enters a business deal where he is receiving payment `V` in exchange for a product with cost-of-production `C`, then as long as `R > C` the reputation system removes the incentive to run away with the money because doing so would sacrifice the reputation. Finally, reputation can be thought of as a kind of point system that people value intrinsically, both in a private context and as a status good in comparison with others. - -Money serves functions that are very similar. People who are willing to spend more money on something tend to want it more, creating a filtering function ensuring efficient resource consumption on the demand side. It provides an incentive not to cheat by consuming and not producing, because if you do so your remaining currency units and thus ability to consume in the future will go down. And finally, it is also very much an intrinsically valued point system; in fact, some argue that among very wealthy individuals this function of money is dominant. - -However, there are also differences. First, money is an absolute score - I have X units of currency C from the point of view of everyone in the world - but reputation is a relative measure, depending on both the owner of the reputation and the observer. I may have a high reputation in North America, a near-zero reputation in Africa, and a negative reputation among certain kinds of antitechnologist and ultranationalist groups. Second, reputation is free to give; it does not cost me anything to praise you, except potentially moral liability that I may incur if you turn out to act immorally in some way. This is in contrast with money, where adding X units to A means subtracting X units from B. - -However, up until very recently, reputation has been a very informal concept, having no concept of score and instead relying entirely on individual opinion. Because opinion is relatively easy to manipulate, this means that reputation as a concept has been highly suboptimal in its implementation, and has been quite vulnerable to informational and psychological attacks. Some specific problems are: - -1. How do we know how what the value of someone's reputation with someone else is after a particular number of interactions? A common attack on informal reputation systems is the "long con" - act honestly but passively and cheaply for a very long time, accumulate trust, and then suddenly go all out and destructively capitalize on one's reputation as much as possible. The initial dormant phase is cheap for the attacker, but ends up resulting in the attacker accumulating a disproportionately large amount of trust for the community and thereby ultimately causing much more damange than good. Overcompensate for this too much, however, and there ends up being no opportunity to gain trust. -2. How do we incorporate secondary trust? In general, when `A` is deciding whether or not to trust `B`, `A` has not had any prior dealings with `B`, and therefore has no way of knowing whether or not `B` is trustworthy. One approach is to just look at all ratings for `B`, but then we run into the issue of Sybil attacks: what if `B` creates 50000 fake users, all of whom rate each other highly, to give good ratings to him? To solve this problem, reputation systems rely on a fallback known as a web of trust: find some chain of people `P[1] ... P[k]` such that `A` trusts `P[1]`, `P[i]` trusts `P[i+1]` for all `i`, and `P[k]` trusts `B`. Under the "six degrees of separation hypothesis", any two people in the world except those completely disconnected from society have such a chain of maximum length `k = 5` (so at most six hops total). However, the question arises, if `A` has a certain rating for `P[1]` and `P[1]` has a certain rating for `B`, what should the reputation system recommend to `B`? -3. If a reputation system becomes more formalized, are there market attacks that reduce its effectiveness to simply being just another form of money? Specifically, how would a reputation system where giving reputation is free handle users multiplying their reputation with millions of "I praise you if you praise me" trades? Will such trades need to be explicitly banned, punishable by loss of reputation, or is there a better solution? -4. How do we deal with double use attacks? Specifically, suppose that `A` has a reputation with value `R = $1000`. Using this reputation, `A` has a business dealing where `P[1]` trusts her for $600. Then, she simultaneously engages in such a dealing with `P[2], P[3] ... P[10]`, each of whom individually believe that `A` will not betray them since $600 < $1000, and then runs away with $6000 taking the $1000 hit from the value of her reputation. How do we prevent such fractional reserve-like scenarios? - -**Problem**: design a formalized reputation system, including a score `rep(A,B) -> V` where `V` is the reputation of `B` from the point of view of `A`, a mechanism for determining the probability that one party can be trusted by another, and a mechanism for updating the reputation given a record of a particular open or finalized interaction. - -Note that for the purpose of this use case we are targeting specifically the "can I trust you" use case of reputation, and not the social-incentivizing "[whuffie](https://en.wikipedia.org/wiki/Whuffie)"-esque currency-like aspect. - -**Additional Assumptions and Requirements** - -* The system has access to a record of all finalized transactions inside the system and all transactions in progress, although entities are of course able to choose to make deals outside the system -* It is allowed to introduce mechanisms like charity donations, public goods provision and sacrifices as a way of increasing one's reputation. However, if non-monetary contributions are allowed, there needs to be some mechanism for measuring their value -* For simplicity, we can assume that interactions between two people are of the form "A pays, then B sends the product and A receives", with no possibility for loss beyond the principal (eg. food poisoning) or ambiguous quality. Ideally, however, the system should account for such possibilities. -* The system should continue to be reasonably accurate whether the parties involved are simple programs (eg. micropayment software protocols), more complicated AIs, DAOs, individual humans or human centralized or decentralized organizations -* If a mechanism is provided for determining the probability of a successful interaction, a success metric for the system can be defined as the sum over all transactions of `V * (S * log(p) - (1-S) * log(1-p))`, where `S = 1` if the transaction succeeded and `S = 0` if there was a registered complaint, `p` is the assigned probability and `V` is the value of the transaction. The objective is to maximize this metric. - -## Metrics - -In the world of cryptoeconomics, in order for something to be rewarded it must be measured. Some things are easy to measure; for example, just by looking at the string "dog5356356" and its SHA256 hash, `0000390f327fefc900...`, one can clearly see that around 216 SHA256 computations were done to produce it. Other computational results that cannot be verified so quickly can be easily measured competitively using challenge-response protocols, where different parties are incentivized to find errors in each other's proofs. Results to mathematical problems are also usually easy to computationally verify. Other things, however, cannot be verified just by looking them; in that case, in both the real world and the cryptographic world, there is only one solution: social proof. - -To some extent, proof of work consensus is itself a form of social proof. Transaction A happened before transaction B because the majority of users say it did, and there is an economic incentive to go with the majority opinion (specifically, if you generate a block on the incorrect chain, that block will get discarded and the miner will receive no reward). Assuming that most participants act truthfully, the incentive is to go along with the projected majority and tell the truth as well. This insight can be extended into [SchellingCoin](http://blog.ethereum.org/2014/03/28/schellingcoin-a-minimal-trust-universal-data-feed/), a generalized data feed protocol, protocols for proof of bandwidth, and anything else that can be quickly verified. The challenge is, however, what if verification has a cost? What if it takes some effort to determine whether or not a certain thing has happened, or what if the information is in principle only available to a few people? If there is too much gathering cost or secrecy, then centralization becomes necessary; the question is, how high can we go? How much can we measure without any social proof at all, and how much can we measure without a centralized verifier? - -### 13. Proof of excellence - -One interesting, and largely unexplored, solution to the problem of distribution specifically (there are reasons why it cannot be so easily used for mining) is using tasks that are socially useful but require original human-driven creative effort and talent. For example, one can come up with a "proof of proof" currency that rewards players for coming up with mathematical proofs of certain theorems. There is no generic algorithm, aside from brute force, for proving theorems, and yet proofs of theorems are theoretically computationally easy to verify: one simply needs to write every step of the proof in a formal language, allowing the use of only one inference rule (eg. `a + b = b + a` or `a * (b + c) = a * b + a * c` but not `a * (b + c) = a * c + b * a`) between each step, and having a program verify the correctness of the inferences at each step. - -For example, a proof of a common algebraic factorization problem appears as follows: - - a^2 - b^2 - = a^2 - a*b + a*b - b^2 - = a*a - a*b + a*b - b^2 - = a*(a - b) + a*b - b^2 - = a*(a - b) + a*b - b*b - = a*(a - b) + b*a - b*b - = a*(a - b) + b*(a - b) - = (a + b)*(a - b) - -Each step of the proof can be verified using pattern matching algorithms, but it is much harder for a computer to figure out that the trick is to add and subtract `a*b` into the expression (technically, in this case specialized algorithms can do it, but in more general cases especially involving second-order logic it becomes intractable). Note that for computers the proof must be written down in excruciating detail; blockchain-based algorithms specifically heavily benefit from simplicity. To alleviate this problem, compilers can likely be made that can make small two and three-step inferences and expand shorter proofs into more complete ones. - -Alternatives to proof-of-proof include proof-of-optimization, finding optimal inputs to some function to maximize a particular output (eg. the ability of a radio antenna to receive signals), algorithms involving playing strategy games or multiplayer AI challenges (one can even require users to submit programs to the blockchain that play against each other), and solving a specific math problem at greater and greater difficulty (eg. factoring). Note that because success in these problems is very sporadic, and highly inegalitarian, one cannot use most of these algorithms for consensus; rather, it makes sense to focus on distribution. - -**Problem**: create a proof-of-excellence distribution mechanism that rewards solving problems that are both dominated by human effort and whose solutions provide some benefit to humanity. - -**Additional Assumptions and Requirements** - -* Given a well-justified extrapolation of the global levels of human and computer competence at the underlying problem, over 75% of the rewards from the system should be provided by human labor, although software aids are allowed. -* The algorithm must ideally be future-proof; that is to say, it must continue rewarding value production in the long term and should not be an area that will eventually be "solved" completely. -* The distribution should be maximally egalitarian, though this is a secondary concern. -* The system should be secure against front-running attacks, ie. if an individual submits a solution, then it should not be practical for even a moderately powerful attacker to look at the solution and then resubmit his own transaction containing the same solution and thereby steal the reward. - -### 15. Anti-Sybil systems - -A problem that is somewhat related to the issue of a reputation system is the challenge of creating a "unique identity system" - a system for generating tokens that prove that an identity is not part of a Sybil attack. The naive form of anti-Sybil token is simple: a sacrifice or proof of deposit. In a sacrifice setup, such identities simply cost $X, and in a PoD system identities require a deposit of $Y in order to be active, where perhaps the deposit can be taken away or destroyed under certain circumstances. However, we would like to have a system that has nicer and more egalitarian features than "one-dollar-one-vote"; arguably, one-person-one-vote would be ideal. - -To date, we have seen two major strategies for trying to solve this problem. One potential solution is to come up with a proof-of-work algorithm which is dominated by human labor, and not computers. This is not as difficult as it may seem; although computers get more and more powerful every year, there are a number of problems that have remained out of computers' reach for decades, and it may even be possible to identify a class of problems that are the artificial-intelligence-theoretic equivalent of "NP-complete" - problems such that, if they can be solved, it with high probability implies that AI can essentially replicate human activity in its entirety, in which case we are essentially in a post-scarcity utopia and money and incentivization may not even be necessary. These problems may be non-interactive challenges like CAPTCHAs, although all existing CAPTCHAs are far from adequate for the task, or they may be interactive strategy games like Go. - -The second strategy is to use social proof, turning the muscle of decentralized information gathering toward a simple problem: are these two identities the same person? If they are not, then they receive two anti-Sybil tokens, and if they are they receive one token. In general, we can separately define two concepts of identity: voluntary identity and involuntary identity. A voluntary identity can be seen as a cluster of interactions which are in some fashion correlated with each other; for example, a cryptographic identity consists of the set of interactions signed by a particular public key. An involuntary identity is a cluster of interactions which are correlated with each other, but where the entity producing the interactions does not want the correlations to be visible. A simple unique identity system would rely on voluntary identities embedded in social networks, with the understanding that creating separate identities with reputations is an expensive task and so most people would not want to do it, but a more advanced system may try to detect involuntary slipups like writing style patterns or IP addresses. - -The question is, can we use these mechanisms, either separately or together, and perhaps in combination with cryptoeconomic protocols and sacrifices as a fallback in order to create an anti-Sybil system which is highly egalitarian? We will accept that any scheme can be cracked at some cost; however, what we want is for it to be much more efficient for individuals to obtain _one_ anti-Sybil token "the proper way" rather than purchasing one off the grey/black market. The challenge is to push the grey/black market cost as high as possible, as much as possible without making the first token difficult. - -**Problem** - create a mechanism for distributing anti-Sybil tokens - -**Additional Assumptions and Requirements**: - -* Everyone is part of a social network with similar characteristics to social networks now found in the real world, and social data can be provably provided to cryptoeconomic systems (eg. blockchains, Ethereum contracts) -* The cost of obtaining one anti-Sybil token for a human should be as low as possible -* The cost of obtaining multiple anti-Sybil tokens for a human should be as high as possible -* The cost of obtaining anti-Sybil tokens for an automated system should be as high as possible (this is a more important criterion than high cost for multi-obtainment for humans) -* The system should not create dependency on centralized parties (eg. government passport offices) that have the power to cheat the system - -### 14. Decentralized contribution metrics - -Incentivizing the production of public goods is, unfortunately, not the only problem that centralization solves. The other problem is determining, first, which public goods are worth producing in the first place and, second, determining to what extent a particular effort actually accomplished the production of the public good. This challenge deals with the latter issue. Although in the case of computational tasks it's easy to come up with a proof of solution, for non-computational tasks the situation is much more difficult. If a cryptoeconomic system wants to incentivize users to build better graphical user interfaces to its own system, how would it rate people's contributions? [Even more problematically](http://en.wikipedia.org/wiki/Underhanded_C_Contest), what about potentially quasi-adversarial tasks like incentivizing updates to its own code? What about a DAO that funds healthcare, or tries to incentivize adopting renewable energy? - -This is a subclass of the general "social proof" problem; here, the particular challenge is that each individual datum in question is something that very few people are interested in, and data gathering costs are often high. Sometimes, there is not even a concept of a single "correct" value with respect to the particular metric; in the case of quality measurement for an interface, a solution like A/B testing may be required. In adversarial cases, there may need to be an opportunity for incentivized opponents to look at a solution and attempt to pick it apart. - -**Problem**: come up with and implement a decentralized method for determining whether or not a particular task was performed by a specific person, and for estimating the quality of the work - -**Additional Assumptions and Requirements** - -* The agents involved can be a combination of individual humans, teams of humans, AIs, simple software programs and other DAOs -* There is no cryptographically verifiable information about the completion of any task; the system must rely entirely on some form of social proof - -### 16. Decentralized success metrics - -Another, related, problem to the problem of decentralized contribution metrics is the problem of decentralized success metrics. On the macroscopic scale, how do we know if, and to what extent, an organization has succeeded in accomplishing its objectives? In the case of something like Bitcoin, there is a simple, but imperfect, answer: success can be measured by the hashpower of the network. This setup is reasonably effective, but is flawed in two ways: first, hashpower is an imperfect proxy for price, because the development or nondevelopment of ASICs may skew the results, and second, price is an imperfect proxy for success, because the currency may have greater success as something with a lower market capitalization if it is more used in other ways. In the case of a DAO funding healthcare or anti-climate-change efforts, however, no such heuristic exists at all. Once again, some concept of social proof is the only option. - -Here, information gathering costs are low, and information is accessible to everyone in the public, so a higher level of accuracy is possible, hopefully even enough for financial contracts based off of the metric to be possible. However, in order to maintain that higher level of accuracy, and in the presence of such financial derivatives, new problems arise. Can one moderately powerful entity manipulate the metric for their own benefit? If information gathering costs do exist, is the system vulnerable to falling into a centralized equilibrium, where everyone is incentivized to simply follow along with the actions of some specific party? - -**Problem**: come up with and implement a decentralized method for measuring numerical real-world variables - -**Additional Assumptions and Requirements** - -* The agents involved can be a combination of individual humans, teams of humans, AIs, simple software programs and other DAOs -* The system should be able to measure anything that humans can currently reach a rough consensus on (eg. price of an asset, temperature, global CO2 concentration \ No newline at end of file diff --git a/pages/other-languages/[Japanese]-Ethereum-Development-Tutorial.md b/pages/other-languages/[Japanese]-Ethereum-Development-Tutorial.md deleted file mode 100644 index 3d0c3f5c7..000000000 --- a/pages/other-languages/[Japanese]-Ethereum-Development-Tutorial.md +++ /dev/null @@ -1,249 +0,0 @@ ---- -name: Ethereum Development Tutorial -category: ---- - - このページの目的はコントラクトや分散アプリケーションを作成するために、開発の観点から理解する必要があるEthereumの基礎を紹介することです。Ethereumの全般的なイントロダクションについてはホワイトペーパー、完全な技術仕様についてはイエローペーパーが参考になりますが、このページを読むのに必須ではありません。アプリケーション開発者にとって、このページがそれらに代わるEthereumへの導入となり得ます。 - -### Introduction - - Ethereumは、ブロックチェーンを利用した分散型アプリケーション(DApps)を簡単にプログラムすることを目的としたプラットフォームです。DAppsとは、ユーザーに対し特定の目的のためを果たすアプリケーションですが、アプリケーション自体は既存の特定の管理者に依存しないという重要な特性を持っています。DAppsは、特定の管理者のサービスを提供するためのフロントエンドとして機能するのではなく、仲介業者なしで人や組織がやり取りするのためのツールです。 - - このDAppsというものは、特定のプラットフォームを提供し売り込むための開発環境というよりかはむしろ、(売り手と買い手などといった)違った立場にいる人間や機関が、中央集約型の媒介を無しにして取引、契約等(相互利用)をするための道具である。フィルタリングや第三者認証、紛争解決、個人認証業務のような典型的な「中央集約型の媒介」の業務でさえ、分散型ネットワークで扱うことが可能であり、参加者全員にオープンとなっており、内部トークンシステムとして評判の高いシステムをツールとして採用し、利用者に高品質なサービスを提供する。初期のDAppsの例としては、ファイルシェアアプリとしてBitTorrentが、通貨アプリとしてビットコインが含まれる。Ethereumは BittorentやBitcoinで使われたものや、P2Pネットワークやブロックチェーン技術を含む最初の進化版開発物(web3.0)といえよう。そして、開発者がこれらの技術を使いやすいように一般化したものだ。 - - Ethereumのブロックチェーンは(ビットコインに見られる単なる金銭記録データではなく)プログラミング言語が組み込まれたブロックチェーンというふうに説明できる。あるいは、大衆の思惑による決定(コンセンサス)を基板とした地球規模の仮想マシンとも言える。Ethereum仮想マシン(EVM)を参照してえられる部分的なプロトコルは、内部状態と計算を実際に処理する。実用的な観点からして、EVMは膨大な量のアカウント(というオブジェクト)を内部に保持する分散型コンピュータと考えることができ、このコンピュータでは各々のオブジェクトがそれぞれ内部コードとストレージという名前の32バイトのkey/valueデータベースを保持し、オブジェクトは他のオブジェクトを意のままに呼び出すことができる。 - 〜アカウントには2つのタイプがある〜 - オブジェクトの外側の世界からEVMを使用してアクセスすることができるアカウント(オブジェクト)として「外部所有アカウント(EOA,EOアカウント)」という名の特別なタイプがある。あるEOアカウントから他のどんなアカウントに対する「メッセージ」も、そのEOアカウントの秘密鍵で署名されたトランザクションを送ることが引き金となり、送ることが可能だ。EOアカウントでないものは「 契約、contract 」と呼ばれ、「メッセージ」の受け取り、自動的に内部コードを実行し、(自身のもつ内部ストレージに読み書きする能力を持つ。)受け取った「メッセージ」のストレージを読み取り、そして他の契約アカウントにメッセージを送る。(自分自身にも送ることができる。) ひとつの捉え方として、contract とは、契約を遂行するためのプログラミングコードだ。 - - contract はふつう、4つの目的 に分類できる。 - -1. データを維持する。 -他の契約アカウントや外の世界のアカウントにとって役立つ何かを表すデータ貯蔵を維持する。一例として、通貨をシミュレートした「 contract 」がある。他の例としては、ある特定の機関の構成員を記録する「 contract 」がある。 - -2. 「 EOアカウント 」に保持される。 -「 contract 」よりも複雑なアクセス制御がなされる「 EOアカウント 」に保持される。このコントラクトは「 先渡契約 forwarding contract 」と呼ばれる。これの典型的なものとして、「ある条件が整えば受信した「メッセージ」を送りたい場所へただ単に転送する」というものがある。例として「3つある秘密鍵のうち2つが、ある今送りたいメッセージが確約(コンファーム)するのを待ってから、メッセージを転送する」といった先渡契約をもつものが考えられる(「 multisig 」)。より複雑な先渡契約は送られたメッセージの形態に基づいて違った状態を取るというもので、この機能の最もシンプルな例として、より複雑なアクセス手順によって上書きされうる「引き出し制限」がある。(つまり複雑な手順の親クラス・あるいはインターフェースとしてEOアカウントに保持される) - -3. ユーザー間の契約内容や関係性を管理する。 - 金融契約における「第3者認証」が例としてわかりやすい。 - -4. ライブラリとして機能する。 - 他の契約によって呼び出される関数を格納しておく。 - - contract は、互いに「 呼出(calling)」や「 送信(sending message)」などと呼ばれる動作を通じて作用しあう。一通の「メッセージ」は、1.ある量のether 2.どんなサイズのデータを格納したバイト型配列 3.送受信者双方のアドレス を保持する。契約アカウントが、返り値としてあるデータを返す「メッセージ」を受信し、その返り値をメッセージの送り手がすぐに使用できるようなときは、「送信」とは、まさに、プログラミングにおける関数の履行である。 - - 以上に示したように、契約アカウントは異なる働きをし、それら同士が互いに作用しあうことが期待できる。例をあげよう。次のような状況を考えてみよう。 - アリスとボブが、「来年サンフランシスコの気温が35度を超えることはない」ということに100Gavcoin(開発者の名前が付けられた仮想通貨)の賭けをしたとしよう。しかし、アリスは危険回避思考の持ち主で、アリスの第一アカウントは、マルチシグをかけた「前進型契約」を保持している。ボブは量子暗号に猜疑的で(疑い深く)、伝統的な楕円曲線アルゴリズムに沿ったランポート署名を施したメッセージを転送する「前進型契約」を保持している(訳略)。この賭博を管理する契約アカウントはそれ自身サンフランシスコの気象データをあるコントラクトから呼び出してこないといけない。(以後、契約アカウントの呼び名として、プログラマであるわれわれがmethodのことをメソッドと呼ぶように、コントラクトと呼ぶことにする。コンストラクタ等と混同しないように別名がほしいところだが。)またGavCoinコントラクトともやりとりしなくてはならない。・・・ - 以下に図を示す。 - -![img](https://github.com/ethereumbuilders/GitBook/blob/master/en/vitalik-diagrams/contract_relationship.png) - - スタック上に積み上がっていくメソッドの呼び出し(コールスタック)を頭に思い描くことができれば、 -ここでの説明は容易であろう。 - -ボブが賭けを終了させたいと思った時、次のことが起こる: - -1. トランザクションが送信され、それが有効になると、ボブの EOA からボブの「 forwading contract 」へ message が送信される -2. ボブの「 forwading contract 」は message を受け取り、hash と ランポート署名 を「 ランポート署名検証 Library contract 」へ送信する -3. 「 ランポート署名検証 Library contract 」はボブがSHA256のランポート署名が欲しいことをみて、 SHA256 のライブラリを検証に必要な回数にわたって呼び続ける。 -4. 「 ランポート署名検証 Library contract 」が 1 を返すと、署名が有効であると署名し、message を「 bet contract 」に送信する -5. 「 bet contract 」は 「 サンフランシスコの気温を提供する Library contract 」 に値を要求する -6. 「 bet contract 」は返事をみて、値が 35 度以上であることを確認する。そこで「 Gavcoin contract 」に、Gavcoin を その account から ボブの「 forwarding contract 」に移動するよう message を送信する。 - -GavCoin はすべて Gavcion contract データベースの項目として "貯蔵" されていることに注意して欲しい。 -ステップ 6 の内容にある単語 "account" が意味するところは単に Gavcoin cocntract の中に、bet contract の address のための key と 残高 とともに、データ項目 があるということだ。 -この message を受信したあと、Gavcoin contract は自身の残高からある量の値を減らし、同じ分だけボブの forwarding contract への送信項目の値を増やす。以下のdiagramにこれらのステップを示した: - -![img](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/contract_relationship2.png?1) - -### State Machine - - Ethereum仮想マシンの計算処理は、ビットコインスクリプトと伝統的アセンブラやLispといったものの架け橋である、スタックベースのバイトコード言語を使用する。(Lispは再帰的コントラクト呼出の機能の役割を担う。)仮想マシン上のプログラムは以下のようなopcodesのシーケンスである。 - - PUSH1 0 CALLDATALOAD SLOAD NOT PUSH1 9 JUMPI STOP PUSH1 32 CALLDATALOAD PUSH1 0 CALLDATALOAD SSTORE - - この例が示すコントラクトの目的は、レジストリという名前をもつ contract として振る舞うことにある。誰でも64バイトのデータを含む「メッセージ」送付することができる。 32バイトは鍵keyに 32バイトは値valueにわり振られる。このレジストリcontractは、鍵がすでにストレージ内に登録されているかをチェックし、もし登録されていなければ、その鍵と共に値を登録する。 - - 実行中は、「メモリ」と呼ばれる無限拡張可能なバイト型配列、現在の指令の位置を指し示す「program counter」、および32バイトの値を格納したスタックが維持されている。実行の開始時、メモリとスタックは空で、PCは0である。さて、それでは、一番最初にアクセスされるこのコードと、123weiと、(値54,鍵2020202020) の64バイトのデータともに、contract についてみていこう。 - - -初期状態は: - - PC: 0 STACK: [] MEM: [], STORAGE: {} - -最初の命令は`PUSH1`で次の値である0をスタックにpushする。`PUSH1`は1バイトの値を扱う。よって以下のような状態に変わる: - - PC: 2 STACK: [0] MEM: [], STORAGE: {} - -2番目の命令である`CALLDATALOAD`では、スタックから値を一つ取り出し、そのアドレス先のデータの先頭32バイトのメッセージを取得し、その値をスタックに保存する(ここでは先頭の32ビットが54である)。よって以下のような状態に変わる: - - PC: 3 STACK: [54] MEM: [], STORAGE: {} - -次の命令の`SLOAD`はスタックから値を一つ取り出し、contractのstorageの参照先の値をスタックに保存する。今回初めてcontractは使用するため値が入っておらず、値は0が埋められる: - - PC: 4 STACK: [0] MEM: [], STORAGE: {} - -`NOT`スタックから値を取り出し、0であれば1を、それ以外は0をスタックに入れる: - - PC: 5 STACK: [1] MEM: [], STORAGE: {} - -次は`PUSH1`であるため、9をスタックに保存する: - - PC: 7 STACK: [1, 9] MEM: [], STORAGE: {} - -次の`JUMPI`命令では、スタックから2つの値を取り出し、二つ目の値が0でなければ、一つ目の値によって指定された命令へジャンプする。ここでは0でないのでジャンプする。もしストレージ内の54番目の値が0でなかったならば、スタックの二つ目の値が0になっているだろう。よって、この場合ジャンプできずに動作がここで終了する: - -次は`PUSH1`であるため、32をスタックに保存する. - - PC: 11 STACK: [32] MEM: [], STORAGE: {} - -次は再び`CALLDATALOAD`である。 スタックの32バイト目から63バイトまで値を取得しスタックに保存する: - - PC: 13 STACK: [2020202020] MEM: [], STORAGE: {} - -次は`PUSH1`で0をスタックに保存する: - - PC: 14 STACK: [2020202020, 0] MEM: [], STORAGE: {} - -そして再び0-31バイト目のデータを取得してスタックに保存する (なぜメモリに保存させて再利用しないかって?それはメモリからロードをする方が安上がりだからさ): - - PC: 16 STACK: [2020202020, 54] MEM: [], STORAGE: {} - -最後は`SSTORE`で、スタックから取り出した1番目の値を、ストレージ内の参照値とした場所へ、二つ目の値を格納する。よって以下の通りになる: - - PC: 17 STACK: [] MEM: [], STORAGE: {54: 2020202020} - - 17番目の指令は何も書かれていないので、ここでストップとなり、もし、スタックやメモリ上に何か残っていれば、消えてしまう。しかし、ストレージ内のデータは次回誰かが呼び出すときまで保存される。これと同じようにして、同じ送信者が同じメッセージを再び呼び出したとすると(あるいは別の誰かが、54番目に3030303030を登録しようと試みたとすると)これは、8番目の指令のところで動作が終了する。 - - 幸運なことに、低級アセンブラを君が扱う必要はない。 -LLLやSerpent、Mutanなどと言った数々の高級言語が存在し、コントラクトをもっと簡単に記述してくれる。これらの言語で書かれたどんな言語もEthereum仮想マシンにコンパイルされ、あなたがEVMバイトコードを含むトランザクション上で呼び出すコントラクトを作成する。 - - トランザクションには二つのタイプがある。 -「Ether送信トランザクション」と「コントラクト生成トランザクション」だ。 -Ether送信トランザクションとは標準的なトランザクションのことで、受信用アドレス、etherの額、バイト型配列のデータと他のパラメータを含み、秘密鍵による署名は送信者のアカウントに関連づけられている。「コントラクト生成トランザクション」は、受信用アドレスが空である点を除いて標準的なトランザクションと似ている。コントラクト生成トランザクションがブロックチェーンに自身を組み込むとき、トランザクションのバイト型配列のデータはEVMコードとして解釈され、EVMの実行による返り値が新しいコントラクトのコードとなる。このように、初期化の間中、ひとつのトランザクションにあることをやってもらうことができる。新しいコントラクトのアドレスは送信アドレスとそのアカウントが以前トランザクションを作成した回数に基づいて決定論的に計算される。(nonceと呼ばれるこの値もまた別のセキュリティの観点から保存される。)このように、上記のnameレジストリを生成するためにブロックチェーン上に載せる必要があるフルコードは以下のとおり: - - PUSH1 16 DUP PUSH1 12 PUSH1 0 CODECOPY PUSH1 0 RETURN STOP PUSH1 0 CALLDATALOAD SLOAD NOT PUSH1 9 JUMPI STOP PUSH1 32 CALLDATALOAD PUSH1 0 CALLDATALOAD SSTORE - - このopcodesを読み解く上での鍵はCODECOPYだ。今スタック上には[16,12,0]の順に積まれていて、コード配列の要素12(13番目)からスタートして、16バイト分をコピーしたものをメモリの0番地を起点としたところに貼り付け、今貼り付けられたメモリ上の0番目から16番目の値を返す。 -結果として、12(含まず)〜28番目のコードがこの一つのコードにより実行される。 - -### Gas - - 仮想マシンを動かす上で重要な側面がある。それは「仮想マシン内部で処理されるあらゆる単一操作は、実際はすべてのノード上で同時に実行される」ということだ。Ethereum1.0の必要なコンポーネントであり、「仮想マシン上のどんなコントラクトもほぼコスト0で他のあらゆるコントラクトを呼び出すことができる」といった恩恵をもたしてくれる。しかしながら、Ethereum仮想マシン上での計算処理のステップはとても高価なもとなる。Ethereum仮想マシンの使用方法の概要は、「1999年代以降のスマホでできないことは、ここでもできない。」とでもとらえておけばだいたい正しい。 -ビジネスロジックを走らせたり、署名やその他の暗号オブジェクトの有効化をしているEVMの正しい使用法として;EVMの使用法の上限としてあるのが、他のブロックチェーンの部分集合を有効化するアプリケーションだ。(例:分散型ether - bitcoin 両替所) 受け入れがたい使い道としては、ファイルストレージやEmailテキスト、メールシステム、画像処理インターフェースを用いて行うプログラムや遺伝的アルゴリズムや機械学習、グラフ探索などのcloud computingにベストマッチするアプリケーションなどだ。 - - 故意による攻撃や破壊を予防するため、Ethereumプロトコルは、一計算ステップあたりの使用料を徴収する。料金は市場に基づくものの、いざ動かしてみると強制力をともわすような設計がなされている。;ブロックひとつあたりに蓄えられるオペレーション数の流動的上限があることによって、ほぼコストなしでトランザクションをインクルードすることのできる(ブロックを生成することのできる)マイナー(採掘者)でさえネットワーク全体へのトランザクションのコストと同額の使用料が課せられる。手数料とブロックのオペレーション上限のシステムの経済基礎知識についての詳細は、Ethereum白書の「fee」の項目を参照。 - - 手数料が実際にどう動くかをいかに述べる。あらゆるトランザクションは、他のデータとともに、ガス価格とガス開始値を含む。ガス開始値とはガスの量であり、トランザクション自身がそれを確約する。ガス価格とはトランザクションが支払うことになる単位ガス料金だ。;このようにして、トランサクションが送られると、ガスがあるとき最初に行われるのが、送信者のアカウントのバランスから、トランザクションの値と、(ガス価格☓ガス開始値)[wei]を足したものを差し引く。ガス価格は送信者によりセットされるが、低すぎるガス価格のトランザクションの処理は、採掘者が拒否をする可能性が高いだろう。 - - ガスはざっくりといえば、計算ステップのカウンターとして考えることができ、トランザクションの実行中存在するもので、実行が終われば消えてなくなる。トランザクションの実行が始まった時、今あるガスは(ガス開始値 - 500 - 5 ☓ トランザクションデータ長※)としてセットされる。全計算ステップにおいて、あるガス量(ふつう1で、時々オペレーションに依存して値が大きくなる)が全体から差し引かれていく。もしガスが0に達すれば、すべての実行は元に戻るがトランザクションは有効で送信者はガスの料金を支払わなければならない。もし、トランザクションの実行が無事終了し、Nだけガスがのこっていたら、N×ガス価格が払い戻されるというわけだ。 - - - -ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー - -※ トランザクションデータ長 トランザクションのデータにあるバイトの数のこと。 - - コントラクトによるコントラクト呼び出しという場合にも同様のことが起こる。 -(つまりトランザクションと送信作業、コントラクト呼び出しは同義で、それが人の手書きによるものなのか、コントラクトによる自動実行なのかという違いに尽きる。) - コントラクト呼び出しの際、途中でガスが尽きると、処理は元に戻るだけで、処理が遂行すれば返り値を返し、このどちらかの状態しかありえないので、完全に安全に呼び出し処理ができるのである。 -サブのコントラクトが余力を残していれば、親の実行まで戻る。 - -### Virtual machine opcodes - -The opcodes in the EVM are as follows: - -* `0x00`: `STOP`, stops execution -* `0x01`: `ADD`, pops 2 values `a`, `b` from the top of the stack and pushes `a+b` to the top of the stack (all arithmetic is modulo 2256) -* `0x02`: `MUL`, pops 2 values `a`, `b`, pushes `a*b` -* `0x03`: `SUB`, pops 2 values `a`, `b`, pushes `a-b` (`a` is the value immediately at the top of the stack before execution, `b` is second from top) -* `0x04`: `DIV`, pops 2 values `a`, `b`, pushes `a/b` if `b != 0` else 0 -* `0x05`: `SDIV`, pops 2 values `a`, `b`, pushes `a/b` if `b != 0` else 0, except where `a` and `b` are treated as signed integers, ie. if `a >= 2^255` then it's treated as the negative value `a - 2^256`. Division with negative numbers is done as in Python, ie. `25 / 3 = 8`, `25 / -3 = -9`, `-25 / 3 = -9`, `-25 / -3 = 8` -* `0x06`: `MOD`, pops 2 values `a`, `b`, pushes `a%b` if `b != 0` else 0 -* `0x07`: `SMOD`, pops 2 values `a`, `b`, pushes `a%b` if `b != 0` else 0, treating `a`, `b` as signed values. Modulo with negative numbers is done as in Python, ie. `25 % 3 = 1`, `25 % -3 = -2`, `-25 % 3 = 2`, `-25 % -3 = -1` -* `0x08`: `EXP`, pops 2 values `a`, `b`, pushes `a^b` -* `0x09`: `NEG`, pops 1 value `a`, pushes `-a` (ie. `2^256 - a`) -* `0x0a`: `LT`, pops 2 values `a`, `b`, pushes 1 if `a < b` else 0 -* `0x0b`: `GT`, pops 2 values `a`, `b`, pushes 1 if `a > b` else 0 -* `0x0c`: `SLT`, pops 2 values `a`, `b`, pushes 1 if `a < b` else 0, doing a signed comparison -* `0x0d`: `SGT`, pops 2 values `a`, `b`, pushes 1 if `a > b` else 0, doing a signed comparison -* `0x0e`: `EQ`, pops 2 values `a`, `b`, pushes 1 if `a == b` else 0 -* `0x0f`: `NOT`, pops 1 value `a`, pushes 1 if `a = 0` else 0 -* `0x10`: `AND`, pops 2 values `a`, `b`, pushes the bitwise and of `a` and `b` -* `0x11`: `OR`, pops 2 values `a`, `b`, pushes the bitwise or of `a` and `b` -* `0x12`: `XOR`, pops 2 values `a`, `b`, pushes the bitwise xor of `a` and `b` -* `0x13`: `BYTE`, pops 2 values `a`, `b`, pushes the `a`th byte of `b` (zero if `a >= 32`) -* `0x20`: `SHA3`, pops 2 values `a`, `b`, pushes `SHA3(memory[a: a+b])` -* `0x30`: `ADDRESS`, pushes the contract address -* `0x31`: `BALANCE`, pushes the contract balance -* `0x32`: `ORIGIN`, pushes the original sending account of the transaction that led to the current message (ie. the account that pays for the gas) -* `0x33`: `CALLER`, pushes the sender of the current message -* `0x34`: `CALLVALUE`, pushes the ether value sent with the current message -* `0x35`: `CALLDATALOAD`, pops 1 value `a`, pushes `msgdata[a: a + 32]` where `msgdata` is the message data. All out-of-bounds bytes are assumed to be zero -* `0x36`: `CALLDATASIZE`, pushes `len(msgdata)` -* `0x37`: `CALLDATACOPY`, pops 3 values `a`, `b`, `c`, copies `msgdata[b: b+c]` to `memory[a: a+c]` -* `0x38`: `CODESIZE`, pushes `len(code)` where `code` is the contract's code -* `0x39`: `CODECOPY`, pops 3 values `a`, `b`, `c`, copies `code[b: b+c]` to `memory[a: a+c]` -* `0x3a`: `GASPRICE`, pushes the `GASPRICE` of the current transaction -* `0x40`: `PREVHASH`, pushes the hash of the previous block -* `0x41`: `COINBASE`, pushes the coinbase (ie. miner's address) of the current block -* `0x42`: `TIMESTAMP`, pushes the timestamp of the current block -* `0x43`: `NUMBER`, pushes the number of the current block -* `0x44`: `DIFFICULTY`, pushes the difficulty of the current block -* `0x45`: `GASLIMIT`, pushes the gas limit of the current block -* `0x50`: `POP`, pops one value from the stack -* `0x51`: `DUP`, pops one value `a` from the stack and pushes `a` twice -* `0x52`: `SWAP`, pops two values `a` and `b` and pushes them in reverse order -* `0x53`: `MLOAD`, pops one value `a` and pushes `memory[a: a + 32]` -* `0x54`: `MSTORE`, pops two values `a`, `b` and sets `memory[a: a + 32] = b` -* `0x55`: `MSTORE8`, pops two values `a`, `b` and sets `memory[a] = b % 256` -* `0x56`: `SLOAD`, pops one value `a` and pushes `storage[a]` -* `0x57`: `SSTORE`, pops two values `a`, `b` and sets `storage[a] = b` -* `0x58`: `JUMP`, pops one values `a`, and sets `PC = a` where `PC` is the program counter -* `0x59`: `JUMPI`, pops two values `a`, `b` and sets `PC = a` if `b != 0` -* `0x5a`: `PC`, pushes the program counter -* `0x5b`: `MSIZE`, pushes `len(memory)` -* `0x5c`: `GAS`, pushes the amount of gas remaining (before executing this operation) -* `0x60` - `0x7f`: `PUSH1` - `PUSH32`, `PUSH_k` pushes a value corresponding to the next `k` bytes in the code, and sets `PC += k + 1` (ie. to the byte immediately after the `k` bytes pushed) -* `0xf0`: `CREATE`, pops three values `a`, `b`, `c`, creates a new contract with initialization code `memory[b: b+c]` and endowment (ie. initial ether sent) `a`, and pushes the value of the contract -* `0xf1`: `CALL`, pops seven values `a`, `b`, `c`, `d`, `e`, `f`, `g`, and sends a message to address `b` with `a` gas and `c` ether and data `memory[d: d+e]`. Output is saved to `memory[f: f+g]`, right-padding with zero bytes if the output length is less than `g` bytes. If execution did not run out of gas pushes 1, otherwise pushes 0. -* `0xf2`: `RETURN`, pops two values `a`, `b`, and stops execution, returning `memory[a: a + b]` -* `0xff`: `SUICIDE`, pops one value `a`, sends all remaining ether to that address, returns and flags the contract for deletion as soon as transaction execution ends - -Note that high-level languages will often have their own wrappers for these opcodes, sometimes with very different interfaces. - -### Ethereum ブロックチェーンの基本 - - Ethereum・ブロックチェーン(あるいは「帳簿」)は分散型で(中央集約型ではなく)、全アカウントのカレントステイト(現在の状態)を保持し、大規模に複製されたデータベースである。このブロックチェーンは全アカウントの状態を貯蔵するのに、[「パトリシア木」](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree) というデータ構造を採用している。この「パトリシア木」は本質的に、一般的なKey/value貯蔵時にふるまう「マークル木」の特殊型である。標準のマークル木のように、パトリシア木はルートハッシュを保持している。ルートハッシュは、木構造全体を参照するために使用可能で、木のコンテンツはルートハッシュの変更なしに修正不可能である。それぞれのアカウントのために、木は、[ account_nonce, ether_balance, code_hash, storage_root ] をふくんだ、4つの構成要素からなるタップル(4-tuple)を貯蔵している。ここで、このタップルの要素の定義は以下の通りである。 - -* account_nonce:アカウントから送られたトランザクション数 -* ether_balance :アカウントの残金 -* code_hash  :アカウントの種類がコントラクト->コードのハッシュ値 -        アカウントの種類がEOアカウント->"" -* storage_root  :アカウントの保持するストレージ内を格納した -        新たなパトリシア木データ構造のルート - -![img](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/chaindiag.png) - - 毎分、マイナーは新しいブロックを生成し、(Ethereumのマイニングの概念はビットコインにおける概念と全く同じである。より情報が必要ならばそこらのビットコインのチュートリアルを見るとよい。)新しいブロックは、「一番最近生成されたブロック以降に生成され、かつパトリシア木が、これらのトランザクションを一つのブロックとして適用しマイナーに報酬を与えたのち、そのルートのハッシュ値を新しい状態(状態木)にしてから、新たに生成されたトランザクションのリスト」を含んでいる。 - - パトリシア木の仕組みのおかげで、もし少ししかない変更がなされれば、木の大部分は変更前の最後の状態と全く同じになるだろう。このように、新しいパトリシア木のノードが単に、古いパトリシア木と新しいパトリシア木が全く同じである空間における古い方のノードを貯蔵する同じメモリアドレスを指し戻すことができるだろうような場合には、同じデータを二度蓄える必要はない。N番目のブロックとN+1番目のブロックの間に(N+1番目のブロックに取り込まれるべき)、千箇所の変更があったとして、たとえ全パトリシア木のデータサイズが何ギガバイトに及ぼうとも、N+1番目のブロックに貯蔵されるのに必要な新しいデータ量はたかだか数百キロバイトであり、基本的にもっと少ない(同じコントラクト内で変化が生じたときは特に)。全てのブロックは、ブロック数、タイムスタンプ、マイナーのアドレス、ガスの上限のような他のデータと同様にして、一つ前のブロックのハッシュ値を含んでいる。 - -### Graphical Interfaces - - コントラクトはそれ自身とてもパワフルなものだが、Dアプリを完全にするものとは言えない。Dアプリはむしろ、コントラクトとそのコントラクトを使用するグラフィカルインターフェースの融合によるものである。(これは、現バージョンのEthereumのことを述べており、Ethereumの未来バージョンでは、whisperといった、Dアプリ内のノードに対して、ブロックチェーンなしで互いにp2pメッセージを送らせることのできるプロトコルを含むだろう。)いまちょうど、そのインターフェイスは、HTML/CSS/JSのウェブページとして実装され、特別な javascript API がEthereumブロックチェーンと一緒に動作する eth オブジェクト形式の中にある。javascript APIのキーとなる部分は以下の通りである。 - -* `eth.transact(from, ethervalue, to, data, gaslimit, gasprice)` - sends a transaction to the desired address from the desired address (note: `from` must be a private key and `to` must be an address in hex form) with the desired parameters -* `(string).pad(n)` - converts a number, encoded as a string, to binary form `n` bytes long -* `eth.gasPrice` - returns the current gas price -* `eth.secretToAddress(key)` - converts a private key into an address -* `eth.storageAt(acct, index)` - returns the desired account's storage entry at the desired index -* `eth.key` - the user's private key -* `eth.watch(acct, index, f)` - calls `f` when the given storage entry of the given account changes - - ethオブジェクトを利用するのに、特別なソースファイルやライブラリは全く要らない。 -しかしながら、そうして作られたDアプリはEthereumクライアントの中で開いたときのみ動作するようになり、一般的なwebブラウザ上では動かない。Javascript APIの実践的使用例として[the source code of this webpage](http://gavwood.com/gavcoin.html)を訪れるとよい。 -. - -### Fine Points To Keep Track Of - -See [https://github.com/ethereum/wiki/wiki/Subtleties](https://github.com/ethereum/wiki/wiki/Subtleties) diff --git a/pages/other-languages/[Japanese]-Ethereum-TOC.md b/pages/other-languages/[Japanese]-Ethereum-TOC.md deleted file mode 100644 index 1d6f401bd..000000000 --- a/pages/other-languages/[Japanese]-Ethereum-TOC.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -name: Ethereum TOC -category: ---- - -###Ethereum 次世代スマートコントラクトとディセントラルアプリケーションレイヤー へようこそ。 - -[Ethereum White Paper](https://github.com/ethereum/wiki/wiki/White-Paper) ( 英語版 ) -[Ethereum 白書](https://github.com/ethereum/wiki/wiki/%5BJapanese%5D-White-Paper) ( 要改訳 ) - - - -[RLP](https://github.com/ethereum/wiki/wiki/%5BJapanese%5D-RLP), Ethereumのデータエンコードに使用される再帰的リニアプレフィックス仕様 - -[パトリシアツリー](https://github.com/ethereum/wiki/wiki/%5BJapanese%5D-Patricia-Tree) 別名Trieとしても知られるマークルパトリシアツリー仕様 Ethereumにおいてブロックチェインのステートのハッシュを記憶するために使用される構造 - -[ワイヤプロトコル](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Wire-Protocol) 仕様 - -[Serpent](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Serpent-programming-language-operations), コントラクトを書くための高水準言語. チュートリアルは [こちら](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Serpent-programming-language-operations). - -[LLL](https://github.com/ethereum/cpp-ethereum/wiki/LLL), Lispに似た低水準言語 "Lisp-like Language" の仕様, PoC-3以降のPoCシリーズでコントラクトを書くために使用される。 - -[用語集](https://github.com/ethereum/wiki/wiki/Glossary) - -[暗号通貨における困難な問題 (取組中)](https://github.com/ethereum/wiki/wiki/Problems) \ No newline at end of file diff --git a/pages/other-languages/[Japanese]-HPOC_2015.md b/pages/other-languages/[Japanese]-HPOC_2015.md deleted file mode 100644 index 8e57f07b6..000000000 --- a/pages/other-languages/[Japanese]-HPOC_2015.md +++ /dev/null @@ -1,201 +0,0 @@ ---- -name: HPOC 2015 -category: ---- - -HPoC 2015 - -昨年私達は、暗号通貨とCryptoeconomic のテクノロジーが主流のものとなるのを妨げています。 -幾つかの技術的、経済的な難しい問題を叙述し、"Hard Problems of Cryptocurrency"の文書を出しました。 - -そのリストには、幾つもの他の困難とともに例えばスケーラビリティや、より効率的なコンセンサスのアルゴリズム、公益となるインセンティブの仕組みを叙述しました。 - -昨年に渡って多くの問題が解決されました、少なくとも追加された更新はもはや、0から1への解決が必要な根本的な問題ではなくなり、 -むしろ現実世界への確かな実装の問題となりました。 -そして、同時に、かなりの数の試練が未だに残っている。それにもかかわらずここにある問題はかなり限定的で、 -過去のものよりも広域に渡るものではありません。 - -メタコンセンサス(コンセンサスのためのコンセンサス) - -技術的な視野が急速に広がることに関連し続けるために、ソフトウェアは更新されなければならず、 -更新しないソフトウェアは代替手段が無いものの、ゆっくりとより優れた技術へと取って代わられて死に絶えます。 -このことは何故この問題が分散形の暗号プロトコルの同様に当てはまるべきでないのかの理由とはなりません。 -しかしながら分散形の暗号システムは自然な疑問へと結びつく。誰が更新のプロセスをコントロールするのでしょうか? -このことを書いている間に、Bitcoinのコミュニティはブロックサイズを1MBから20MBに増やすかどうかを決定するプロセスを辿っていて、 -これは、意図を明確化し、新しく機関を設立して意思決定をするというプロセスを得ずして、 -既定路線による意思決定のプロセスがなされる状況へと結びつくこととなっていて、 -政治的な議論が、小数のコア開発者の中で行われる、という状況を生み出しています。 - -meta-consensus(大衆による合意形成を形作っていくもの)となる intra-protocol(内部プロトコル)は有るのでしょうか、 -ー 即ち、プロトコルの更新に対しての合意形成を円滑化する、 -例えば consensus 決定に関する投票 のような、プロトコルの内部にあるメカニズムはあるでしょうか? -あるいは、何故この理論は分散形の暗号プロトコルに同様に当てはめられるべきではないのでしょうか。 -そんなシステムがあったとすれば、 -恩恵は計り知れず、 -柔軟性が格段と広がり、 -中央集約型のリスクとなる政治的な癒着に頼らずにすみ、 -かつ、参加者に対して大きな発言権を得ることができ、 -社会的に "well-connected" であるような人々のみならず、あらゆる人にその恩恵が行き渡るでしょう。 - (see Jo Freeman's The Tyranny of Structurelessness for more on this). - - - -In order to remain relevant in a rapidly evolving technological landscape, software must update, and software that does not update has no alternative but to slowly fade away and die as it is replaced by superior technology. There is no reason why this principle should not apply to decentralized crypto-protocols as well. However, the need to make upgrades to decentralized crypto-systems leads to a natural question: who controls the updating process? As of the time of this writing, the Bitcoin community is going through the process of deciding whether or not to increase the maximum block size from 1 MB to 20 MB, and the lack of a deliberately instituted decision-making process has lead to the situation where the de-facto decision-making process essentially amounts to political debate among a small number of core developers. - -Is there a way of building intra-protocol meta-consensus - that is, a mechanism inside the protocol that facilitates agreement on upgrades to the protocol, perhaps using some kind of consensus voting? Such a system would have a number of benefits, including greater flexibility, less reliance on political processes that end up being centralization risks, and can arguably ensure a greater voice to all participants in the protocol, not just those that are socially well-connected (see Jo Freeman's The Tyranny of Structurelessness for more on this). - -望ましいメタコンセンサスのプロトコルは下記を含みます: -Desirable properties of meta-consensus include: - -* 利益となるプロトコルの変更に対しての合意のインセンティブ -* ある種の古いプロトコルのもとに作られるアプリケーションが新しいプロトコルのもとでも最大限効果的であること。 -* ある種のオブジェクト指向のカプセル化のメカニズムのように、開発者があるプロトコル特有の機能を使わなければならないようにすることから離れるようにする。(interface の実装) -* メカニズムが壊れないように抗うということは、望ましくないプロトコルの変更をしなければならないことに繋がっていきます。 -* ユーザーが自動的に新しく選ばれたプロトコルへと、新しいクライアントをダウンロードせずに更新することが出来るようにすること。 -* 現時点でこのメタプロトコルに対する取り組みは、Arthur Bretman's Tezos を含む、Bitsharesの delegated proof of stake そして未だリリースされていない Ethereum 2.0 の提案があります。 - -Some kind of guarantee that applications built under the old protocol will remain maximally effective under the new protocol. Note that a part of this will likely be some kind of object-oriented encapsulation mechanisms in order to steer developers away from using features which are highly protocol-specific -Resistance against the mechanism being corrupted in some sense and forced to lead to an undesirable protocol change -The ability for users to automatically upgrade to a newly chosen protocol without having to download a new client -Existing work on this includes Arthur Breitman's Tezos, Bitshares' delegated proof of stake, and the not-yet-released Ethereum 2.0 proposal. - -公共益の設定による解放と、インセンティブの仕組み - -暗号プロトコルの開発における他の大きな問題は、類似しているファンディングの問題です。どのようにしてプロトコルが更新され、そしてより多くの一般的で公共益に繋がるミドルウェアとが結びつくか、という問題です。 -最初の開発フェイズにおいては、Crowdsaleのコンセプトは絶対的に欠かせないものです。何百万ドルの努力に対してのファンディング -そうでなければ・・・以下略 -The other major problem in crypto-protocol development is the analogous funding problem: how will protocol upgrades, and more generally public-good ecosystem middleware, be paid for? In the initial phase of development, the concept of "crowdsales" has proven to be absolutely invaluable, providing millions of dollars of funding for efforts which would have otherwise been relegated to being little more than volunteer side projects. However, crowdsales by themselves have a fundamental problem: they are front-loaded, creating heavy incentives for short-term marketing but less so for long-term performance, and they are limited one-time events from which the funds received eventually run out. And even if the funds could somehow be managed so as not to run out, crypto-protocol development would be permanently centralized in a single organization. What would be ideal is, once again, some kind of intra-protocol mechanism for incentivizing the development of public goods. - -公共益に対するインセンティブ化(動機付け)の仕組みは、長い文章を確立するというものを含んでいます。 -その文章は、 -メカニズムの仕様の設計から生まれる数多くのことと、そしてどのようにして公共益の開発に投資し、どの公共益が第一に投資されるに値するか、を決めるということを含んでいます。 -Blockchainの文脈では、 -個人的なマーケットの文脈よりもファンディングの問題は幾分簡単です。 -なぜなら我々には全ての通貨の保持者に -インフレーションによる課税をし、トランザクションフィーからコンセンサスのコストを引いた超過分を得ることが出来るからです。 -しかし、preferece revelation の問題はいっそう困難なものです。というのは、人間の政府は非公式な決定を用いようとし、サポートに値する公共益が何かを判断するための非公式な判断を用いようとしますが、しかし、Blockchainは文脈的に信頼に足るファンドと、信頼に足らないファンドの違いを知ることが出来ません。例えば、とあるタバコ会社は、そのスキャムであり、使用不可能な "zero address" かどうか判断することができません。 -それ故に、完全にある種の明白なコミュニティからもたらされる情報に対して設計されたメカニズムに頼らなければなりません。 - -Public goods incentivization has a long and established literature, including numerous results from mechanism design and assurance contract theory on the topic of both how to fund the development of public goods and on the equally important question of deciding which public goods are worth funding in the first place. -In a blockchain context, -the funding problem is somewhat easier than in a private-market context, -because we have the ability to "tax" all currency holders via inflation and taking the excess of transaction fees minus consensus costs, -but the preference revelation problem is much harder; -a human government can try to use informal judgement to figure out which public goods are worth supporting and which ones are not, -but a blockchain literally cannot tell the difference between a trustworthy development fund, -an untrustworthy development fund, -a tobacco lobbying company, -the "zero address" from which coins can never be spent and a scammer. Hence, it must rely entirely on some kind of mechanism design to elicit this information from the community. - -この困難は、Blockchainの文脈に対してのこれらの保証について当てはめます。 -この困難に対する特定の挑戦は下記の内容を含みます: -The challenge here is applying these guarantees to a blockchain context. Particular challenges include: - -* インセンティブと結びついたシステムの設計は、ユーザーが安全で信頼をおかずにお互いに贈り合うことさえ出来ます -* 例えばコントラクトを通じて(Game theoryでの協調ゲームはこの点にある) -* インセンティブと結びついたシステムの設計は、攻撃者が(P+ epsilon攻撃のように、協調ゲーム理論が不十分かもしれない、何故なら全体的にユーザーの集合は、完全に強調するか、それとも一切協調しないかのどちらかであることが期待されるからだ。) -* Caplanianの"理性的な非理性 (rational irrationality"の批判には、例えば十分に大きな報酬をユーザーに対して与えることで、どのファンドがサポートに値するかを知り、そして単純にすぐにどのようにみえるのがより良いかをすぐに単純にクリックしない。 - -一般的なモデルは下記のように考えられる。: -* Nの公共益が存在し、それらのファンドが有る公共益に対して使うと約束しているアドレスによって表されているとする。誰でもそのアドレスをこのセットに登録することは出来る、ユーザーが必要とする幾らかの手数料を支払った後かも知れない。、どのようにfunding pool Dを分割するかを選択し、(Dは最大の大きさかもしれない、そのメカニズムは、幾らかのDを燃やすかもしれない。) -* 攻撃者は、そこにただお金を送って欲しいだけの偽物の公共益を作り、公共液として、1が分配される和ありアイが完全に一つのプレイヤーに対していくように見えるかもしれない。 -* 攻撃者がどうして攻撃に成功することが社会的に悪である理由は、他の"公式な”公共益が、より高い支払いの割合を持っているかもしれないからだ - -Being incentive-compatible even given the assumption that users can securely and trustlessly bribe each other, eg. via contracts (cooperative game theory can help here) -Being incentive-compatible even given the assumption that the attacker may have a superior ability to coordinate versus the individual participants (cf. P + epsilon attacks; cooperative game theory may be insufficient here as it generally assumes that collections of users can either coordinate totally or not coordinate at all) -Avoiding Caplanian "rational irrationality" critiques, ie. providing sufficiently large incentives for users to learn about which funds are worth supporting and not simply immediately click on what looks nicer -The general model can be thought of as follows: -もし必要であるならば、我々はユーザーがセキュリティのデポジットを持っていることに頼る事が出来る。例 承認者であること、脅されていないことが証明できる投票) -There exist N public goods, represented by addresses owned by funds that promise to spend the money on particular public goods (eg. development). Anyone can register an address in this set, perhaps after paying some fee -Users need to, using some mechanism, select how to split up funding pool D between these goods (D may be a maximum size; the mechanism may end up "burning" some of D) -Attackers creating fake "public goods" that really just send money to themselves can be seen simply as being public goods with a payoff ratio of 1 that happens to be concentrated entirely in a single player. The reason why attackers winning is socially bad is that other "legitimate" public goods will have much higher payoff ratios -If necessary, we can rely on the users having security deposits, eg. being validators -Coercion-proof Voting - -2001年のAri Juel は、"脅迫耐性のある電子投票システム" のプロトコル を考えついた。 それは投票をオンラインで、ユーザーが他者に誰に投票したくぉ公表すること無く投票が出来るだけでなく、さらには実際に、望むのでさえあれば他の誰かに投票することを証明することが出来ないようになっている。ー脅迫したり賄賂を投票する人に対して送ることが不可能となる。 -投票問題と同様には全般的に、revelation問題の設定を解決する有る一つの可能性のある方法であうr. -このようなスキームを実装することが出来る。それによって協調することが更に困難となる。 -ユーザーが2つのIDをコントロール出来るために、2つのIDが安全に腐敗した取引を互いに行うことは出来、完全な解決策は決してないが、 -富の集中を防ぐことの思い込みはシステムをかなる頑強なものとする。 -Ari Juels in 2001 came up with a protocol for "coercion-resistant electronic elections" - a way of doing voting online such that not only is it possible for users to vote without revealing to others who they voted for, but it is in fact not possible to prove to anyone else who you voted for even if you wanted to - making it impossible to coerce or bribe people to vote. One possible route to solving the preference revelation problem, as well as voting games in general, is to implement this kind of scheme, making it much harder to coordinate. It is by no means a complete solution, since a user that controls two identities can still have those two identities securely collude with each other, but combined with a wealth deconcentration assumption it would make systems substantially more robust. - -試練は、どのようにしてある種の脅迫耐性のある電子投票システムをDecenralizedな公共のblockchainの文脈に実装するかということだ。その最大の問題は、完全に特定の秘密鍵を持っている当事者がおらず、互いに不正をしない信頼される事ができ、システムは完全に公共であることが必要だろう。 - -注意: 暗号学的に脅迫耐性のある投票システムを作る大体の手段は、暗号経済学的に脅迫耐性のある電子投票のシステムを制作することだ。ある種のメカニズムを思いつき、もし投票者が他の当事者に対して証明することが出来たのであれば、ゼロでないクオリティの誰が投票したかに対しての情報を得ることが出来る。 -Note: an alternative to making cryptographically coercion-resistant electronic elections is making cryptoeconomically coercion-resistant electronic elections: come up with some kind of mechanism such that if a voter proves to another party any nonzero quantity of information about who they voted for, that party can exploit them for an expected nonzero return at their expense (if this exploitation can be made to be unprovable, then even better, as it reduces the possibility of effective circumvention through reputation). - -事前に解放されることに反対すること - -Schellingcoinのように沢山のプロトコルがある、AugurではN-of-Nのプロトコルを乱数生成において使用し、ユーザーが最初に暗号的に -ある値xを"コミット”したことに気付き、例えば、H(x)をあるハッシュの関数に対してサブミットすること、そして後になってサブミットされた値xを公表する段階となって、何もrevelationや、誤りとなる解放は無く、セキュリティのデポジットの負担によって罰することが出来る。 -しかしながら、これらの多くのプロトコルは、もしユーザーの答えが最初のフレーズの間はプライベートであるのであれば効果的に機能する。 -そして、取り分け情報を共有した事が証明できるために、不正が簡単になるに連れて、このメカニズムの効率性は、減少していくこととなる。 -There are many protocols such as Schellingcoin, Augur, N-of-N protocols in random number generation, etc, that rely on some notion of users first cryptographically "committing" to some value x, eg. by submitting H(x) for some hash function, and then in a later stage "revealing" the value for x that they submitted - with non-revelation or incorrect revelation being punishable by security deposit loss. However, many of these protocols only work effectively if users' answers during the first phase are private; if users can collude to share information, and particularly if they can provably share information, then the mechanism's effectiveness decreases as collusion becomes easier. - -あらゆるユーザーが0か1かを提供するコミットが明らかにするプロトコを考えて見て欲しい、そしてランダムにこの値を選ぶことを考えてみて欲しい最初は、どちらのユーザーも関係のないsalt s を選ばなければならない、そしてH([s, v]) を提出しvが0か1かとなる。 -そして2番目のステップではユーザーはsとvの値を提出しなければならない、そしてコミットに対してチェックされなければならない。 -全てのvの値の合計をmod2で行ったものは、ランダムな出力の1つを取り上げたもので、ここにおいて - - -Suppose a commit-reveal protocol where all users must supply either 0 or 1, and they are "supposed to" randomly choose this value. In the first step, each user must pick a (irrelevant) salt s, and provide H([s, v]) where v is either 0 or 1. In the second step, the user must supply their values of s and v, and have them be checked against the commitment. The sum of all values v mod 2 is then taken as a single bit of random output. Here, hypothetically all players can talk to each other and provably coordinate on voting either 0 or 1. However, we can design an anti-pre-revelation protocol as follows: any party can choose to register a bet against any other party that they will vote on some specific value with at last a 60% probability (ie. if A bets that B will bet 0, then if B ends up betting 0 then B gets 2 units out of A's security deposit, and if B ends up betting 1 then A gets 3 units out of B's security deposit). Hence, if party P[i] reveals to party P[j] their v value, or even a zero-knowledge proof of their v value with more than 60% probability, they can be exploited. - -困難なことはこの道を選ぶことが出来るか、取りうる値が一層大きく、投票の可能性が前提条件として知られていないかもしれない、もしくは暗号学的に不可能にするか、暗号経済的に誰かの隠された値を明らかにすることをハイコストにすることによって -その他のアプローチ - -A challenge is to either take this path and try to expand it into an environment where the potential value space is much larger and probabilities of voting may not be known a priori, or find some other approach to make it cryptographically impossible or cryptoeconomically expensive to reveal one's hidden value before one is supposed to. Tailoring to specific applications (eg. linear Schellingcoin price voting) is suboptimal but acceptable. A particular problem is the existence of zero-knowledge proofs: one can use zk-SNARKs (or simply plain ZKPs) in order to reveal any information about v and prove that this information is correct by using the provided hash H([s, v]) without revealing anything about s or any information about v that is undesired; hence, a solution should be secure against all kinds of partial information revelation that may be useful, and not simply revealing the exact value of v. - -乱数の生成 -Random Number Generation - -コンセンサスのプロトコルを含む様々なプロトコルにおいてblockchain に基づいたくじ、スケーラブルなサンプル抽出のスキーム当 -ある種の乱数生成をプロトコル内に必要としている。 -Proof of workでは簡単な答えがある、何故なら結果が分かる前に誰かがその回答を計算することが出来ないからだ。そして一旦結果が見つかれば、後悔しないことは大きな機会損失となる。 -しかしながらproof of workは極端に高価であり、セキュリティを保っておくために定常的なコストを必要とする。 -A number of protocols, including consensus protocols, blockchain-based lotteries, scalable sampling schemes, etc, require some kind of random number generation in the protocol. Proof of work provides an answer easily, because one cannot compute ahead of time what the result will be, and once a result is found not revealing it carries a large opportunity cost. However, proof of work is extremely expensive, requiring constant expenditure equal to the security margin. - - -N of N のコミットが明らかにすることの代わりとしてTomilionのRANDAOのプロトコルが上げられる。 -働き方は以下となる。 - -n のPlayerが P[1] ... P[n] としてサイズDのセキュリティのデポジットをプロトコル内に持ち、ランダムな値V[1]... V[n]を -ラウンド1の間にP[i]はH(V[i])をサブミットする。 -ラウンド2では、H(V[i])を提出した全てのプレイヤーはV[i}を提出しなければならない。 -もし全てのプレイヤーがそれらの値を正しく提出したならば、(V[1] + ... + V[n]) % 2**256 はランダムなシードとして取り上げられ、そして全てのプレイヤーは自らの値を正しく公開する。 -n players P[1] ... P[n] with security deposits of size D in the protocol choose random values V[1] ... V[n] with 0 <= v[i] < 2**256, and P[i] submits H(V[i]) during round one. -In round two, every player who submitting a value H(V[i]) must submit V[i]. -If all players submit their value correctly, then (V[1] + ... + V[n]) % 2**256 is taken as a random seed, and all players are rewarded with D * i where i is an interest rate (eg. 0.0001 per period). -If not all players submitted their value correctly, then all players who participated get D * i, all players who did not participate lose their entire deposit and are kicked out, and the remaining players repeat the game until eventually all N players cooperate and reveal their values. -もし最後のプレイヤーが参加 -If you are the last player to participate, then you can manipulate the value at a very high cost, and even then only by replacing it with a random value next time around (ie. one can avoid unfavorable values, but one cannot target favorable values or even choose between two known values). However, the mechanism has the limitations that (i) it relies on a non-collusion assumption, (ii) the randomness that it provides is not nearly as fast as proof of work randomness, making it useless for some specific intra-block applications where proof of work shines, and (iii) it can lead to honest players losing large amounts of money from a network attack. Mitigating problem (iii) necessarily involves exacerbating problem (ii), and vice versa. - -The open-ended challenge is to come up with a mechanism inside of a cryptoeconomic context which provides random numbers as output with maximally relaxed security assumptions and maximal robustness and resilience to attackers - ideally, a mechanism with the same properties as proof of work but without (or with only a negligible fraction of) its cost. - -検閲耐久性 -Anti-censorship - -Public blockchains particularly have a strong need to be censorship-resistant, ie. to be able to get transactions into the chain even if powerful parties do not want them included. This is important not just for controversial Wikileaks-style applications; even ordinary financial applications, commit-reveal protocols, etc, could have their security threatened if there was a way of effectively preventing "challenge" messages from entering the blockchain. - -If the set of participants willing to collude to censor is smaller than 33%, then the problem is fairly trivial. If the set is greater than 33%, however, then we know that those participants have the power to shut down the network, albeit at very high cost to themselves. Hence, the problem becomes somewhat different: how do we make it impossible for colluding censors to censor specific transactions without censoring everything else as well? - -One possible route to take is some kind of commit-reveal protocol, where users submit a hash of a transaction plus proof that the transaction is available, and then the transaction sender is somehow bound to include the transaction itself once it is revealed (ie. blocks that do not include the transaction will be invalid). However, this has the problem that (i) proof of availability is very hard to implement, and (ii) colluding censors can simply require the submission of a transaction alongside its proof. In general, any protocol will likely be vulnerable to "colluding censors can simply require a zero-knowledge proof of X", but the challenge is making such a requirement maximally inconvenient for all parties to implement. - -プライバシー -Privacy - -Blockchains are often hailed as an alternative to centralized networks that rely on trusting specific parties. However, one of the major areas in which people actually do strongly distrust centralized parties in real life is in the area of privacy, and blockchain protocols by themsleves are even more public than centralized systems. Hence, blockchain-based solutions to privacy will likely need to go a bit beyond simply creating a decentralized database and being done with it; effort must be made into creating protocols for maximally broad categories of applications (eg. payments, financial contracts, identity and reputation info publication) that combine blockchain-based data publication with protocols that preserve individual privacy, and allow individuals maximum freedom in what facts about themselves to expose to what parties. - -この問題の副次的な問題は以下を含む -Sub-problems of this problem include: - -完全に匿名な通貨(現在はZerocashがある。Zerocashの論証可能な大きな欠点は、xkSNARKsを使っていることがら生じる90秒の間トランザクションの署名の時間を必要としていることだ。) -Privacyが担保された名声のシステムはユーザーが”Zero-knowledgeのreputationの証明"システムを作ることが出来るようにし、ターゲットの望ましい数値に応じて幾らかの名声のスコアを持つことが出来、しかし最小の他の個人的な情報を晒していることだ。 - -対象が求める基準に従ってreputation scoreを持つことが、最小の個人的な情報だけを公開する事で出来る -"zero-knowledge reputation certificates"を作ることが出来るようにしているプライバシーが担保されたreputationシステム - -A privacy-preserving reputation system that allows users to create "zero-knowledge reputation certificates" proving that they have some reputation score according to the target's desired metric but revealing minimal other personal information - -ユーザーがそのコントラクトのコードとコンテントを最大限可能な限り隠せるようにしている金融のコントラクトのシステム - -最大限プライバシーを保護している分散形の internet of thingsのプラットフォーム -A maximally privacy-preserving decentralized internet-of-things platform diff --git a/pages/other-languages/[Japanese]-Javascript-API.md b/pages/other-languages/[Japanese]-Javascript-API.md deleted file mode 100644 index 881269a78..000000000 --- a/pages/other-languages/[Japanese]-Javascript-API.md +++ /dev/null @@ -1,2040 +0,0 @@ ---- -name: Javascript API -category: ---- - -# Introduction - -Dapp を Ethereum 上でうごかすために、`web3` オブジェクトが使えます。これは [web3.js library](https://github.com/ethereum/web3.js)で提供されています。 -この、まるでパーカーのフードのように、 ethereum を包み込んだライブラリのもとでは、 -ローカルのノードと -[RPC calls](https://github.com/ethereum/wiki/wiki/JSON-RPC)を介して通信できます。 -web3.js はすべての ethereum node と通信可能で、そのノードは RPC を発信しています。 - -`web3` オブジェクトは、 -`eth` オブジェクトと - `web3.eth` ( Ethereum blockchain との通信に特化したオブジェクト) と -`shh` オブジェクト - `web3.shh` ( Whisper 上のやりとりのためのオブジェクト) を保持します。 -時間の経過とともに、web3 プロトコル上の他のオブジェクトも紹介していくつもりです。 -使用例は [こちら](https://github.com/ethereum/web3.js/tree/master/example). - -web3.js の洗練された使用例につきましては、[useful Ðapp patterns](https://github.com/ethereum/wiki/wiki/Useful-Ðapp-Patterns)をごらんください。 - -## Using callbacks - -As this API is designed to work with a local RPC node and all its functions are by default use synchronous HTTP requests.con - -If you want to make asynchronous request, you can pass an optional callback as the last parameter to most functions. -All callbacks are using an [error first callback](http://fredkschott.com/post/2014/03/understanding-error-first-callbacks-in-node-js/) style: - -```js -web3.eth.getBlock(48, function(error, result){ - if(!error) - console.log(result) - else - console.error(error); -}) -``` - -## Batch requests - -Batch requests allow queuing up requests and processing them at once. - -```js -var batch = web3.createBatch(); -batch.add(web3.eth.getBalance.request('0x0000000000000000000000000000000000000000', 'latest', callback)); -batch.add(web3.eth.contract(abi).at(address).balance.request(address, callback2)); -batch.execute(); -``` - -## A note on big numbers in web3.js - -You will always get a BigNumber object for balance values as JavaScript is not able to handle big numbers correctly. -Look at the following examples: - -```js -"101010100324325345346456456456456456456" -// "101010100324325345346456456456456456456" -101010100324325345346456456456456456456 -// 1.0101010032432535e+38 -``` - -web3.js depends on the [BigNumber Library](https://github.com/MikeMcl/bignumber.js/) and adds it automatically. - -```js -var balance = new BigNumber('131242344353464564564574574567456'); -// or var balance = web3.eth.getBalance(someAddress); - -balance.plus(21).toString(10); // toString(10) converts it to a number string -// "131242344353464564564574574567477" -``` - -The next example wouldn't work as we have more than 20 floating points, therefore it is recommended to keep you balance always in *wei* and only transform it to other units when presenting to the user: -```js -var balance = new BigNumber('13124.234435346456466666457455567456'); - -balance.plus(21).toString(10); // toString(10) converts it to a number string, but can only show max 20 floating points -// "13145.23443534645646666646" // you number would be cut after the 20 floating point -``` - -# API - -* [web3](#web3) - * [version](#web3versionapi) - * [api](#web3versionapi) - * [client](#web3versionclient) - * [network](#web3versionnetwork) - * [ethereum](#web3versionethereum) - * [whisper](#web3versionwhisper) - * [setProvider(provider)](#web3setprovider) - * [currentProvider](#web3currentprovider) - * [reset()](#web3reset) - * [sha3(string)](#web3sha3) - * [toHex(stringOrNumber)](#web3tohex) - * [toAscii(hexString)](#web3toascii) - * [fromAscii(textString, [padding])](#web3fromascii) - * [toDecimal(hexString)](#web3todecimal) - * [fromDecimal(number)](#web3fromdecimal) - * [fromWei(numberStringOrBigNumber, unit)](#web3fromwei) - * [toWei(numberStringOrBigNumber, unit)](#web3toWei) - * [toBigNumber(numberOrHexString)](#web3tobignumber) - * [isAddress(hexString)](#web3isAddress) - * [net](#web3net) - * [listening/getListening](#web3netlistening) - * [peerCount/getPeerCount](#web3ethpeercount) - * [eth](#web3eth) - * [defaultAccount](#web3ethdefaultaccount) - * [defaultBlock](#web3ethdefaultblock) - * [coinbase/getCoinbase](#web3ethcoinbase) - * [hashrate/getHashrate](#web3ethhashrate) - * [gasPrice/getGasPrice](#web3ethgasprice) - * [accounts/getAccounts](#web3ethaccounts) - * [mining/getMining](#web3ethmining) - * [blockNumber/getBlockNumber](#web3ethblocknumber) - * [register(hexString)](#web3ethregister) (Not implemented yet) - * [unRegister(hexString)](#web3ethunregister) (Not implemented yet) - * [getBalance(address)](#web3ethgetbalance) - * [getStorageAt(address, position)](#web3ethgetstorageat) - * [getCode(address)](#web3ethgetcode) - * [getBlock(hash/number)](#web3ethgetblock) - * [getBlockTransactionCount(hash/number)](#web3ethgetblocktransactioncount) - * [getUncle(hash/number)](#web3ethgetuncle) - * [getBlockUncleCount(hash/number)](#web3ethgetblockunclecount) - * [getTransaction(hash)](#web3ethgettransaction) - * [getTransactionFromBlock(hashOrNumber, indexNumber)](#web3ethgettransactionfromblock) - * [getTransactionReceipt(hash)](#web3ethgettransactionreceipt) - * [getTransactionCount(address)](#web3ethgettransactioncount) - * [sendTransaction(object)](#web3ethsendtransaction) - * [call(object)](#web3ethcall) - * [estimateGas(object)](#web3ethestimategas) - * [filter(array (, options) )](#web3ethfilter) - - [watch(callback)](#web3ethfilter) - - [stopWatching(callback)](#web3ethfilter) - - [get()](#web3ethfilter) - * [contract(abiArray)](#web3ethcontract) - * [contract.myMethod()](#contract-methods) - * [contract.myEvent()](#contract-events) - * [getCompilers()](#web3ethgetcompilers) - * [compile.lll(string)](#web3ethcompilelll) - * [compile.solidity(string)](#web3ethcompilesolidity) - * [compile.serpent(string)](#web3ethcompileserpent) - * [namereg](#web3ethnamereg) - * [db](#web3db) - * [putString(name, key, value)](#web3dbputstring) - * [getString(name, key)](#web3dbgetstring) - * [putHex(name, key, value)](#web3dbputhex) - * [getHex(name, key)](#web3dbgethex) - * [shh](#web3shh) - * [post(postObject)](#web3shhpost) - * [newIdentity()](#web3shhnewidentity) - * [hasIdentity(hexString)](#web3shhhaveidentity) - * [newGroup(_id, _who)](#web3shhnewgroup) - * [addToGroup(_id, _who)](#web3shhaddtogroup) - * [filter(object/string)](#web3shhfilter) - * [watch(callback)](#web3shhfilter) - * [stopWatching(callback)](#web3shhfilter) - * [get(callback)](#web3shhfilter) - -## Usage - -#### web3 -The `web3` object provides all methods. - -##### Example - -```js -var web3 = require('web3') -``` - -*** - -#### web3.version.api - - web3.version.api - // or async - web3.version.getApi(callback(error, result){ ... }) - -##### Returns - -`String` - The ethereum js api version. - -##### Example - -```js -var version = web3.version.api; -console.log(api); // "0.2.0" -``` - -*** - -#### web3.version.client - - web3.version.client - // or async - web3.version.getClient(callback(error, result){ ... }) - - -##### Returns - -`String` - The client/node version. - -##### Example - -```js -var version = web3.version.client; -console.log(version); // "Mist/v0.9.3/darwin/go1.4.1" -``` - -*** - -#### web3.version.network - - web3.version.network - // or async - web3.version.getNetwork(callback(error, result){ ... }) - - -##### Returns - -`String` - The network protocol version. - -##### Example - -```js -var version = web3.version.network; -console.log(version); // 54 -``` - -*** - -#### web3.version.ethereum - - web3.version.ethereum - // or async - web3.version.getEthereum(callback(error, result){ ... }) - - -##### Returns - -`String` - The ethereum protocol version. - -##### Example - -```js -var version = web3.version.ethereum; -console.log(version); // 60 -``` - -*** - -#### web3.version.whisper - - web3.version.whisper - // or async - web3.version.getWhisper(callback(error, result){ ... }) - - -##### Returns - -`String` - The whisper protocol version. - -##### Example - -```js -var version = web3.version.whisper; -console.log(version); // 20 -``` - -*** - -#### web3.setProvider - - web3.setProvider(provider) - -Should be called to set provider. - -##### Parameters -none - -##### Returns - -`undefined` - -##### Example - -```js -web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545')); // 8080 for cpp/AZ, 8545 for go/mist -``` - -*** - -#### web3.currentProvider - - web3.currentProvider - -Will contain the current provider, if one is set. This can be used to check if mist etc. set already a provider. - - -##### Returns - -`Object` - The provider set or `null`; - -##### Example - -```js -// Check if mist etc. already set a provider -if(!web3.currentProvider) - web3.setProvider(new web3.providers.HttpProvider("http://localhost:8545")); - -``` - -*** - -#### web3.reset - - web3.reset() - -Should be called to reset state of web3. Resets everything except manager. Uninstalls all filters. Stops polling. - -##### Parameters -none - -##### Returns - -`undefined` - -##### Example - -```js -web3.reset(); -``` - -*** - -#### web3.sha3 - - web3.sha3(string [, callback]) - -##### Parameters - -1. `String` - The string to hash using the SHA3 algorithm -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -`String` - The SHA3 of the given data. - -##### Example - -```js -var str = web3.sha3("Some ASCII string to be hashed"); -console.log(str); // "0x536f6d6520415343494920737472696e6720746f20626520686173686564" - -var hash = web3.sha3(str); -console.log(hash); // "0xb21dbc7a5eb6042d91f8f584af266f1a512ac89520f43562c6c1e37eab6eb0c4" -``` - -*** - -#### web3.toHex - - web3.toHex(mixed); - -Converts any value into HEX. - -##### Parameters - -1. `String|Number|Object|Array|BigNumber` - The value to parse to HEX. If its an object or array it will be `JSON.stringify` first. If its a BigNumber it will make it the HEX value of a number. - -##### Returns - -`String` - The hex string of `mixed`. - -##### Example - -```js -var str = web3.toHex({test: 'test'}); -console.log(str); // '0x7b2274657374223a2274657374227d' -``` - -*** - -#### web3.toAscii - - web3.toAscii(hexString); - -Converts a HEX string into a ASCII string. - -##### Parameters - -1. `String` - A HEX string to be converted to ascii. - -##### Returns - -`String` - An ASCII string made from the given `hexString`. - -##### Example - -```js -var str = web3.toAscii("0x657468657265756d000000000000000000000000000000000000000000000000"); -console.log(str); // "ethereum" -``` - -*** - -#### web3.fromAscii - - web3.fromAscii(string [, padding]); - -Converts any ASCII string to a HEX string. - -##### Parameters - -1. `String` - An ASCII string to be converted to HEX. -2. `Number` - The number of bytes the returned HEX string should have. - -##### Returns - -`String` - The converted HEX string. - -##### Example - -```js -var str = web3.fromAscii('ethereum'); -console.log(str); // "0x657468657265756d" - -var str2 = web3.fromAscii('ethereum', 32); -console.log(str2); // "0x657468657265756d000000000000000000000000000000000000000000000000" -``` - -*** - -#### web3.toDecimal - - web3.toDecimal(hexString); - -Converts a HEX string to its number representation. - -##### Parameters - -1. `String` - An HEX string to be converted to a number. - - -##### Returns - -`Number` - The number representing the data `hexString`. - -##### Example - -```js -var number = web3.toDecimal('0x15'); -console.log(number); // 21 -``` - -*** - -#### web3.fromDecimal - - web3.fromDecimal(number); - -Converts a number or number string to its HEX representation. - -##### Parameters - -1. `Number|String` - A number to be converted to a HEX string. - -##### Returns - -`String` - The HEX string representing of the given `number`. - -##### Example - -```js -var value = web3.fromDecimal('21'); -console.log(value); // "0x15" -``` - -*** - -#### web3.fromWei - - web3.fromWei(number, unit) - -Converts a number of wei into the following ethereum units: - -- `kwei`/`ada` -- `mwei`/`babbage` -- `gwei`/`shannon` -- `szabo` -- `finney` -- `ether` -- `kether`/`grand`/`einstein` -- `mether` -- `gether` -- `tether` - -##### Parameters - -1. `Number|String|BigNumber` - A number or BigNumber instance. -2. `String` - One of the above ether units. - - -##### Returns - -`String|BigNumber` - Either a number string, or a BigNumber instance, depending on the given `number` parameter. - -##### Example - -```js -var value = web3.fromWei('21000000000000', 'finney'); -console.log(value); // "0.021" -``` - -*** - -#### web3.toWei - - web3.toWei(number, unit) - -Converts an ethereum unit into wei. Possible units are: - -- `kwei`/`ada` -- `mwei`/`babbage` -- `gwei`/`shannon` -- `szabo` -- `finney` -- `ether` -- `kether`/`grand`/`einstein` -- `mether` -- `gether` -- `tether` - -##### Parameters - -1. `Number|String|BigNumber` - A number or BigNumber instance. -2. `String` - One of the above ether units. - -##### Returns - -`String|BigNumber` - Either a number string, or a BigNumber instance, depending on the given `number` parameter. - -##### Example - -```js -var value = web3.toWei('1', 'ether'); -console.log(value); // "1000000000000000000" -``` - -*** - -#### web3.toBigNumber - - web3.toBigNumber(numberOrHexString); - -Converts a given number into a BigNumber instance. - -See the [note on BigNumber](#a-note-on-big-numbers-in-javascript). - -##### Parameters - -1. `Number|String` - A number, number string or HEX string of a number. - - -##### Returns - -`BigNumber` - A BigNumber instance representing the given value. - - -##### Example - -```js -var value = web3.toBigNumber('200000000000000000000001'); -console.log(value); // instanceOf BigNumber -console.log(value.toNumber()); // 2.0000000000000002e+23 -console.log(value.toString(10)); // '200000000000000000000001' -``` - -*** - -### web3.net - -#### web3.net.listening - - web3.net.listening - // or async - web3.net.getListening(callback(error, result){ ... }) - -This property is read only and says whether the node is actively listening for network connections or not. - -##### Returns - -`Boolean` - `true` if the client is actively listening for network connections, otherwise `false`. - -##### Example - -```js -var listening = web3.net.listening; -console.log(listening); // true of false -``` - -*** - -#### web3.net.peerCount - - web3.net.peerCount - // or async - web3.net.getPeerCount(callback(error, result){ ... }) - -This property is read only and returns the number of connected peers. - -##### Returns - -`Number` - The number of peers currently connected to the client. - -##### Example - -```js -var peerCount = web3.net.peerCount; -console.log(peerCount); // 4 -``` - -*** - -### web3.eth - -Contains the ethereum blockchain related methods. - -##### Example - -```js -var eth = web3.eth; -``` - -*** - -#### web3.eth.defaultAccount - - web3.eth.defaultAccount - -This default address is used for the following methods (optionally you can overwrite it by specifying the `from` property): - -- [web3.eth.sendTransaction()](#web3ethsendtransaction) -- [web3.eth.call()](#web3ethcall) - -##### Values - -`String`, 20 Bytes - Any address you own, or where you have the private key for. - -*Default is* `undefined`. - -##### Returns - -`String`, 20 Bytes - The currently set default address. - -##### Example - -```js -var defaultAccount = web3.eth.defaultAccount; -console.log(defaultAccount); // '' - -// set the default block -web3.eth.defaultAccount = '0x8888f1f195afa192cfee860698584c030f4c9db1'; -``` - -*** - -#### web3.eth.defaultBlock - - web3.eth.defaultBlock - -This default block is used for the following methods (optionally you can overwrite the defaultBlock by passing it as the last parameter): - -- [web3.eth.getBalance()](#web3ethgetbalance) -- [web3.eth.getCode()](#web3ethgetcode) -- [web3.eth.getTransactionCount()](#web3ethgettransactioncount) -- [web3.eth.getStorageAt()](#web3ethgetstorageat) -- [web3.eth.call()](#web3ethcall) - -##### Values - -Default block parameters can be one of the following: - -- `Number` - a block number -- `String` - `"earliest"`, the genisis block -- `String` - `"latest"`, the latest block (current head of the blockchain) -- `String` - `"pending"`, the currently mined block (including pending transactions) - -*Default is* `latest` - -##### Returns - -`Number|String` - The default block number to use when querying a state. - -##### Example - -```js -var defaultBlock = web3.eth.defaultBlock; -console.log(defaultBlock); // 'latest' - -// set the default block -web3.eth.defaultBlock = 231; -``` - -*** - -#### web3.eth.coinbase - - web3.eth.coinbase - // or async - web3.eth.getCoinbase(callback(error, result){ ... }) - -This property is read only and returns the coinbase address were the mining rewards go to. - -##### Returns - -`String` - The coinbase address of the client. - -##### Example - -```js -var coinbase = web3.eth.coinbase; -console.log(coinbase); // "0x407d73d8a49eeb85d32cf465507dd71d507100c1" -``` - -*** - -#### web3.eth.mining - - web3.eth.mining - // or async - web3.eth.getMining(callback(error, result){ ... }) - - -This property is read only and says whether the node is mining or not. - - -##### Returns - -`Boolean` - `true` if the client is mining, otherwise `false`. - -##### Example - -```js -var mining = web3.eth.mining; -console.log(mining); // true or false -``` - -*** - -#### web3.eth.hashrate - - web3.eth.hashrate - // or async - web3.eth.getHashrate(callback(error, result){ ... }) - -This property is read only and returns the number of hashes per second that the node is mining with. - - -##### Returns - -`Number` - number of hashes per second. - -##### Example - -```js -var hashrate = web3.eth.hashrate; -console.log(hashrate); // 493736 -``` - -*** - -#### web3.eth.gasPrice - - web3.eth.gasPrice - // or async - web3.eth.getGasPrice(callback(error, result){ ... }) - - -This property is read only and returns the current gas price. -The gas price is determined by the x latest blocks median gas price. - -##### Returns - -`BigNumber` - A BigNumber instance of the current gas price in wei. - -See the [note on BigNumber](#a-note-on-big-numbers-in-javascript). - -##### Example - -```js -var gasPrice = web3.eth.gasPrice; -console.log(gasPrice.toString(10)); // "10000000000000" -``` - -*** - -#### web3.eth.accounts - - web3.eth.accounts - // or async - web3.eth.getAccounts(callback(error, result){ ... }) - -This property is read only and returns a list of accounts the node controls. - -##### Returns - -`Array` - An array of addresses controlled by client. - -##### Example - -```js -var accounts = web3.eth.accounts; -console.log(accounts); // ["0x407d73d8a49eeb85d32cf465507dd71d507100c1"] -``` - -*** - -#### web3.eth.blockNumber - - web3.eth.blockNumber - // or async - web3.eth.getBlockNumber(callback(error, result){ ... }) - -This property is read only and returns the current block number. - -##### Returns - -`Number` - The number of the most recent block. - -##### Example - -```js -var number = web3.eth.blockNumber; -console.log(number); // 2744 -``` - -*** - -#### web3.eth.register - - web3.eth.register(addressHexString [, callback]) - -(Not Implemented yet) -Registers the given address to be included in `web3.eth.accounts`. This allows non-private-key owned accounts to be associated as an owned account (e.g., contract wallets). - -##### Parameters - -1. `String` - The address to register -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -? - - -##### Example - -```js -web3.eth.register("0x407d73d8a49eeb85d32cf465507dd71d507100ca") -``` - -*** - -#### web3.eth.unRegister - - web3.eth.unRegister(addressHexString [, callback]) - - -(Not Implemented yet) -Unregisters a given address. - -##### Parameters - -1. `String` - The address to unregister. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -? - - -##### Example - -```js -web3.eth.unregister("0x407d73d8a49eeb85d32cf465507dd71d507100ca") -``` - -*** - -#### web3.eth.getBalance - - web3.eth.getBalance(addressHexString [, defaultBlock] [, callback]) - -Get the balance of an address at a given block. - -##### Parameters - -1. `String` - The address to get the balance of. -2. `Number|String` - (optional) If you pass this parameter it will not use the default block set with [web3.eth.defaultBlock](#web3ethdefaultblock). -3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - A BigNumber instance of the current balance for the given address in wei. - -See the [note on BigNumber](#a-note-on-big-numbers-in-javascript). - -##### Example - -```js -var balance = web3.eth.getBalance("0x407d73d8a49eeb85d32cf465507dd71d507100c1"); -console.log(balance); // instanceof BigNumber -console.log(balance.toString(10)); // '1000000000000' -console.log(balance.toNumber()); // 1000000000000 -``` - -*** - -#### web3.eth.getStorageAt - - web3.eth.getStorageAt(addressHexString, position [, defaultBlock] [, callback]) - -Get the storage at a specific position of an address. - -##### Parameters - -1. `String` - The address to get the storage from. -2. `Number` - The index position of the storage. -3. `Number|String` - (optional) If you pass this parameter it will not use the default block set with [web3.eth.defaultBlock](#web3ethdefaultblock). -4. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -`String` - The value in storage at the given position. - -##### Example - -```js -var state = web3.eth.getStorageAt("0x407d73d8a49eeb85d32cf465507dd71d507100c1", 0); -console.log(state); // "0x03" -``` - -*** - -#### web3.eth.getCode - - web3.eth.getCode(addressHexString [, defaultBlock] [, callback]) - -Get the code at a specific address. - -##### Parameters - -1. `String` - The address to get the code from. -2. `Number|String` - (optional) If you pass this parameter it will not use the default block set with [web3.eth.defaultBlock](#web3ethdefaultblock). -3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - The data at given address `addressHexString`. - -##### Example - -```js -var code = web3.eth.getCode("0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8"); -console.log(code); // "0x600160008035811a818181146012578301005b601b6001356025565b8060005260206000f25b600060078202905091905056" -``` - -*** - -#### web3.eth.getBlock - - web3.eth.getBlock(blockHashOrBlockNumber [, returnTransactionObjects] [, callback]) - -Returns a block matching the block number or block hash. - -##### Parameters - -1. `String|Number` - The block number or hash. Or the string `"earliest"`, `"latest"` or `"pending"` as in the [default block parameter](#web3ethdefaultblock). -2. `Boolean` - (optional, default `false`) If `true`, the returned block will contain all transactions as objects, if `false` it will only contains the transaction hashes. -3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Object` - The block object: - - - `number`: `Number` - the block number. `null` when its pending block. - - `hash`: `String`, 32 Bytes - hash of the block. `null` when its pending block. - - `parentHash`: `String`, 32 Bytes - hash of the parent block. - - `nonce`: `String`, 8 Bytes - hash of the generated proof-of-work. `null` when its pending block. - - `sha3Uncles`: `String`, 32 Bytes - SHA3 of the uncles data in the block. - - `logsBloom`: `String`, 256 Bytes - the bloom filter for the logs of the block. `null` when its pending block. - - `transactionsRoot`: `String`, 32 Bytes - the root of the transaction trie of the block - - `stateRoot`: `String`, 32 Bytes - the root of the final state trie of the block. - - `miner`: `String`, 20 Bytes - the address of the beneficiary to whom the mining rewards were given. - - `difficulty`: `BigNumber` - integer of the difficulty for this block. - - `totalDifficulty`: `BigNumber` - integer of the total difficulty of the chain until this block. - - `extraData`: `String` - the "extra data" field of this block. - - `size`: `Number` - integer the size of this block in bytes. - - `gasLimit`: `Number` - the maximum gas allowed in this block. - - `gasUsed`: `Number` - the total used gas by all transactions in this block. - - `timestamp`: `Number` - the unix timestamp for when the block was collated. - - `transactions`: `Array` - Array of transaction objects, or 32 Bytes transaction hashes depending on the last given parameter. - - `uncles`: `Array` - Array of uncle hashes. - -##### Example - -```js -var info = web3.eth.block(3150); -console.log(info); -/* -{ - "number": 3, - "hash": "0xef95f2f1ed3ca60b048b4bf67cde2195961e0bba6f70bcbea9a2c4e133e34b46", - "parentHash": "0x2302e1c0b972d00932deb5dab9eb2982f570597d9d42504c05d9c2147eaf9c88", - "nonce": "0xfb6e1a62d119228b", - "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "transactionsRoot": "0x3a1b03875115b79539e5bd33fb00d8f7b7cd61929d5a3c574f507b8acf415bee", - "stateRoot": "0xf1133199d44695dfa8fd1bcfe424d82854b5cebef75bddd7e40ea94cda515bcb", - "miner": "0x8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty": BigNumber, - "totalDifficulty": BigNumber, - "size": 616, - "extraData": "0x", - "gasLimit": 3141592, - "gasUsed": 21662, - "timestamp": 1429287689, - "transactions": [ - "0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b" - ], - "uncles": [] -} -*/ -``` - -*** - -#### web3.eth.getBlockTransactionCount - - web3.eth.getBlockTransactionCount(hashStringOrBlockNumber [, callback]) - -Returns the number of transaction in a given block. - -##### Parameters - -1. `String|Number` - The block number or hash. Or the string `"earliest"`, `"latest"` or `"pending"` as in the [default block parameter](#web3ethdefaultblock). -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Number` - The number of transactions in the given block. - -##### Example - -```js -var number = web3.eth.getBlockTransactionCount("0x407d73d8a49eeb85d32cf465507dd71d507100c1"); -console.log(number); // 1 -``` - -*** - -#### web3.eth.getUncle - - web3.eth.getUncle(blockHashStringOrNumber, uncleNumber [, returnTransactionObjects] [, callback]) - -Returns a blocks uncle by a given uncle index position. - -##### Parameters - -1. `String|Number` - The block number or hash. Or the string `"earliest"`, `"latest"` or `"pending"` as in the [default block parameter](#web3ethdefaultblock). -2. `Number` - The index position of the uncle. -3. `Boolean` - (optional, default `false`) If `true`, the returned block will contain all transactions as objects, if `false` it will only contains the transaction hashes. -4. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -`Object` - the returned uncle. For a return value see [web3.eth.getBlock()](#web3ethgetblock). - -**Note**: An uncle doesn't contain individual transactions. - -##### Example - -```js -var uncle = web3.eth.getUncle(500, 0); -console.log(uncle); // see web3.eth.getBlock - -``` - -*** - -##### web3.eth.getTransaction - - web3.eth.getTransaction(transactionHash [, callback]) - -Returns a transaction matching the given transaction hash. - -##### Parameters - -1. `String` - The transaction hash. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -`Object` - A transaction object its hash `transactionHash`: - - - `hash`: `String`, 32 Bytes - hash of the transaction. - - `nonce`: `Number` - the number of transactions made by the sender prior to this one. - - `blockHash`: `String`, 32 Bytes - hash of the block where this transaction was in. `null` when its pending. - - `blockNumber`: `Number` - block number where this transaction was in. `null` when its pending. - - `transactionIndex`: `Number` - integer of the transactions index position in the block. `null` when its pending. - - `from`: `String`, 20 Bytes - address of the sender. - - `to`: `String`, 20 Bytes - address of the receiver. `null` when its a contract creation transaction. - - `value`: `BigNumber` - value transferred in Wei. - - `gasPrice`: `BigNumber` - gas price provided by the sender in Wei. - - `gas`: `Number` - gas provided by the sender. - - `input`: `String` - the data send along with the transaction. - - -##### Example - -```js -var blockNumber = 668; -var indexOfTransaction = 0 - -var transaction = web3.eth.getTransaction(blockNumber, indexOfTransaction); -console.log(transaction); -/* -{ - "hash": "0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b", - "nonce": 2, - "blockHash": "0xef95f2f1ed3ca60b048b4bf67cde2195961e0bba6f70bcbea9a2c4e133e34b46", - "blockNumber": 3, - "transactionIndex": 0, - "from": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "to": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f", - "value": BigNumber, - "gas": 314159, - "gasPrice": BigNumber, - "input": "0x57cb2fc4" -} -*/ - -``` - -*** - -#### web3.eth.getTransactionFromBlock - - getTransactionFromBlock(hashStringOrNumber, indexNumber [, callback]) - -Returns a transaction based on a block hash or number and the transactions index position. - -##### Parameters - -1. `String` - A block number or hash. Or the string `"earliest"`, `"latest"` or `"pending"` as in the [default block parameter](#web3ethdefaultblock). -2. `Number` - The transactions index position. -3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Object` - A transaction object, see [web3.eth.getTransaction](#web3ethgettransaction): - - -##### Example - -```js -var transaction = web3.eth.getTransactionFromBlock('0x4534534534', 2); -console.log(transaction); // see web3.eth.getTransaction - -``` - -*** - -#### web3.eth.getTransactionReceipt - - web3.eth.getTransactionReceipt(hashString [, callback]) - -Returns the receipt of a transaction by transaction hash. - -**Note** That the receipt is not available for pending transactions. - - -##### Parameters - -1. `String` - The transaction hash. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Object` - A transaction receipt object, or `null` when no receipt was found: - - - `blockHash`: `String`, 32 Bytes - hash of the block where this transaction was in. - - `blockNumber`: `Number` - block number where this transaction was in. - - `transactionHash`: `String`, 32 Bytes - hash of the transaction. - - `transactionIndex`: `Number` - integer of the transactions index position in the block. - - `from`: `String`, 20 Bytes - address of the sender. - - `to`: `String`, 20 Bytes - address of the receiver. `null` when its a contract creation transaction. - - `cumulativeGasUsed `: `Number ` - The total amount of gas used when this transaction was executed in the block. - - `gasUsed `: `Number ` - The amount of gas used by this specific transaction alone. - - `contractAddress `: `String` - 20 Bytes - The contract address created, if the transaction was a contract creation, otherwise `null`. - - `logs `: `Array` - Array of log objects, which this transaction generated. - -##### Example -```js -var receipt = web3.eth.getTransactionReceipt('0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b'); -console.log(receipt); -{ - "transactionHash": "0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b", - "transactionIndex": 0, - "blockHash": "0xef95f2f1ed3ca60b048b4bf67cde2195961e0bba6f70bcbea9a2c4e133e34b46", - "blockNumber": 3, - "contractAddress": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "cumulativeGasUsed": 314159, - "gasUsed": 30234, - "logs": [{ - // logs as returned by getFilterLogs, etc. - }, ...] -} -``` - -*** - -#### web3.eth.getTransactionCount - - web3.eth.getTransactionCount(addressHexString [, defaultBlock] [, callback]) - -Get the numbers of transactions send from this address. - -##### Parameters - -1. `String` - The address to get the numbers of transactions from. -2. `Number|String` - (optional) If you pass this parameter it will not use the default block set with [web3.eth.defaultBlock](#web3ethdefaultblock). -3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Number` - The number of transactions send from the given address. - -##### Example - -```js -var number = web3.eth.getTransactionCount("0x407d73d8a49eeb85d32cf465507dd71d507100c1"); -console.log(number); // 1 -``` - -*** - -#### web3.eth.sendTransaction - - web3.eth.sendTransaction(transactionObject [, callback]) - -Sends a transaction to the network. - -##### Parameters - -1. `Object` - The transaction object to send: - - `from`: `String` - The address for the sending account. Uses the [web3.eth.defaultAccount](#web3ethdefaultaccount) property, if not specified. - - `to`: `String` - (optional) The destination address of the message, left undefined for a contract-creation transaction. - - `value`: `Number|String|BigNumber` - (optional) The value transferred for the transaction in Wei, also the endowment if it's a contract-creation transaction. - - `gas`: `Number|String|BigNumber` - (optional, default: To-Be-Determined) The amount of gas to use for the transaction (unused gas is refunded). - - `gasPrice`: `Number|String|BigNumber` - (optional, default: To-Be-Determined) The price of gas for this transaction in wei, defaults to the mean network gas price. - - `data`: `String` - (optional) Either a [byte string](https://github.com/ethereum/wiki/wiki/Solidity,-Docs-and-ABI) containing the associated data of the message, or in the case of a contract-creation transaction, the initialisation code. - - `nonce`: `Number` - (optional) Integer of a nonce. This allows to overwrite your own pending transactions that use the same nonce. -2. `Number|String` - (optional) If you pass this parameter it will not use the default block set with [web3.eth.defaultBlock](#web3ethdefaultblock). -3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - The 32 Bytes transaction hash as HEX string. - -If the transaction was a contract creation use [web3.eth.getTransactionReceipt()](#web3gettransactionreceipt) to get the contract address, after the transaction was mined. - -##### Example - -```js - -// compiled solidity source code using https://chriseth.github.io/cpp-ethereum/ -var code = "603d80600c6000396000f3007c01000000000000000000000000000000000000000000000000000000006000350463c6888fa18114602d57005b600760043502 -8060005260206000f3"; - -web3.eth.sendTransaction({data: code}, function(err, address) { - if (!err) - console.log(address); // "0x7f9fade1c0d57a7af66ab4ead7c2eb7b11a91385" -}); -``` - -*** - -#### web3.eth.call - - web3.eth.call(callObject [, defaultBlock] [, callback]) - -Executes a message call transaction, which is directly executed in the VM of the node, but never mined into the blockchain. - -##### Parameters - -1. `Object` - A transaction object see [web3.eth.sendTransaction](#web3ethsendtransaction), with the difference that for calls the `from` property is optional as well. -2. `Number|String` - (optional) If you pass this parameter it will not use the default block set with [web3.eth.defaultBlock](#web3ethdefaultblock). -3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - The returned data of the call, e.g. a codes functions return value. - -##### Example - -```js -var result = web3.eth.call({ - to: "0xc4abd0339eb8d57087278718986382264244252f", - data: "0xc6888fa10000000000000000000000000000000000000000000000000000000000000003" -}); -console.log(result); // "0x0000000000000000000000000000000000000000000000000000000000000015" -``` - -*** - -#### web3.eth.estimateGas - - web3.eth.estimateGas(callObject [, defaultBlock] [, callback]) - -Executes a message call or transaction, which is directly executed in the VM of the node, but never mined into the blockchain and returns the amount of the gas used. - -##### Parameters - -See [web3.eth.sendTransaction](#web3ethsendtransaction), expect that all properties are optional. - -##### Returns - -`Number` - the used gas for the simulated call/transaction. - -##### Example - -```js -var result = web3.eth.estimateGas({ - to: "0xc4abd0339eb8d57087278718986382264244252f", - data: "0xc6888fa10000000000000000000000000000000000000000000000000000000000000003" -}); -console.log(result); // "0x0000000000000000000000000000000000000000000000000000000000000015" -``` - -*** - -#### web3.eth.filter - -```js -// can be 'latest' or 'pending' -var filter = web3.eth.filter(filterString); -// OR object are log filter options -var filter = web3.eth.filter(options); - -// watch for changes -filter.watch(function(error, result){ - if (!error) - console.log(result); -}); - -// Additionally you can start watching right away, by passing a callback: -web3.eth.filter(options, function(error, result){ - if (!error) - console.log(result); -}); -``` - -##### Parameters - -1. `String|Object` - The string `"latest"` or `"pending"` to watch for changes in the latest block or pending transactions respectively. Or a filter options object as follows: - * `fromBlock`: `Number|String` - The number of the earliest block (`latest` may be given to mean the most recent and `pending` currently mining, block). By default `latest`. - * `toBlock`: `Number|String` - The number of the latest block (`latest` may be given to mean the most recent and `pending` currently mining, block). By default `latest`. - * `address`: `String` - An address or a list of addresses to only get logs from particular account(s). - * `topics`: `Array of Strings` - An array of values which must each appear in the log entries. The order is important, if you want to leave topics use `null`, e.g. `[null, '0x00...']`. - -##### Returns - -`Object` - A filter object with the following methods: - - * `filter.get()`: Returns all of the log entries that fit the filter. - * `filter.watch(callback)`: Watches for state changes that fit the filter and calls the callback. See [this note](#using-callbacks) for details. - * `filter.stopWatching()`: Stops the watch and uninstalls the filter in the node. Should always be called once it is done. - -##### Watch callback return value - -- `String` - When using the `"latest"` parameter, it returns the block hash of the last incoming block. -- `String` - When using the `"pending"` parameter, it returns a transaction hash of the last add pending transaction. -- `Object` - When using manual filter options, it returns a log object as follows: - - `logIndex`: `Number` - integer of the log index position in the block. `null` when its pending log. - - `transactionIndex`: `Number` - integer of the transactions index position log was created from. `null` when its pending log. - - `transactionHash`: `String`, 32 Bytes - hash of the transactions this log was created from. `null` when its pending log. - - `blockHash`: `String`, 32 Bytes - hash of the block where this log was in. `null` when its pending. `null` when its pending log. - - `blockNumber`: `Number` - the block number where this log was in. `null` when its pending. `null` when its pending log. - - `address`: `String`, 32 Bytes - address from which this log originated. - - `data`: `String` - contains one or more 32 Bytes non-indexed arguments of the log. - - `topics`: `Array of Strings` - Array of 0 to 4 32 Bytes `DATA` of indexed log arguments. (In *solidity*: The first topic is the *hash* of the signature of the event (e.g. `Deposit(address,bytes32,uint256)`), except you declared the event with the `anonymous` specifier.) - -**Note** For event filter return values see [Contract Events](#contract-events) - -##### Example - -```js -var filter = web3.eth.filter('pending'); - -filter.watch(function (error, log) { - console.log(log); // {"address":"0x0000000000000000000000000000000000000000", "data":"0x0000000000000000000000000000000000000000000000000000000000000000", ...} -}); - -// get all past logs again. -var myResults = filter.get(); - -... - -// stops and uninstalls the filter -filter.stopWatching(); - -``` - -*** - -#### web3.eth.contract - - web3.eth.contract(abiArray) - -Creates a contract object for a solidity contract, which can be used to initiate contracts on an address. -You can read more about events [here](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI#example-javascript-usage). - -##### Parameters - -1. `Array` - ABI array with descriptions of functions and events of the contract. - -##### Returns - -`Object` - A contract object, which can be initiated as follows: - -```js -var MyContract = web3.eth.contract(abiArray); - -// instantiate from an existing address -var myContractInstance = MyContract.at(myContractAddress); - -// Create the contract async -var myContract = MyContract.new(param1, param2, { - data: myContractCode, - gas: 300000, - from: mySenderAddress}, function(err, contract){ - if(!err) { - // The callback will fire after the contract is mined - // Note that the returned "myContract" === "myContractInstance" - console.log(myContractInstance.address) // "0xc4abd0339eb8d57087278718986382264244252f" - console.log(myContractInstance.transactionHash) // The hash of the transaction, which created the contract - } - }); - -// Create contract sync: Then the address will be added as soon as the contract is mined. -// Additionally you can watch the transaction by using the "transactionHash" property -var myContractInstance = MyContract.new(param1, param2, {data: myContractCode, gas: 300000, from: mySenderAddress}); -myContractInstance.transactionHash // The hash of the transaction, which created the contract -myContractInstance.address // undefined at start, but will be auto-filled later -``` - -##### Example - -```js -// contract abi -var abi = [{ - name: 'myConstantMethod', - type: 'function', - constant: true, - inputs: [{ name: 'a', type: 'string' }], - outputs: [{name: 'd', type: 'string' }] -}, { - name: 'myStateChangingMethod', - type: 'function', - constant: false, - inputs: [{ name: 'a', type: 'string' }, { name: 'b', type: 'int' }], - outputs: [] -}, { - name: 'myEvent', - type: 'event', - inputs: [{name: 'a', type: 'int', indexed: true},{name: 'b', type: 'bool', indexed: false] -}]; - -// creation of contract object -var MyContract = web3.eth.contract(abi); - -// initiate contract for an address -var myContractInstance = MyContract.at('0xc4abd0339eb8d57087278718986382264244252f'); - -// call constant function -var result = myContractInstance.myConstantMethod('myParam'); -console.log(result) // '0x25434534534' - -// send a transaction to a function -myContractInstance.myStateChangingMethod('someParam1', 23, {value: 200, gas: 2000}); - -// short hand style -web3.eth.contract(abi).at(address).myAwesomeMethod(...); - -// create filter -var filter = myContractInstance.myEvent({a: 5}, function (error, result) { - if (!error) - console.log(result); - /* - { - address: '0x8718986382264244252fc4abd0339eb8d5708727', - topics: "0x12345678901234567890123456789012", "0x0000000000000000000000000000000000000000000000000000000000000005", - data: "0x0000000000000000000000000000000000000000000000000000000000000001", - ... - } - */ -}); -``` - -*** - -#### Contract Methods - -```js -// Automatically determines the use of call or sendTransaction based on the method type -myContractInstance.myMethod(param1 [, param2, ...] [, transactionObject] [, callback]); - -// Explicitly calling this method -myContractInstance.myMethod.call(param1 [, param2, ...] [, transactionObject] [, callback]); - -// Explicitly sending a transaction to this method -myContractInstance.myMethod.sendTransaction(param1 [, param2, ...] [, transactionObject] [, callback]); -``` - -The contract object exposes the contracts methods, which can be called using parameters and a transaction object. - -##### Parameters - -- `String|Number` - (optional) Zero or more parameters of the function. -- `Object` - (optional) The (previous) last parameter can be a transaction object, see [web3.eth.sendTransaction](#web3ethsendtransaction) parameter 1 for more. -- `Function` - (optional) If you pass a callback as the last parameter the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - If its a call the result data, if its a send transaction a created contract address, or the transaction hash, see [web3.eth.sendTransaction](#web3ethsendtransaction) for details. - - -##### Example - -```js -// creation of contract object -var MyContract = web3.eth.contract(abi); - -// initiate contract for an address -var myContractInstance = MyContract.at('0x78e97bcc5b5dd9ed228fed7a4887c0d7287344a9'); - -var result = myContractInstance.myConstantMethod('myParam'); -console.log(result) // '0x25434534534' - -myContractInstance.myStateChangingMethod('someParam1', 23, {value: 200, gas: 2000}, function(err, result){ ... }); -``` - -*** - - -#### Contract Events - -```js -var event = myContractInstance.MyEvent({valueA: 23}, additionalFilterObject) - -// watch for changes -event.watch(function(error, result){ - if (!error) - console.log(result); -}); - -// Or pass a callback to start watching immediately -var event = myContractInstance.MyEvent({valueA: 23}, additionalFilterObject, function(error, result){ - if (!error) - console.log(result); -}); - -``` - -You can use events like [filters](#web3ethfilter) and they have the same methods, but you pass different objects to create the event filter. - -##### Parameters - -1. `Object` - Indexed return values you want to filter the logs by, e.g. `{'valueA': 1, 'valueB': [myFirstAddress, mySecondAddress]}`. By default all filter values are set to `null`. It means, that they will match any event of given type sent from this contract. -2. `Object` - Additional filter options, see [filters](#web3ethfilter) parameter 1 for more. By default filterObject has field 'address' set to address of the contract. Also first topic is the signature of event. - -##### Callback return - - -`Object` - An event object as follows: - -- `args`: `Object` - The arguments coming from the event. -- `event`: `String` - The event name. -- `logIndex`: `Number` - integer of the log index position in the block. -- `transactionIndex`: `Number` - integer of the transactions index position log was created from. -- `transactionHash`: `String`, 32 Bytes - hash of the transactions this log was created from. -- `address`: `String`, 32 Bytes - address from which this log originated. -- `blockHash`: `String`, 32 Bytes - hash of the block where this log was in. `null` when its pending. -- `blockNumber`: `Number` - the block number where this log was in. `null` when its pending. - - -##### Example - -```js -var MyContract = web3.eth.contract(abi); -var myContractInstance = MyContract.at('0x78e97bcc5b5dd9ed228fed7a4887c0d7287344a9'); - -// watch for an event with {some: 'args'} -var myEvent = myContractInstance.MyEvent({some: 'args'}, {fromBlock: 0, toBlock: 'latest'}); -myEvent.watch(function(error, result){ - ... -}); - -// would get all past logs again. -var myResults = myEvent.get(); - -... - -// would stop and uninstall the filter -myEvent.stopWatching(); -``` - -*** - -#### web3.eth.getCompilers - - web3.eth.getCompilers([callback]) - -Gets a list of available compilers. - -##### Parameters - -1. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Array` - An array of strings of available compilers. - -##### Example - -```js -var number = web3.eth.getCompilers(); -console.log(number); // ["lll", "solidity", "serpent"] -``` - -*** - -#### web3.eth.compile.solidity - - web3.eth.compile.solidity(sourceString [, callback]) - -Compiles solidity source code. - -##### Parameters - -1. `String` - The solidity source code. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Object` - Contract and compiler info. - - -##### Example - -```js -var source = "" + - "contract test {\n" + - " function multiply(uint a) returns(uint d) {\n" + - " return a * 7;\n" + - " }\n" + - "}\n"; -var compiled = web3.eth.compile.solidity(source); -console.log(compiled); -// { - "test": { - "code": "0x605280600c6000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa114602e57005b60376004356041565b8060005260206000f35b6000600782029050604d565b91905056", - "info": { - "source": "contract test {\n\tfunction multiply(uint a) returns(uint d) {\n\t\treturn a * 7;\n\t}\n}\n", - "language": "Solidity", - "languageVersion": "0", - "compilerVersion": "0.8.2", - "abiDefinition": [ - { - "constant": false, - "inputs": [ - { - "name": "a", - "type": "uint256" - } - ], - "name": "multiply", - "outputs": [ - { - "name": "d", - "type": "uint256" - } - ], - "type": "function" - } - ], - "userDoc": { - "methods": {} - }, - "developerDoc": { - "methods": {} - } - } - } -} -``` - -*** - -#### web3.eth.compile.lll - - web3. eth.compile.lll(sourceString [, callback]) - -Compiles LLL source code. - -##### Parameters - -1. `String` - The LLL source code. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - The compiled LLL code as HEX string. - - -##### Example - -```js -var source = "..."; - -var code = web3.eth.compile.lll(source); -console.log(code); // "0x603880600c6000396000f3006001600060e060020a600035048063c6888fa114601857005b6021600435602b565b8060005260206000f35b600081600702905091905056" -``` - -*** - -#### web3.eth.compile.serpent - - web3.eth.compile.serpent(sourceString [, callback]) - -Compiles serpent source code. - -##### Parameters - -1. `String` - The serpent source code. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - The compiled serpent code as HEX string. - - -```js -var source = "..."; - -var code = web3.eth.compile.serpent(source); -console.log(code); // "0x603880600c6000396000f3006001600060e060020a600035048063c6888fa114601857005b6021600435602b565b8060005260206000f35b600081600702905091905056" -``` - -*** - -#### web3.eth.namereg - - web3.eth.namereg - -Returns GlobalRegistrar object. - -##### Usage - -see [namereg](https://github.com/ethereum/web3.js/blob/master/example/namereg.html) example - -*** - -### web3.db - -#### web3.db.putString - - web3.db.putString(db, key, value) - -This method should be called, when we want to store a string in the local leveldb database. - -##### Parameters - -1. `String` - The database to store to. -2. `String` - The name of the store. -3. `String` - The string value to store. - -##### Returns - -`Boolean` - `true` if successfull, otherwise `false`. - -##### Example - - param is db name, second is the key, and third is the string value. -```js -web3.db.putString('testDB', 'key', 'myString') // true -``` - -*** - -#### web3.db.getString - - web3.db.getString(db, key) - -This method should be called, when we want to get string from the local leveldb database. - -##### Parameters - -1. `String` - The database string name to retrieve from. -2. `String` - The name of the store. - -##### Returns - -`String` - The stored value. - -##### Example - param is db name and second is the key of string value. -```js -var value = web3.db.getString('testDB', 'key'); -console.log(value); // "myString" -``` - -*** - -#### web3.db.putHex - - web3.db.putHex(db, key, value) - -This method should be called, when we want to store binary data in HEX form in the local leveldb database. - -##### Parameters - -1. `String` - The database to store to. -2. `String` - The name of the store. -3. `String` - The HEX string to store. - -##### Returns - -`Boolean` - `true` if successfull, otherwise `false`. - -##### Example -```js -web3.db.putHex('testDB', 'key', '0x4f554b443'); // true - -``` - -*** - -#### web3.db.getHex - - web3.db.getHex(db, key) - -This method should be called, when we want to get a binary data in HEX form from the local leveldb database. - -##### Parameters - -1. `String` - The database to store to. -2. `String` - The name of the store. - -##### Returns - -`String` - The stored HEX value. - - -##### Example - param is db name and second is the key of value. -```js -var value = web3.db.getHex('testDB', 'key'); -console.log(value); // "0x4f554b443" -``` - -*** - -### web3.shh - -[Whisper Overview](https://github.com/ethereum/wiki/wiki/Whisper-Overview) - -##### Example - -```js -var shh = web3.shh; -``` - -*** - -#### web3.shh.post - - web3.shh.post(object [, callback]) - -This method should be called, when we want to post whisper message to the network. - -##### Parameters - -1. `Object` - The post object: - - `from`: `String`, 60 Bytes HEX - (optional) The identity of the sender. - - `to`: `String`, 60 Bytes HEX - (optional) The identity of the receiver. When present whisper will encrypt the message so that only the receiver can decrypt it. - - `topics`: `Array of Strings` - Array of topics `Strings`, for the receiver to identify messages. - - `payload`: `String|Number|Object` - The payload of the message. Will be autoconverted to a HEX string before. - - `priority`: `Number` - The integer of the priority in a rang from ... (?). - - `ttl`: `Number` - integer of the time to live in seconds. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Boolean` - returns `true` if the message was send, otherwise `false`. - - -##### Example - -```js -var identity = web3.shh.newIdentity(); -var topic = 'example'; -var payload = 'hello whisper world!'; - -var message = { - from: identity, - topics: [topic], - payload: payload, - ttl: 100, - workToProve: 100 // or priority TODO -}; - -web3.shh.post(message); -``` - -*** - -#### web3.shh.newIdentity - - web3.shh.newIdentity([callback]) - -Should be called to create new identity. - -##### Parameters - -1. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -`String` - A new identity HEX string. - - -##### Example - -```js -var identity = web3.shh.newIdentity(); -console.log(identity); // "0xc931d93e97ab07fe42d923478ba2465f283f440fd6cabea4dd7a2c807108f651b7135d1d6ca9007d5b68aa497e4619ac10aa3b27726e1863c1fd9b570d99bbaf" -``` - -*** - -#### web3.shh.hasIdentity - - web3.shh.hasIdentity(identity, [callback]) - -Should be called, if we want to check if user has given identity. - -##### Parameters - -1. `String` - The identity to check. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Boolean` - returns `true` if the identity exists, otherwise `false`. - - -##### Example - -```js -var identity = web3.shh.newIdentity(); -var result = web3.shh.hasIdentity(identity); -console.log(result); // true - -var result2 = web3.shh.hasIdentity(identity + "0"); -console.log(result2); // false -``` - -*** - -#### web3.shh.newGroup - -##### Example -```js -// TODO: not implemented yet -``` - -*** - -#### web3.shh.addToGroup - -##### Example -```js -// TODO: not implemented yet -``` - -*** - -#### web3.shh.filter - -```js -var filter = web3.shh.filter(options) - -// watch for changes -filter.watch(function(error, result){ - if (!error) - console.log(result); -}); -``` - -Watch for incoming whisper messages. - -##### Parameters - -1. `Object` - The filter options: - * `topics`: `Array of Strings` - Filters messages by this topic(s). You can use the following combinations: - - `['topic1', 'topic2'] == 'topic1' && 'topic2'` - - `['topic1', ['topic2', 'topic3']] == 'topic1' && ('topic2' || 'topic3')` - - `[null, 'topic1', 'topic2'] == ANYTHING && 'topic1' && 'topic2'` -> `null` works as a wildcard - * `to`: Filter by identity of receiver of the message. If provided and the node has this identity, it will decrypt incoming encrypted messages. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Callback return - -`Object` - The incoming message: - - - `from`: `String`, 60 Bytes - The sender of the message, if a sender was specified. - - `to`: `String`, 60 Bytes - The receiver of the message, if a receiver was specified. - - `expiry`: `Number` - Integer of the time in seconds when this message should expire (?). - - `ttl`: `Number` - Integer of the time the message should float in the system in seconds (?). - - `sent`: `Number` - Integer of the unix timestamp when the message was sent. - - `topics`: `Array of String` - Array of `String` topics the message contained. - - `payload`: `String` - The payload of the message. - - `workProved`: `Number` - Integer of the work this message required before it was send (?). \ No newline at end of file diff --git a/pages/other-languages/[Japanese]-License.md b/pages/other-languages/[Japanese]-License.md deleted file mode 100644 index ce643a3ab..000000000 --- a/pages/other-languages/[Japanese]-License.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -name: License -category: ---- - -Overview - -The Ethereum Foundation ensures three principles concerning the funds it uses to develop Ethereum: - -- it is both open source software and Free software after the definition of the Free Software Foundation (so-called FOSS); -- no special treatment is given to any single entity concerning the copyright of the software, the Foundation included; -- source-code will not be distributed ahead of binaries. - -However, this is not where the story ends; there are many different licences available that conform to these rules. After considerable discussion, both internal and external together with The Ethereum software collection is distributed under several licences, partly to reflect the different thinking of the minds behind different pieces of software and partly to reflect the need to adapt to real-world issues and opportunities and lay out a strategy to provide the best possible future for the Ethereum community. - -### The Core - -Ethereum の core (核となる部分)には、分散型大衆決定マシンのエンジンとネットワークを担うコードとethereumをサポートする -全てのライブラリが含まれています。: -* libethereum -* libp2p -* libdevcore -* libethcore -* livevm -* libevmface - -Ethereum core は、最もライセンスフリーである概念のもとでリリース予定であり、できるだけ多様な環境で Ethereum が使用されること願っております。閉鎖的な環境においてリリースされる、修正や拡張が必要な場合においても、同様に、フリーソフトとして使用していただくことを願っております。 - -In this way, while we have not arrived at a final licence, we expect to select one of the MIT licence, the MPL licence or the LGPL licence. If the latter is chosen, it will come with an amendment allowing it to be linked to be statically linked to software for which source code is not available. - -In this way, the core of Ethereum, be it C++ or Go, will be available for use in any commercial environment, closed or open source. - -### The Applications - -Ethereum の application は以下を含め、GNUライセンスのもとで配布予定です。 -* Solidityコンパイラ ( Libsolidity , solc ) -* AlethZero -* Mix - -This is to reflect the fact that these pieces of software tend to not, by nature, need to be amalgamated or augmented into a larger, closed-source, whole. There is however, much to be gained through many different members of the Ethereum-community being incentivised to develop on and build out such software. - -In this way we hope our initial version of Solidity and Mix lay down the foundation for others to build upon and improve in the true Free/open-source software manner. - -### The Middleware - -Ethereum の middleware は、以下の3つを含み、Affero licence のもとで配布予定です。これはLGPライセンスの一種のようなものです。 -* Javascriptで書かれた ethereum.js -* webthree libraries -* eth (command line client) - -We wish to allow free development of technologies by allowing linking to arbitrary software, but again would like to incentivise feeding of back-end integration work back into the community, especially regarding the interoperability with legacy systems. \ No newline at end of file diff --git a/pages/other-languages/[Japanese]-Solidity-Tutorial.md b/pages/other-languages/[Japanese]-Solidity-Tutorial.md deleted file mode 100644 index 8d7838d55..000000000 --- a/pages/other-languages/[Japanese]-Solidity-Tutorial.md +++ /dev/null @@ -1,954 +0,0 @@ ---- -name: Solidity Tutorial -category: ---- - -- [Cheat Sheet](#cheatsheet) -- [Tips and Tricks](#tips-and-tricks) - - - - -Solidity は、構文がJavaScriptとよく似た高級言語で、 -EVM(イーサリアム仮想マシン)上で動くコードへとコンパイルされるために設計されました。 -この項では、Solidityの基礎事項を抑え、EVMの知識を深めます。 -より詳細な事項については[Solidity 特記事項(建設中)]()を参照して下さい。 -また、この項では、非開発者向けの言語で書かれておらず、さらに安定版を確約するものでもありません。 - -オンライン・エミュレーターはこちら: - [Solidity in your browser](http://chriseth.github.io/cpp-ethereum), -このリンクはコンパイルのみをサポートしています。 -Contract を実際に走らせたり、Blockchain 上に埋め込んだりするには、 -Alethzero (cpp-client) 等をご使用ください。 - - -## Simple Example - -``` -contract SimpleStorage { - uint storedData; - function set(uint x) { - storedData = x; - } - function get() constant returns (uint retVal) { - return storedData; - } -} -``` -`uint storedData` は、`uint`型の `storedData`という呼び名の状態変数を宣言します。 -(`uint`: unsigned integer of 256 bits) -この変数のアドレス領域はコンパイラによって自動生成されます。 -`set`関数と`get`関数はこの値を引用したり修正したりするのに使われます。 - - -## Subcurrency Example - - -```js -contract Coin { - address minter; - mapping (address => uint) balances; - - event Send(address from, address to, uint value); - - function Coin() { - minter = msg.sender; - } - function mint(address owner, uint amount) { - if (msg.sender != minter) return; - balances[owner] += amount; - } - function send(address receiver, uint amount) { - if (balances[msg.sender] < amount) return; - balances[msg.sender] -= amount; - balances[receiver] += amount; - Send(msg.sender, receiver, amount); - } - function queryBalance(address addr) constant returns (uint balance) { - return balances[addr]; - } -} -``` - - - -このコントラクトでは少し新しい概念が出てきます。 -   - -* まず `address`型です。これは 160 bitの値で、論理数値演算できません。    -* 状態変数`balance`を見て欲しいのですが、これは複雑なデータ型から成り立っており、 -難しい言葉で言うと、`address`型から`uint`型への射(写像) ということになります。 -Mapping(写像)はハッシュテーブルのようなもので、自動的に初期化され、 -どんなkeyに対しても、初期値0(byte表記)を与えます。 -* `Coin`という関数を見てみましょう。 -コードをよく見ると、`contract Code`の中に`function Code`が定義されており、 -コンストラクタであることが見て取れます。 -コンスタラクタでありますから当然、あとでこの関数を呼び出すことはできません。 -この例では、コンストラクタにより、contract 作成者のアドレスが永久的に保存されます。    - `tx`、`block`、`msg`はグローバル変数で魔法のように場所を選びません。 -この3種類の魔法変数によって保持されるメンバにより contract の外部にアクセスすることが可能です。 -* `queryBalance`関数は`constant`宣言がされており、contractの状態を修正できないようにします。 -(まだ完全に修正不可能というわけではない、ということに注意してください) -Solidity 言語では、returns のとる引数には名前がついていて、戻り値は基本、ローカル変数を作成します。 -なので、ここでは、リターン文を記述しなくとも、 `balance = balances[addr];` と書くだけで、戻り値が返ります。 -* `Send` のような event は外部クライアントがブロックチェーンをより効率的に探索できるようにするものです。 -`send` 関数の中にあるようにして、 event が呼び起こされると、このことは、永久的にblockchain 上に保存されます。 -このことについては、あとでもう少し詳しく述べます。 - - - - -## Comments - - -一行コメント (`//`) と 複数行コメント (`/*...*/`) が使えます。 -トリプルスラッシュのコメント (`///`) を用いると、[NatSpec](https://github.com/ethereum/wiki/wiki/Natspec-Example)を導入することができますが、ここでは詳しく述べません。 - - - - -## Types - -現段階で開発済みの 基本型 は  -* booleans `bool` -* integer -* 固定長string / byte配列(bytes0 ~ bytes32) - -の3つです。 -integer は -`int8`/`uint8` から8刻みで、`int256`/`uint256` まで -`uint`/`int` は `uint256`/`int256` の alias なので、同じ型 -`address` 型は `uint160` から派生した型です。 - -Comparisons (`<=`, `!=`, `==`, etc.) の影響力の優劣は、booleans ( `&&`, `||` and `!`の組合せ) より常に小さく、 -また、`&&` and `||` に対しては、short-circuiting rules (短回路優先の法則) が成立することに注意してください。 -たとえば `(0 < 1 || fun())` では最初の命題が常に真で、fun()関数は永遠に呼ばれません。 - -もし、演算子が違う型に適用されたら、 -コンパイラは暗黙のうちに一方を別の演算子へ変換しようとします (代入演算子に関してもあてはまります)。 -一般論としては、この暗黙変換が適用されるのは、構文がしっかりとしているときで、情報は失われません。: -`uint8` は `uint16` ・ `int120` ・ `int256` に変換可能ですが `int8` から `uint256` へはできません。 -さらに、unsigned integers は 同等もしくはそれ以上 のサイズの bytes へ変換可ですが、その逆は不可です。 -`uint160` へ変換可能な型は `address` 型への変換可となります。 - - -コンパイラが暗黙変換を許さない状況であっても、 -あなたが何をしているのか把握している状況では、 -例えば以下のような型変換が可能です。 - -```js -int8 y = -3; -uint x = uint(y); -``` - -この断片的なソースコードにおける `x` の最終状態は、`0xfffff..fd` (64桁の16進コード) となります。 -これは 256 bit の2進数表現における -3 です。 - -変数の型を常に外部で特定する必要はなく、コンパイラが自動的に、その変数が最初にでてくる代入文から、決定します。 - -```js -uint20 x = 0x123; -var y = x; -``` - -ここでは、`y` の型は `uint20` となります。 -ただし関数の引数や、戻り値に `var` は使用できません。 -integer 型と byte 型は定数として宣言できます。 - -```js -uint constant x = 32; -bytes3 constant text = "abc"; -``` - - - -## Integer Literals - -integer 式 の型は、式の計算がされたのちに、さいごに決定されます。 -次の例を見てみましょう。 - -```js -var x = 1 - 2; -``` -`1 - 2` の値は `-1` です。 これが `x` に代入され、`x` の型は `-1` を含みうる最小の型である `int8` となります。 -次にいきましょう。 -今度は少し結果が違います。 - -```js -var one = 1; -var two = 2; -var x = one - two; -``` - -ここでは、`one` と `two` は `uint8`となり、`x` に対しても同じ型が遺伝します。 -`uint8` 型の内部での引き算は、wrapping (`uint8`として処理) されるため、`x` の値は、`255` となります。 - -integer のみで表された計算式であれば、 -一時的には、256bit で表される型の最大の値すら超えることが可能です。 - -```js -var x = (0xffffffffffffffffffff * 0xffffffffffffffffffff) * 0; -``` - -ここでは、`x` は `uint` 型の `0` となります。 - - -## Ether と Time の単位 - -文字としての数値は `wei` , `finney` , `szabo` , `ether` といった単位を取ることができます。 -単位を記述しないと、単位は "wei" となります。例を挙げると、 `2 ether == 2000 finney` は `true` を返します。 -さらに、 `seconds`, `hours`, `days`, `weeks`, `years` といった単位が使用でき、 秒が基本単位となります。 -(結果として a year は常にちょうど 365 days を表します。等等) - - - -## Control Structures - -C/JapaScript 由来の、大部分の(分岐やジャンプといった)制御構造が Solidity で利用可能です。 -ただし、 `switch` と `goto` (Solidity と呼ばれることに注意) は含まれません。 -ということで、`if` , `else` , `while` , `for` , `break` , `continue` , `return` といった制御文が使えます。 -C言語やJavascriptにみられるような、非boolean型からboolean型への型変換は存在せず、 -`if (1) { ... }` は Solidity では無効なものとなります。 - - -## Function Calls - -the current contract の関数は直接呼び出すことができ、 -また再起呼び出しも可能です。 -ナンセンスな事例ですが、次をごらんください。 - -```js -contract c { - function g(uint a) returns (uint ret) { return f(); } - function f() returns (uint ret) { return g(7) + f(); } -} -``` - -`this.g(8);` という表現も関数呼び出しに有効ですが、 -この方法では、関数の呼び出しは message call を介して呼び出されるので、 -直接 jump operation 等により呼び出されるものではありません。 -他の contract の関数呼び出し時、呼び出しで使用されるガスの単価と量は特定されます。 - - -```js -contract InfoFeed { - function info() returns (uint ret) { return 42; } -} -contract Consumer { - InfoFeed feed; - function setFeed(address addr) { feed = InfoFeed(addr); } - function callFeed() { feed.info.value(10).gas(800)(); } -} -``` -`InfoFeed(addr)` という表現は、 -与えられた address 上のコントラクトの型は `InfoFeed` であると宣言し、 -外部型への変換を行い、ここにおいてコンストラクタの遂行はしません。 - -`feed.info.value(10).gas(800)` は関数呼び出しで送られるガスの値と量をローカルでsetするだけであり、 -実際の呼び出しは終わりにある括弧が遂行します。 - - -関数呼び出しにおける引数は名前で指定することができ、順番がバラバラでも構いません。 - -```js -contract c { -function f(uint key, uint value) { ... } -function g() { - f({value: 2, key: 3}); -} -} -``` - -関数や戻り宣言の仮引数名はなくても構いません。 - -```js -contract test { - function func(uint k, uint) returns(uint){ - return k; - } -} -``` - - - -## Special Variables and Functions - -デフォルトのグローバル名前空間に存在する -グローバル変数およびグローバル関数を紹介します。 - - -### Block and Transaction Properties - - - `block.coinbase` (`address`): current block miner's address - - `block.difficulty` (`uint`): current block difficulty - - `block.gaslimit` (`uint`): current block gaslimit - - `block.number` (`uint`): current block number - - `block.blockhash` (`function(uint) returns (bytes32)`): hash of the given block - - `block.timestamp` (`uint`): current block timestamp - - `msg.data` (`bytes`): complete calldata - - `msg.gas` (`uint`): remaining gas - - `msg.sender` (`address`): sender of the message (current call) - - `msg.value` (`uint`): number of wei sent with the message - - `now` (`uint`): current block timestamp (alias for `block.timestamp`) - - `tx.gasprice` (`uint`): gas price of the transaction - - `tx.origin` (`address`): sender of the transaction (full call chain) - -### Cryptographic Functions - - - `sha3(...) returns (bytes32)`: compute the SHA3 hash of the (tightly packed) arguments - - `sha256(...) returns (bytes32)`: compute the SHA256 hash of the (tightly packed) arguments - - `ripemd160(...) returns (bytes20)`: compute RIPEMD of 256 the (tightly packed) arguments - - `ecrecover(bytes32, byte, bytes32, bytes32) returns (address)`: recover public key from elliptic curve signature - - "tightly packed" :複数の引数間の余白をなくしひとまとめにできることを意味します。 -`sha3("ab", "c") == sha3("abc") == sha3(0x616263) == sha3(6382179) = sha3(97, 98, 99)`。 -もし余白が必要ならば、外部型変換が利用可能です。 - -注意事項として、プライベート・ブロックチェーン上においては、`sha256` 、`ripemd160` あるいは `ecrecover` はガス欠になりえます。 -というのは、コントラクトは最初いわゆるプリ・コンパイルされた contract としてコンパイルされ、コントラクトは最初の message を受信してはじめて存在することとなるからです。(インスタンスが生成されるとも言います。) -存在しない(インスタンスが生成されていない)コントラクトへのメッセージはとても高くつき、このためエラーが(ガス欠が)生じるのです。 -この問題への動作対処法ははじめに、(例えば)1 Wei を暗号関数を含む各コントラクトへ送信(初期化)してから、あなたの作成したコントラクト上でそれらのコントラクトを呼び出す形をとります。 -テストネット上や、公式のブロックチェーン上では、(初期の段階であらかじめ初期化されているため、)このようなことは起こりません。 - - - -### Contract Related - - - `this` (current contract's type): the current contract, explicitly convertible to `address` - - `suicide(address)`: suicide the current contract, sending its funds to the given address - -Furthermore, all functions of the current contract are callable directly including the current function. - -## Functions on addresses - -It is possible to query the balance of an address using the property `balance` -and to send Ether (in units of wei) to an address using the `send` function: - -```js -address x = 0x123; -if (x.balance < 10 && address(this).balance >= 10) x.send(10); -``` - -Beware that if `x` is a contract address, its code will be executed together with the `send` call (this is a limitation of the EVM and cannot be prevented). If that execution runs out of gas or fails in any way, the Ether transfer will be reverted. In this case, `send` returns `false`. - -Furthermore, to interface with contracts that do not adhere to the ABI (like the classic NameReg contract), -the function `call` is provided which takes an arbitrary number of arguments of any type. These arguments are ABI-serialized (i.e. also padded to 32 bytes). One exception is the case where the first argument is encoded to exactly four bytes. In this case, it is not padded to allow the use of function signatures here. - -```js -address nameReg = 0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2; -nameReg.call("register", "MyName"); -nameReg.call(bytes4(sha3("fun(uint256)")), a); -``` - -`call` returns a boolean indicating whether the invoked function terminated (`true`) or caused an EVM exception (`false`). It is not possible to access the actual data returned (for this we would need to know the encoding and size in advance). - -In a similar way, the function `callcode` can be used: The difference is that only the code of the given address is used, all other aspects (storage, balance, ...) are taken from the current contract. The purpose of `callcode` is to use library code which is stored in another contract. The user has to ensure that the layout of storage in both contracts is suitable for callcode to be used. - -Both `call` and `callcode` are very low-level functions and should only be used as a *last resort* as they break the type-safety of Solidity. - -Note that contracts inherit all members of address, so it is possible to query the balance of the -current contract using `this.balance`. - -## Order of Evaluation of Expressions - -The evaluation order of expressions is not specified (more formally, the order -in which the children of one node in the expression tree are evaluated is not -specified, but they are of course evaluated before the node itself). It is only -guaranteed that statements are executed in order and short-circuiting for -boolean expressions is done. - -## Arrays - -Both variably and fixed size arrays are supported in state and as parameters of external -functions: - -```js -contract ArrayContract { - uint[2**20] m_aLotOfIntegers; - bool[2][] m_pairsOfFlags; - function setAllFlagPairs(bool[2][] newPairs) external { - // assignment to array replaces the complete array - m_pairsOfFlags = newPairs; - } - function setFlagPair(uint index, bool flagA, bool flagB) { - // access to a non-existing index will throw an exception - m_pairsOfFlags[index][0] = flagA; - m_pairsOfFlags[index][1] = flagB; - } - function changeFlagArraySize(uint newSize) { - // if the new size is smaller, removed array elements will be cleared - m_pairsOfFlags.length = newSize; - } - function clear() { - // these clear the arrays completely - delete m_pairsOfFlags; - delete m_aLotOfIntegers; - // identical effect here - m_pairsOfFlags.length = 0; - } - bytes m_byteData; - function byteArrays(bytes data) external { - // byte arrays ("bytes") are different as they are stored without padding, - // but can be treated identical to "uint8[]" - m_byteData = data; - m_byteData.length += 7; - m_byteData[3] = 8; - delete m_byteData[2]; - } -} -``` - -## Structs - -Solidity provides a way to define new types in the form of structs, which is -shown in the following example: - -```js -contract CrowdFunding { - struct Funder { - address addr; - uint amount; - } - struct Campaign { - address beneficiary; - uint fundingGoal; - uint numFunders; - uint amount; - mapping (uint => Funder) funders; - } - uint numCampaigns; - mapping (uint => Campaign) campaigns; - function newCampaign(address beneficiary, uint goal) returns (uint campaignID) { - campaignID = numCampaigns++; // campaignID is return variable - Campaign c = campaigns[campaignID]; // assigns reference - c.beneficiary = beneficiary; - c.fundingGoal = goal; - } - function contribute(uint campaignID) { - Campaign c = campaigns[campaignID]; - Funder f = c.funders[c.numFunders++]; - f.addr = msg.sender; - f.amount = msg.value; - c.amount += f.amount; - } - function checkGoalReached(uint campaignID) returns (bool reached) { - Campaign c = campaigns[campaignID]; - if (c.amount < c.fundingGoal) - return false; - c.beneficiary.send(c.amount); - c.amount = 0; - return true; - } -} -``` - -The contract does not provide the full functionality of a crowdfunding -contract, but it contains the basic concepts necessary to understand structs. -Struct types can be used as value types for mappings and they can itself -contain mappings (even the struct itself can be the value type of the mapping, although it is not possible to include a struct as is inside of itself). Note how in all the functions, a struct type is assigned to a local variable. This does not copy the struct but only store a reference so that assignments to members of the local variable actually write to the state. - -## Assignment - -The semantics of assignment are a bit more complicated for non-value types like arrays and structs. -Assigning *to* a state variable always creates an independent copy. On the other hand, assigning to a local variable creates an independent copy only for elementary types, i.e. static types that fit into 32 bytes. If structs or arrays (including `bytes`) are assigned from a state variable to a local variable, the local variable holds a reference to the original state variable. A second assignment to the local variable does not modify the state but only changes the referenc. Assignments to members (or elements) of the local variable *do* change the state. - -## Enums - -Enums are another way to create a user-defined type in Solidity. They are explicitly convertible -to and from all integer types but implicit conversion is not allowed. The variable of enum type can be declared as constant. - -```js -contract test { - enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill } - ActionChoices choices; - ActionChoices constant defaultChoice = ActionChoices.GoStraight; - function setGoStraight() - { - choices = ActionChoices.GoStraight; - } - function getChoice() returns (uint) - { - return uint(choices); - } - function getDefaultChoice() returns (uint) - { - return uint(defaultChoice); - } -} -``` - -## Exceptions - -Currently, there are two situations, where exceptions can happen in Solidity: If you access an array beyond its length (i.e. `x[i]` where `i >= x.length`) or if a function called via a message call does not finish properly (i.e. it runs out of gas or throws an exception itself). In such cases, Solidity will trigger an "invalid jump" and thus cause the EVM to revert all changes made to the state. - -It is planned to also throw and catch exceptions manually. - -## Interfacing with other Contracts - -There are two ways to interface with other contracts: Either call a method of a contract whose address is known or create a new contract. Both uses are shown in the example below. Note that (obviously) the source code of a contract to be created needs to be known, which means that it has to come before the contract that creates it (and cyclic dependencies are not possible since the bytecode of the new contract is actually contained in the bytecode of the creating contract). - -```js -contract OwnedToken { - // TokenCreator is a contract type that is defined below. It is fine to reference it - // as long as it is not used to create a new contract. - TokenCreator creator; - address owner; - bytes32 name; - function OwnedToken(bytes32 _name) { - address nameReg = 0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2; - nameReg.call("register", _name); - owner = msg.sender; - // We do an explicit type conversion from `address` to `TokenCreator` and assume that the type of - // the calling contract is TokenCreator, there is no real way to check. - creator = TokenCreator(msg.sender); - name = _name; - } - function changeName(bytes32 newName) { - // Only the creator can alter the name -- contracts are explicitly convertible to addresses. - if (msg.sender == address(creator)) name = newName; - } - function transfer(address newOwner) { - // Only the current owner can transfer the token. - if (msg.sender != owner) return; - // We also want to ask the creator if the transfer is fine. - // Note that this calls a function of the contract defined below. - // If the call fails (e.g. due to out-of-gas), the execution here stops - // immediately (the ability to catch this will be added later). - if (creator.isTokenTransferOK(owner, newOwner)) - owner = newOwner; - } -} -contract TokenCreator { - function createToken(bytes32 name) returns (address tokenAddress) { - // Create a new Token contract and return its address. - return address(new OwnedToken(name)); - } - function changeName(address tokenAddress, bytes32 name) { - // We need an explicit type conversion because contract types are not part of the ABI. - OwnedToken token = OwnedToken(tokenAddress); - token.changeName(name); - } - function isTokenTransferOK(address currentOwner, address newOwner) returns (bool ok) { - // Check some arbitrary condition. - address tokenAddress = msg.sender; - return (sha3(newOwner) & 0xff) == (bytes20(tokenAddress) & 0xff); - } -} -``` - -## Constructor Arguments - -A Solidity contract expects constructor arguments after the end of the contract data itself. -This means that you pass the arguments to a contract by putting them after the -compiled bytes as returned by the compiler in the usual ABI format. - -## Contract Inheritance - -Solidity supports multiple inheritance by copying code including polymorphism. -Details are given in the following example. - -```js -contract owned { - function owned() { owner = msg.sender; } - address owner; -} - -// Use "is" to derive from another contract. Derived contracts can access all members -// including private functions and state variables. -contract mortal is owned { - function kill() { if (msg.sender == owner) suicide(owner); } -} - -// These are only provided to make the interface known to the compiler. -contract Config { function lookup(uint id) returns (address adr) {} } -contract NameReg { function register(bytes32 name) {} function unregister() {} } - -// Multiple inheritance is possible. Note that "owned" is also a base class of -// "mortal", yet there is only a single instance of "owned" (as for virtual -// inheritance in C++). -contract named is owned, mortal { - function named(bytes32 name) { - address ConfigAddress = 0xd5f9d8d94886e70b06e474c3fb14fd43e2f23970; - NameReg(Config(ConfigAddress).lookup(1)).register(name); - } - -// Functions can be overridden, both local and message-based function calls take -// these overrides into account. - function kill() { - if (msg.sender == owner) { - address ConfigAddress = 0xd5f9d8d94886e70b06e474c3fb14fd43e2f23970; - NameReg(Config(ConfigAddress).lookup(1)).unregister(); -// It is still possible to call a specific overridden function. - mortal.kill(); - } - } -} - -// If a constructor takes an argument, it needs to be provided in the header (or modifier-invocation-style at the constructor of the derived contract (see below)). -contract PriceFeed is owned, mortal, named("GoldFeed") { - function updateInfo(uint newInfo) { - if (msg.sender == owner) info = newInfo; - } - - function get() constant returns(uint r) { return info; } - - uint info; -} -``` - -Note that above, we call `mortal.kill()` to "forward" the destruction request. The way this is done -is problematic, as seen in the following example: -```js -contract mortal is owned { - function kill() { if (msg.sender == owner) suicide(owner); } -} -contract Base1 is mortal { - function kill() { /* do cleanup 1 */ mortal.kill(); } -} -contract Base2 is mortal { - function kill() { /* do cleanup 2 */ mortal.kill(); } -} -contract Final is Base1, Base2 { -} -``` - -A call to `Final.kill()` will call `Base2.kill` as the most derived override, but this -function will bypass `Base1.kill`, basically because it does not even know about `Base1`. -The way around this is to use `super`: -```js -contract mortal is owned { - function kill() { if (msg.sender == owner) suicide(owner); } -} -contract Base1 is mortal { - function kill() { /* do cleanup 1 */ super.kill(); } -} -contract Base2 is mortal { - function kill() { /* do cleanup 2 */ super.kill(); } -} -contract Final is Base2, Base1 { -} -``` - -If `Base1` calls a function of `super`, it does not simply call this function on one of its -base contracts, it rather calls this function on the next base contract in the final -inheritance graph, so it will call `Base2.kill()` (note that the final inheritance sequence is --- starting with the most derived contract: Final, Base1, Base2, mortal, owned). Note that the actual function that -is called when using super is not known in the context of the class where it is used, -although its type is known. This is similar for ordinary virtual method lookup. - -### Arguments for Base Constructors - -Derived contracts need to provide all arguments needed for the base constructors. This can be done at two places: - -```js -contract Base { - uint x; - function Base(uint _x) { x = _x; } -} -contract Derived is Base(7) { - function Derived(uint _y) Base(_y * _y) { - } -} -``` - -Either directly in the inheritance list (`is Base(7)`) or in the way a modifier would be invoked as part of the header of the derived constructor (`Base(_y * _y)`). The first way to do it is more convenient if the constructor argument is a constant and defines the behaviour of the contract or describes it. The second way has to be used if the constructor arguments of the base depend on those of the derived contract. - - -### Multiple Inheritance and Linearization - -Languages that allow multiple inheritance have to deal with several problems, one of them being the [Diamond Problem](https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem). Solidity follows the path of Python and uses "[C3 Linearization](https://en.wikipedia.org/wiki/C3_linearization)" to force a specific order in the DAG of base classes. This results in the desirable property of monotonicity but disallows some inheritance graphs. Especially, the order in which the base classes are given in the `is` directive is important. In the following code, Solidity will give the error "Linearization of inheritance graph impossible". -```js -contract X {} -contract A is X {} -contract C is A, X {} -``` -The reason for this is that `C` requests `X` to override `A` (by specifying `A, X` in this order), but `A` itself requests to override `X`, which is a contradiction that cannot be resolved. - -A simple rule to remember is to specify the base classes in the order from "most base-like" to "most derived". - -## Abstract Contracts - -Contract functions can lack an implementation as in the following example (note that the function declaration header is terminated by `;`). -```js -contract feline { - function utterance() returns (bytes32); -} -``` -Such contracts cannot be compiled (even if they contain implemented functions alongside non-implemented functions), but they can be used as base contracts: -```js -contract Cat is feline { - function utterance() returns (bytes32) { return "miaow"; } -} -``` -If a contract inherits from an abstract contract and does not implement all non-implemented functions by overriding, it will itself be abstract. - -## Visibility Specifiers - -Functions and state variables can be specified as being `public`, `internal` or `private`, where the default for functions is `public` and `internal` for state variables. In addition, functions can also be specified as `external`. - -`external`: External functions are part of the contract interface and they can be called from other contracts and via transactions. An external function `f` cannot be called internally (i.e. `f()` does not work, but `this.f()` works). Furthermore, all function parameters are immutable. - -`public`: Public functions are part of the contract interface and can be either called internally or via messages. For public state variables, an automatic accessor function (see below) is generated. - -`internal`: Those functions and state variables can only be accessed internally, i.e. from within the current contract or contracts deriving from it without using `this`. - -`private`: Private functions and state variables are only visible for the contract they are defined in and not in derived contracts. - -```js -contract c { - function f(uint a) private returns (uint b) { return a + 1; } - function setData(uint a) internal { data = a; } - uint public data; -} -``` - -Other contracts can call `c.data()` to retrieve the value of data in state storage, but are not able to call `f`. Contracts derived from `c` can call `setData` to alter the value of `data` (but only in their own state). - -## Accessor Functions - -The compiler automatically creates accessor functions for all public state variables. The contract given below will have a function called `data` that does not take any arguments and returns a uint, the value of the state variable `data`. The initialization of state variables can be done at declaration. - -```js -contract test { - uint public data = 42; -} -``` - -The next example is a bit more complex: - -```js -contract complex { - struct Data { uint a; bytes3 b; mapping(uint => uint) map; } - mapping(uint => mapping(bool => Data[])) public data; -} -``` - -It will generate a function of the following form: -```js -function data(uint arg1, bool arg2, uint arg3) returns (uint a, bytes3 b) -{ - a = data[arg1][arg2][arg3].a; - b = data[arg1][arg2][arg3].b; -} -``` - -Note that the mapping in the struct is omitted because there is no good way to provide the key for the mapping. - -## Fallback Functions - -A contract can have exactly one unnamed -function. This function cannot have arguments and is executed on a call to the contract if -none of the other functions matches the given function identifier (or if no data was supplied at all). - -```js -contract Test { - function() { x = 1; } - uint x; -} - -contract Caller { - function callTest(address testAddress) { - Test(testAddress).call(0xabcdefgh); // hash does not exist - // results in Test(testAddress).x becoming == 1. - } -} -``` - -## Function Modifiers - -Modifiers can be used to easily change the behaviour of functions, for example to automatically check a condition prior to executing the function. They are inheritable properties of contracts and may be overridden by derived contracts. - -```js -contract owned { - function owned() { owner = msg.sender; } - address owner; - - // This contract only defines a modifier but does not use it - it will - // be used in derived contracts. - // The function body is inserted where the special symbol "_" in the - // definition of a modifier appears. - modifier onlyowner { if (msg.sender == owner) _ } -} -contract mortal is owned { - // This contract inherits the "onlyowner"-modifier from "owned" and - // applies it to the "kill"-function, which causes that calls to "kill" - // only have an effect if they are made by the stored owner. - function kill() onlyowner { - suicide(owner); - } -} -contract priced { - // Modifiers can receive arguments: - modifier costs(uint price) { if (msg.value >= price) _ } -} -contract Register is priced, owned { - mapping (address => bool) registeredAddresses; - uint price; - function Register(uint initialPrice) { price = initialPrice; } - function register() costs(price) { - registeredAddresses[msg.sender] = true; - } - function changePrice(uint _price) onlyowner { - price = _price; - } -} -``` - -Multiple modifiers can be applied to a function by specifying them in a whitespace-separated list and will be evaluated in order. Explicit returns from a modifier or function body immediately leave the whole function, while control flow reaching the end of a function or modifier body continues after the "_" in the preceding modifier. Arbitrary expressions are allowed for modifier arguments and in this context, all symbols visible from the function are visible in the modifier. Symbols introduced in the modifier are not visible in the function (as they might change by overriding). - -## Events - -Events allow the convenient usage of the EVM logging facilities. Events are inheritable members of contracts. When they are called, they cause the arguments to be stored in the transaction's log. Up to three parameters can receive the attribute `indexed` which will cause the respective arguments to be treated as log topics instead of data. The hash of the signature of the event is one of the topics except you declared the event with `anonymous` specifier. All non-indexed arguments will be stored in the data part of the log. Example: - -```js -contract ClientReceipt { - event Deposit(address indexed _from, bytes32 indexed _id, uint _value); - function deposit(bytes32 _id) { - Deposit(msg.sender, _id, msg.value); - } -} -``` -Here, the call to `Deposit` will behave identical to -`log3(msg.value, 0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20, sha3(msg.sender), _id);`. Note that the large hex number is equal to the sha3-hash of "Deposit(address,bytes32,uint256)", the event's signature. - -### Additional Resources for Understanding Events: - -- Javascript documentation: -- Example usage of events: -- How to access them in js: - -## Layout of State Variables in Storage - -Statically-sized variables (everything except mapping and dynamically-sized array types) are laid out contiguously in storage starting from position `0`. Multiple items that need less than 32 bytes are packed into a single storage slot if possible, according to the following rules: - -- The first item in a storage slot is stored lower-order aligned. -- Elementary types use only that many bytes that are necessary to store them. -- If an elementary type does not fit the remaining part of a storage slot, it is moved to the next storage slot. -- Structs and array data always start a new slot and occupy whole slots (but items inside a struct or array are packed tightly according to these rules). - -The elements of structs and arrays are stored after each other, just as if they were given explicitly. - -Due to their unpredictable size, mapping and dynamically-sized array types use a `sha3` -computation to find the starting position of the value or the array data. These starting positions are always full stack slots. - -The mapping or the dynamic array itself -occupies an (unfilled) slot in storage at some position `p` according to the above rule (or by -recursively applying this rule for mappings to mappings or arrays of arrays). For a dynamic array, this slot stores the number of elements in the array. For a mapping, the slot is unused (but it is needed so that two equal mappings after each other will use a different hash distribution). -Array data is located at `sha3(p)` and the value corresponding to a mapping key -`k` is located at `sha3(k . p)` where `.` is concatenation. If the value is again a -non-elementary type, the positions are found by adding an offset of `sha3(k . p)`. - -So for the following contract snippet: -```js -contract c { - struct S { uint a; uint b; } - uint x; - mapping(uint => mapping(uint => S)) data; -} -``` -The position of `data[4][9].b` is at `sha3(uint256(9) . sha3(uint256(4) . uint(256(1))) + 1`. - -## Esoteric Features - -There are some types in Solidity's type system that have no counterpart in the syntax. One of these types are the types of functions. But still, using `var` it is possible to have local variables of these types: - -```js -contract FunctionSelector { - function select(bool useB, uint x) returns (uint z) { - var f = a; - if (useB) f = b; - return f(x); - } - function a(uint x) returns (uint z) { - return x * x; - } - function b(uint x) returns (uint z) { - return 2 * x; - } -} -``` - -Calling `select(false, x)` will compute `x * x` and `select(true, x)` will compute `2 * x`. - - -## Internals - the Optimizer - -The Solidity optimizer operates on assembly, so it can be and also is used by other languages. It splits the sequence of instructions into basic blocks at JUMPs and JUMPDESTs. Inside these blocks, the instructions are analysed and every modification to the stack, to memory or storage is recorded as an expression which consists of an instruction and a list of arguments which are essentially pointers to other expressions. The main idea is now to find expressions that are always equal (on every input) and combine them into an expression class. The optimizer first tries to find each new expression in a list of already known expressions. If this does not work, the expression is simplified according to rules like `constant` + `constant` = `sum_of_constants` or `X` * 1 = `X`. Since this is done recursively, we can also apply the latter rule if the second factor is a more complex expression where we know that it will always evaluate to one. Modifications to storage and memory locations have to erase knowledge about storage and memory locations which are not known to be different: If we first write to location x and then to location y and both are input variables, the second could overwrite the first, so we actually do not know what is stored at x after we wrote to y. On the other hand, if a simplification of the expression x - y evaluates to a non-zero constant, we know that we can keep our knowledge about what is stored at x. - -At the end of this process, we know which expressions have to be on the stack in the end and have a list of modifications to memory and storage. This information is stored together with the basic blocks and is used to link them. Furthermore, knowledge about the stack, storage and memory configuration is forwarded to the next block(s). If we know the targets of all JUMP and JUMPI instructions, we can build a complete control flow graph of the program. If there is only one target we do not know (this can happen as in principle, jump targets can be computed from inputs), we have to erase all knowledge about the input state of a block as it can be the target of the unknown JUMP. If a JUMPI is found whose condition evaluates to a constant, it is transformed to an unconditional jump. - -As the last step, the code in each block is completely re-generated. A dependency graph is created from the expressions on the stack at the end of the block and every operation that is not part of this graph is essentially dropped. Now code is generated that applies the modifications to memory and storage in the order they were made in the original code (dropping modifications which were found not to be needed) and finally, generates all values that are required to be on the stack in the correct place. - -These steps are applied to each basic block and the newly generated code is used as replacement if it is smaller. If a basic block is split at a JUMPI and during the analysis, the condition evaluates to a constant, the JUMPI is replaced depending on the value of the constant, and thus code like -```js -var x = 7; -data[7] = 9; -if (data[x] != x + 2) - return 2; -else - return 1; -``` -is simplified to code which can also be compiled from -```js -data[7] = 9; -return 1; -``` -even though the instructions contained a jump in the beginning. - -## Tips and Tricks - - * Use `delete` on arrays to delete all its elements. - * Use shorter types for struct elements and sort them such that short types are grouped together. This can lower the gas costs as multiple SSTORE operations might be combined into a single (SSTORE costs 5000 or 20000 gas, so this is what you want to optimise). Use the gas price estimator (with optimiser enabled) to check! - * Make your state variables public - the compiler will create [getters](#accessor-functions) for you for free. - * If you end up checking conditions on input or state a lot at the beginning of your functions, try using [modifiers](#function-modifiers) - -## Cheatsheet - -### Global Variables - - - `block.coinbase` (`address`): current block miner's address - - `block.difficulty` (`uint`): current block difficulty - - `block.gaslimit` (`uint`): current block gaslimit - - `block.number` (`uint`): current block number - - `block.blockhash` (`function(uint) returns (bytes32)`): hash of the given block - - `block.timestamp` (`uint`): current block timestamp - - `msg.data` (`bytes`): complete calldata - - `msg.gas` (`uint`): remaining gas - - `msg.sender` (`address`): sender of the message (current call) - - `msg.value` (`uint`): number of wei sent with the message - - `now` (`uint`): current block timestamp (alias for `block.timestamp`) - - `tx.gasprice` (`uint`): gas price of the transaction - - `tx.origin` (`address`): sender of the transaction (full call chain) - - `sha3(...) returns (bytes32)`: compute the SHA3 hash of the (tightly packed) arguments - - `sha256(...) returns (bytes32)`: compute the SHA256 hash of the (tightly packed) arguments - - `ripemd160(...) returns (bytes20)`: compute RIPEMD of 256 the (tightly packed) arguments - - `ecrecover(bytes32, byte, bytes32, bytes32) returns (address)`: recover public key from elliptic curve signature - - `this` (current contract's type): the current contract, explicitly convertible to `address` - - `super`: the contract one level higher in the inheritance hierarchy - - `suicide(address)`: suicide the current contract, sending its funds to the given address - - `
.balance`: balance of the address in Wei - - `
.send(uint256) returns (bool)`: send given amount of Wei to address, returns `false` on failure. - -### Function Visibility Specifiers - -```js -function myFunction() returns (bool) { - return true; -} -``` - - - `public`: visible externally and internally (creates accessor function for storage/state variables) - - `private`: only visible in the current contract - - `external`: only visible externally (only for functions) - i.e. can only be message-called (via `this.fun`) - - `internal`: only visible internally - -### Modifiers - - - `constant` for state variables: Disallows assignment (except initialisation), does not occupy storage slot. - - `constant` for functions: Disallows modification of state - this is not enforced yet. - - `anonymous` for events: Does not store event signature as topic. - - `indexed` for event parameters: Stores the parameter as topic. - -### Types - -TODO diff --git "a/pages/other-languages/[Japanese]-Whisper-\357\274\210\343\202\246\343\202\243\343\202\271\343\203\221\343\203\274\357\274\211.md" "b/pages/other-languages/[Japanese]-Whisper-\357\274\210\343\202\246\343\202\243\343\202\271\343\203\221\343\203\274\357\274\211.md" deleted file mode 100644 index e052e9520..000000000 --- "a/pages/other-languages/[Japanese]-Whisper-\357\274\210\343\202\246\343\202\243\343\202\271\343\203\221\343\203\274\357\274\211.md" +++ /dev/null @@ -1,127 +0,0 @@ ---- -name: Whisper -category: ---- - -ユースケース - -* DApps(分散形アプリ)は、互いに少量の情報を出しあう必要があり、一定時間情報を公開したまま保持する。 -例えば分散型の通貨換算所を目指すDAppでは、あるレートで通貨を売って欲しいという要求を記録するために公開された情報を利用する。 -このような使い方においては、何十分何日間と情報を公開している状態が続く。 -オファーは決して取引を強制するものではなく、ただ潜在的な取引の始まりを示唆しているだけである。 - -* 分散形アプリは、あるトランザクションにおいて究極的に協力する関係を持つために -お互いに信号を送り合う必要がある。 -例えば分散形の通貨取引所アプリは、1つの取引を作成する前に(交換所に依っては2つの取引)、 -オファーを調整するためにお互いの信号を利用する必要がある。 - -* リアルタイムではない情報を提供する必要がある、もしくは互いに -一般的な通信を行う必要がある分散形のアプリの例は、例えば小さなチャットルームの部屋だ。 - -* 分散形のアプリは、お互いのことを何も分からないがハッシュだけは分かる2つの通信者に対して -見えない通信を提供する必要がある。(全体のネットワークを通じた解析に対して合理的な拒否を行う) -不正告発者が、著名なジャーナリストにコンタクトをとり、少量の証明可能な情報をやりとりし、 -そして、何か他のプロトコル(Swarm, かもしれない)によって、大量の通信を出来るようにするある分散形のアプリかもしれない。 - -一般的にトランザクションを考えると、出来事が記された記録がなかったとしても、 -あらゆる必要な物事は、言ったことや、自動執行や、状態の変更に結びついている。 - -仕様 - -* Low-level 低位のAPIは分散形アプリにのみ提供され、ユーザーには決して提供されない。 -* Low-bandwidth 低位の通信帯は大きなデータの通信には利用されない。 -* Uncertaing-latency 不確実な遅れはRTCには利用されない -* Dark パケットを追跡するための方法は無い。 -* Typical Usage: -** Low-latency 遅延の少ないメッセージは1対1や、1対Nでのメッセージを送る際に使われる。 -** High-latency 遅延は大きいが、生存時間(TTL)の長いメッセージは、メッセージを公開する際に使用される。 -メッセージは64Kバイト未満であり、一般的には約256バイトである。 - -既存の解決策 -* UDP: APIレベルでよく似ていて、ネイティブのマルチキャスティング。生存時間は設定されておらず、セキュリティや、プライバシーの保護もない。 -* [0MQ](http://zeromq.org/): 分散形のメッセージシステム。何もプライバシーの保護機能は備わっていない。 -* [Bitmessage](https://bitmessage.org/wiki/Main_Page): P2Pのネットワーク上でのメッセージ交換システムと似ている。 -高位のプロトコルで、決まった生存期間(TTL)を持ち、スループットに対しての調整機能を持たない。 -* [TeleHash](https://github.com/telehash/telehash.org/blob/master/network.md#paths): 安全な通信を目指したRTC通信。Bittorrentの方法と似ている。(修正版Kademila Techを使用), -だが与えられたハッシュのピアーを見つけるよりも、与えられたハッシュの受信者を見つける。 -DHTを使って決定論的なルーティングを行うため、それゆえに大規模な攻撃に対しての単純で解析的なパケット解析攻撃に脆弱である、 -接続を主目的としているため、生存期間(TTL)や、非同期的な通信の公開のために作られていない。 -* [Tox](https://github.com/irungentoo/toxcore/blob/master/docs/updates/DHT.md): 高位(IM & AV チャット)の補完を目的として作られた。 - -### 基本的なデザイン - -Uses the `"shh"` protocol string of ÐΞVP2P. - -残りはもうじき公開される。一度プロトタイピングは完了した。by Gav -### トラフィック解析を出来なくすることが考慮されている。 - -(Lokiverloren より) -既に存在する位置情報が覆い隠されているインスタントメッセージサービスを目的としている全てのプロトコルは、 -ルーティングに対処するための複雑な問題を抱えている。 - -Bitmessageプロトコルでは、メッセージを匿名でネットワークに公開するが、 -適切な受信者がどうやって復号化して受け取るのかを知る必要がある(他のメッセージツールと丁度同じように)。 -だが、メッセージを保存後、ユーザーが新しいメッセージを得られたことを知る事が出来る。 -問題は全体のネットワークに公開される情報量が著しく増えるに連れて、 -理想的な状態では用意にアクセスされるべきではない暗号化された通信が全体のネットワークに公開されることだ。 - -上記のどの通信プロトコルもとりわけメッセージの出処とその行き先を隠すということについての方法がない。 -そのため、私はウィスパープロトコルの1つの主目的は送信者と受信者の位置情報を匿名化して、 -中継点からにその他、もしくは双方との接続を不可能ではないにしても難しくすることである。 - -Tor システムは2つのノードの間でお互いの位置情報を知ること無く接続を確立する事が出来るプロトコルを持っている。 -それは隠されたサービスを提供するために使われているランデブープロトコルによるものである。 -この記事の読者の大半は、既にどのようにして動くかを知っているだろう。 -だがどのようにして動いているかといえば、隠されたサービス(TCP/IP通信中のポートを聞くサーバーと同様のサービス) -が通信紹介者のノード達の間からランダムな番号を選び出す(通常は6であると筆者は思う)。 -そのためには、一般的な3-hopで届く導入者への接続を確立し、 -ユーザーが隠されたサービスとのコネクションを確立しようと望んだ時には、 -特定の公開鍵と組となる隠されたサービスへと接続しようとするリクエストを発信する必要がある。 - -どのようにしてリクエストが伝播するのかについては確かな確信が無いが、 -明らかに円形の回線かランデブー型のTor導入者のノードが、 -どのノードが回線を創りだそうとしているのかを知っていることによって、 -隠されたサービスへの接続のためのリクエストの伝播が為されている。 -一旦クライアントが有効な接続可能なランデブーノードを知れば、コネクションを確立し、 -隠されたサービスへランデブーノードを中継して、トラフィックを持つことが出来るようにリクエストを送る - -通信接続のプロトコルを隠すための実装としてあまり良いもので内容に思う。 -何故ならば、クライアントのノードとしてノード間を伝わっていくために異なるIDが必要となるためだ。 -同様の原理はEthereum にも当てはまる。 - -しかしながらランデブーを使用することによって、再度互いのことを知っているノード間の接続 -(たとえお互いのアカウントやIDや通信開始者を知らないにしても)が出来るようにし、 -3hop 回線を形成するよりも何か。 - -Tor上の出口となるノードへと繋がる回線を形成するためには、クライアントが通信中のホップのリレーのIDを知る事が危険でない -だが、そのためには、"ネットワーク内で" 位置情報を難読化するセキュリティに対しての脆弱性がある。 -貴方のルーターのIDと、貴方のEthereumのIDを結びつける(筆者は明白にイーサリウムのノードが実行する、ルーティングの機能を公開する必要があると考える。)ランデブーノードに接続する際に、あなたの位置情報をランデブーに対して公開しない。 -そしてランデブーノードは隠されたサービスの位置情報を知ることもない。 -そして、ルーターが創りだされる公開ディレクトリの情報だけを必要とするこれらの通信を確立する。 - -攻撃者にとって結果として手に入る情報ではなく、 -貴方のIPアドレスに関係するサーバーを直接調べることによって明かされてしまうかもしれない。 - -この議論に対して私は下記を述べたい。 - -1. ウィスパーのプロトコルはTorのような位置情報を匿名化するシステムを通して動く必要があると、上記の事実は示唆している。 -それだけでなく、Torが隠されたサービスのために用いているランデブープロトコルを形成する形式を用いなければならない。 - -2. しかしながら、Torは元来ウェブサーバーが貴方のIPアドレス(セッションのクッキーと記録と関連する)を記録することを防ぐための手段を第一義として設計された。そして第二義的に、TCP/IPルーティング(ポート)の通信の同様の手段を実装するための機能が付け加えられた。ランデブープロトコルを形成して位置情報を匿名化するという文脈の中で最初の目的を達成するために残った中間生成物が、3hop ノードとコネクションを利用する方法の形成へと繋がった。そしてコネクションが無いセッションのようなHTTPで使われているプロトコルよりもむしろオープンなまま残っている。 -そこで私が提言したいことは、特定のコネクションが必要であるために、そこには匿名化のプロセスを混ぜあわせる機会がある。その機会を使うことによって、悪意あるノードが攻撃者に対してデータを集めるためのトラフィックの解析があった場合に、 -コネクションを一層隠されたものに出来るのではないかということだ。 - -例えば、ブラウザとサーバー間のような通常の通信では再び接続を確立するために遅れが生じるので、通信は開いたままで -更にリクエストを送る場合にはセッションのクッキーを保管しておく。セッションのクッキーを保存しておく代わりに、クライアントが隠され隠されたノードへのコネクションの方法を変更することが出来る。 -そのコネクションでは秘密鍵を共有して通信する代わりに、多数の異なる回線を通ったデータの断片、そして受信者は断片がオリジナルのパケットを構成できる様になるまで待たなければならない。確かに(ウィスパーに関連しているだけでなく他の分散形のデータストレージプロトコルにおいても)大きな通信や、様々なパートに分かれた通信においてプロセスを取った匿名化の方法を変えることによって、一層トラフィック解析データを難読化するだろう。 - -メッセージシステムであっても、分散形のファイルシステムであっても、 -只送信されるデータの大きさに対処する必要がある違いだけで、本質的に同様の考察が当てはまる。 - -どのようにしてルーティングを進めるかを決定するための評価指標は、通信遅延だ。 -幾つかの目的に対しては通信遅延が少ないことが求められる、他のいくつかの目的に対しては、 -セキュリティが高いことの方が重要である。 -プロセスの流れの中でパーツに分類された際に、パーツから全体のパッケージへとコンバートするためには、 -全てのパーツが揃っている際にだけ出来るとすることによって、セキュリティを一層向上させる事が出来る。 -一部のパートが傍受されて、完全なメッセージでなかった際には、 -データを組み合わせることは不可能で暗号解析の目的にさえも使用することが出来ない。 \ No newline at end of file diff --git a/pages/other-languages/[Japenese]-Ethereum-TOC.md b/pages/other-languages/[Japenese]-Ethereum-TOC.md deleted file mode 100644 index 810bdab91..000000000 --- a/pages/other-languages/[Japenese]-Ethereum-TOC.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -name: 日本語版 -category: ---- - -# ようこそ Ethereum wiki へ - -この項は ÐΞV によって開発された 次世代型 P2P 技術基盤 について、全情報を集約した wiki であり、イーサリアムコミュニティによって維持されています。次世代型 P2P 技術基盤 は以下の内容を含みます。 -* **Ethereum** : スマートコントラクト開発のために一般化を施した ブロックチェイン -* **Whisper** : イーサリアムによる private low-level datagram コミュニケーション基盤 - -どなたでも GitHub にサインインすることで [browser](https://help.github.com/articles/editing-wiki-pages-via-the-online-interface) や [locally](https://help.github.com/articles/adding-and-editing-wiki-pages-locally) に記事を追加することができます。 - -## 進行状況 - -### Frontier - -Ethereum Frontier は試験段階として現在運用されています。 (2015/5/1) -Frontier についての詳細は [Vinay Gupta's blog post](https://blog.ethereum.org/2015/03/03/ethereum-launch-process/) をご覧ください。 - -## はじめに -Ethereum の基本概念の理解といたしましては [ethereum whitepaper (日本語版) ](https://github.com/ethereum/wiki/wiki/%5BJapanese%5D-White-Paper) や [設計原理 (日本語版)](https://github.com/ethereum/wiki/wiki/%5BJapanese%5D-Design-Rationale--(設計原理)) もしくは論文 [ethereum yellow paper (英語版)](http://gavwood.com/Paper.pdf) をご覧ください。またエンジニアの方は [ethereum development tutorial (日本語版)](https://github.com/ethereum/wiki/wiki/%5BJapanese%5D--Ethereum-Development-Tutorial) をご覧ください。 - -## 仕様 -- [Glossary](https://github.com/ethereum/wiki/wiki/Glossary) と [FAQ](https://github.com/ethereum/wiki/wiki/FAQ) は必ずご覧になってください。 -- [C++言語](https://github.com/ethereum/cpp-ethereum/wiki) と [Go言語](https://github.com/ethereum/go-ethereum/wiki) による実装についての wiki です。 ( Python と Javascript 言語につきましてはもうしばらくお待ちください) - -## ダウンロード -開発中ですが PoC-9 code は以下の git レポジトリの branch からダウンロード可能です: -- https://github.com/ethereum/cpp-ethereum -- https://github.com/ethereum/go-ethereum -- https://github.com/ethereum/pyethereum - -最新情報は [build server](http://build.ethdev.com/console) をご覧ください。 \ No newline at end of file diff --git a/pages/other-languages/[Persian]-Ethereum-TOC.md b/pages/other-languages/[Persian]-Ethereum-TOC.md deleted file mode 100644 index 4c37bb10d..000000000 --- a/pages/other-languages/[Persian]-Ethereum-TOC.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: Ethereum TOC -category: ---- - -### به اتریوم، نسل بعدی قراردادهای هوشمند و نرم افزارهای غیر متمرکز خوش آمدید - -[برگ سفید](https://github.com/ethereum/wiki/wiki/%5BPersian%5D-White-Paper) \ No newline at end of file diff --git a/pages/other-languages/[Romanian]-Block-Protocol-2.0.md b/pages/other-languages/[Romanian]-Block-Protocol-2.0.md deleted file mode 100644 index c59fe293b..000000000 --- a/pages/other-languages/[Romanian]-Block-Protocol-2.0.md +++ /dev/null @@ -1,205 +0,0 @@ ---- -name: Block Protocol 2.0 -category: ---- - -###Block Protocol 2.0 - -Una din principalele critici aduse Ethereum-ului, si in general protocoalelor blockchain de tipul Bitcoin, este problema scalabilitatii. Desi dezvoltatorii de baza ai Bitcoin, si ai altor platforme , cum ar fi Ripple, au continuat sa faca imbunatatiri iterative modului in care blockchain-ul este stocat, incluzand inovatii, cum ar fi separarea de starea (“registrul” sau “setul UTXO”) din lista de tranzactie sau folosind structuri separate de date pentru a stoca cele două pe disc / memorie, nimeni nu a implementat cu succes nici o modalitate de a îmbunătăți limitarea fundamentala pe care fiecare nod complet trebuie să prelucreze fiecare tranzacție. In acest punct, nici Ethereum nu rezolva aceasta problema. Totusi, protocolul block descris aici, si in special mecanismul stack trace, permite sexistenta “light nodes” sigure, care downloadeaza doar header-ele fiecarui block si nu intregul set de tranzactii, mentinand acelasi nivel de securitate pentru utilizatorii sai ca si nodurile intregi, sub asumptia gresita ca cel putin un nod cu putere de minare non-neglijabila( ie. >0.01%) sau ether din sistem este onesta. -Data definitions -Un block intreg este stocat ca: -[ - block_header, - transaction_list, - uncle_list, - stack_trace -] - -Unde: -transaction_list = [ - transaction 0, - transaction 1, - ... -] - -uncle list = [ - uncle_block_header_1, - uncle_block_header_2, - ... -] - -block_header = [ - parent hash, - number, - TRIEHASH(transaction_list), - TRIEHASH(uncle_list), - TRIEHASH(stack_trace), - coinbase address, - state_root, - difficulty, - timestamp, - extra_data, - nonce -] - -stack_trace = [ - [ medhash 0, stkhash 0 ], - [ medhash 1, stkhash 1 ], - ... -] - -Fiecare tranzactie si header al block-ului unchi este in sine furnizat direct sub forma unei liste, si nu intr-o forma serializata. uncle_list si transaction_list sunt listele header-lor block-ului unchi si ale tranzactiilor din block. Retineti ca numarul block, dificultatea si timestamp sunt numere intregi , si prin urmare nu pot incepe cu zero; extra_data si nonce pot fi multimi de cel mult 32 bytea, NU liste, desi aceasta verificare in special nu ar trebui facuta pentru block-ul geneza unde campul extra_data va ocupa multi kilobytes. - state_root este radacina Arborelui Patricia continand perechi (key/value) pentru toate conturile, unde fiecare adresa este reprezentata ca un sir binar 20-byte. La adresa fiecarui cont, valoarea stocata in arborele Merkle Patricia este un sir care este forma RLP serializata a unui obiect de forma: -[ balance, nonce, contract_root ] - -nonce este numarul de tranzactii facute din cont, si este incrementat de fiecare data cand este facuta o tranzactie. Scopul este (1) de a face fiecare tranzactie valida pentru a preveni atacurile reply, si (2) de a face imposibil (mai precis, criptografic nefezabil) construirea unui contract cu acelasi hash ca al unui contract deja existent. balance se refera la balanta contului , denominata in wei. contract_root este radacina unui alt arbore Patricia, continand memoria contractului, daca acel cont este controlat de un contract. Daca un cont nu este controlat de un contract, radacina contractului va fi doar un sir gol. -Pentru a intelege toate cele de mai sus, avem nevoie si de cateva definitii ale functiilor: -def H(x): - if len(rlp.encode(x)) < 32: return x - else: return sha3(rlp.encode(x)) - -def H20(x): - if len(rlp.encode(x)) < 20: return x - else: return sha3(rlp.encode(x))[:12] - -def adjust_difficulty(pdiff,ptime,ntime): - if ntime > ptime + 42: return pdiff - int(pdiff / 1024) - else: return pdiff + int(pdiff / 1024) - -def int_to_bin(n,bytes): - return '' if bytes == 0 else int_to_bin(int(n / 256),bytes - 1) + chr(n % 256) - -def TRIE(objs): - t = Trie() - for i in range(len(objs)): - t.insert(int_to_bin(i,32),rlp.encode(objs[i])) - return t - -def TRIEHASH(objs): - return TRIE(objs).root - -Deasemenea, dorim cateva metode pentru a ne ocupa de tries ca stack-uri -def TRIELEN(trie): - i = 0 - while trie.get(int_to_bin(i,32)): i += 1 - return i - -def TRIETOP(trie): - return trie.get(int_to_bin(TRIELEN(trie)-1,32)) - -def TRIEPOP(trie): - trie.update(int_to_bin(TRIELEN(trie)-1,32),'') - -def TRIEPUSH(trie,node): - trie.update(int_to_bin(TRIELEN(trie),3),node) - -Functia de minare este tentativa si va fi inlocuita odata ce stim ca avem alternative mai bune: -def compute_valid_nonce(header): - header[10] = 0 - while not verify_pow(header): - header[10] += 1 - return header[10] - -def verify_pow(header): - return sha3(sha3(header[:10]) + header[10]) * header[7] <= 2**256 - -Procesul de minare - -Cand se mineaza un block, minerul trece prin urmatorul proces: -1- Take as inputs -• uncle_headers – pentru a fi lista de header-e cunoscute nefolosite ale unchilor -• timestamp pentru a fi timestamp-ul curent -• parent pentru a fi block-ul parinte -• extra_data pentru ca extra data dorita sa fie adaugata block-ului -• coinbase pentru a fi adresa coinbase dorita -• txlist pentru a fi lista de tranzactii ce urmeaza a fi adaugata -2- Set: -• difficulty = adjust_difficulty(parent.difficulty,timestamp,parent.timestamp) -• reward = 15 * 10^18 (provizoriu) -• block_header = [ parent.hash, parent.number + 1, TRIEHASH(txlist), TRIEHASH(uncle_headers), 0, coinbase, 0, difficulty, timestamp, extra_data, 0 ] -3- Initializare: -• state pentru a fi starea de parinte block -• txstack = TRIE(txlist) -• stacktrace = TRIE([]) -4- In timp ce stacktrace.root != '': -• TRIEPUSH(stacktrace,[state.root,txstack.root]) -• Se aplica tranzactia TRIETOP(txstack) la state. -• TRIEPOP(txstack) -• Fie L[0] ... L[m-1] lista de tranzactii noi rezultata de acea tranzactie via MKTX, in ordinea in care au fost produse in timpul executie script. -• Initializati j = m-1. While j >= 0, TRIEPUSH(txstack,L[j]) si j -= 1 -5- Faceti urmatoarele modificari arborelui state (de stare): -• Cresteti balanta coinbase prin reward -• Pentru fiecare unchi u in uncle_headers, cresteti balanta lui u.coinbase prin reward * 13/16 si cresteti balanta lui coinbase prin reward * 1/16 -6- Completati primele doua zerouri in block_header cu state.root si TRIEHASH(stack_trace) -7- Setati nonce = compute_valid_nonce(block_header), si completati zeroul ramas in header-ul block cu valoarea lui - -Block Validation Algorithm -1- Luati ca inputs : -• block pentru a fi header-ul block -• uncle_list pentru a fi lista unchiului block -• transaction_list pentru a fi lista tranzactiei block -• stacktrace pentru a fi stack trace a block-ului -• now pentru a fi timpul actual precum e masurat de CPU-ul minerului -2- Verificati urmatoarele: -• Exista un obiect, care este un block, in baza de date cu block.prevhash ca fiind hash-ul sau? Fie parent acel block. -• Este valid proof of work-ul block-ului? -• Este valid proof of work-ul tuturor header-lor unchi? -• Sunt toti unchii unici si unchi intr-adevar? (ie. Copilul parintelui parintelui, dar nu parintele)? -• Este block.timestamp <= now + 900 and is block.timestamp >= parent.timestamp? -• Este block.number == parent.number + 1? -• Este block.difficulty == adjust_difficulty(parent.difficulty,timestamp,parent.timestamp)? -• Este block.transaction_hash = TRIEHASH(transaction_list)? -• Este block.stacktrace_hash = TRIEHASH(stacktrace)? -• Este block.uncle_hash = H(uncle_list)? -3- Initializare: -• state pentru a fi starea block a block-ului parinte -• txstack = TRIE(transaction_list) -• i = 0 -4- Fie stacktrace[k] = [ M[k], H[k] ], defaulting to '' if k is out of bounds. While i < len(stacktrace): -• Verificati daca state.root == M[i] and txstack.root == H[i] -• Aplicati transaction_list[i] la state. -• Aplicati tranzactia TRIETOP(txstack) la state. -• TRIEPOP(txstack) -• Fie L[0] ... L[m-1] lista de noi tranzactii rezultate de acea tranzactie via MKTX, in ordinea in care au fost produse in timpul executiei scriptului. -• Initializati j = m-1. While j >= 0, TRIEPUSH(txstack,L[j]) and j -= 1 -• Setati i += 1 -5- Faceti urmatoarele modificari la state: -• Cresteti balanta coinbase prin reward -• Pentru fiecaree unchi u in uncle_headers, cresteti balanta de u.coinbase prin reward * 13/16 si cresteti balanta de coinbase prin reward * 1/16 -6- Verificati daca txstack.root == '' -7- Verificati daca state.root == block.state_root -8- Daca orice verificare a esuat, returnati FALSE. Altfel, returnati TRUE. -Daca un block este valid, determinati TD(block) ("total difficulty") pentru noul block.. TD este definit recursiv prin TD(genesis_block) = 0 si TD(B) = TD(B.parent) + sum([u.difficulty for u in B.uncles]) + B.difficulty. Daca noul block are TD mai mare decat block-ul curent, setati block-ul curent la noi block-uri si continuati la urmatorul pas. In caz contrariu, iesiti. -Semi-collaborative Block Validation Via Challenge-Response Protocol -In Ethereum, un "light node"poate fi definit ca un nod care accepta header-e block, si fac verificarea in (2) cu exceptia tranzactiei si verificarilor stacktrace trie hash dar nu fac verificarea in (4) si (6), similar cu verificarea headers-only pe care light nodes o fac in Bitcoin. Light nodes ar stoca, astfel, state roots, si poate o parte a starii, insa nu in intregime. Daca un light node vrea sa stie balanta sau starea contractului unui cont oarecare, poate solicita valoarea altor noduri din retea , alaturi de subsetul minimal al nodurilor arborelui Patricia care dovedeste ca perechea key/value data este intr-adevar in stare. -Desi Ethereum nu poate functiona fara cel putin cateva noduri intregi care proceseaza si verifica fiecare tranzactie care ia loc in retea, acest block protocol este creat pentru a furniza o asigurare oarecum mai slaba: atat timp cat exista cel putin un nod intreg onest, clientii ligh (?) pot fi la fel de siguri si pot furniza aceleasi stimulente spre descentralizare precum nodurile intregi. Mecanismul se bazeaza pe un protocol provocare-raspuns in care un nod intreg poate, sub anumite conditii, sa prezinte o provocare precum o anumita parte din block este invalida, si ar depinde de miner furnizarea unui raspuns legat de ce noduri light pot fi verificate eficient. Daca o provocare ramane necontestata, atunci nodurile light s-ar indoi de acel block. -In validarea algoritmului descris in sectiunea anterioara, retineti ca exista cateva locuri specifice in care un block poate esua: -1. Una din verificarile in (2), separata de verificarea hash-ului trie al listei tranzactiei sau a hash-ului trie trace stack, esueaza. -2. Verificarea hash-ului trie al listei tranzactiei esueaza. -3. Verificarea hash-ului trie al trace stack esueaza -4.Una din verificarile din (4) esueaza pentru i=0 -5. Una din verificarile din (4) reuseste pentru toate ii care indica o tranzactie. Un raspuns trebuie sa contina (1) i, (2) j, dasca este aplicabil, (3) subsetul arborelui Patricia trebuie sa verifice valorile la i si j in trie. -Pentru (5), provocarea de invaliditate consta intr-un index k astfel incat tot pana la indexul k este valid, cu exceptia indexului k. Un raspuns consta in (1) k, (2) intrarile stack trace la k-1 si k impreuna cu subsetul arborelui Patricia pentru a le verifica, (3) un subset de noduri ale arborelui Patricia din state tree trebuie sa verifice calculul. Pentru (4), un raspuns consta doar intr-un subset de noduri ale arborelui Patricia pentru a dovedi intrarea stack trace la indexul 0, de unde doua componente pot fi verificate cu hash-ul listei tranzactiei in block header si parintele block state. Pentru (6), un raspuns functioneaza in acelasi mod ca si in (4), cu exceptia ca verificarea raspunsului necesita atat procesarea ultimei tranzactii cat si recompensarea block a unchilor si a coinbase. -Economics -Exista o imperfectiune in protocolul descris mai sus; este vulnerabil la negarea service attack. Mai exact pentru ca provocarile sunt mult mai usor de produs decat sunt raspunsurile de produs sau verificat, este posibil ca nodurile sa polueze reteaua cu provocari false, fortand nodurile light sa respinga orice block atat timp cat alte noduri sunt incapabile sa tina pasul cu verificarea. Pentru a rezolva acest lucru, introducem o rezolvare simpla:O provocare trebuie sa fie semnata de un nod care fie (1) a minat unul din ultimele 10000 de block-uri , sau (2) care detine cel putin 0.01% din tot etherul. Nodurile light ar tine apoi scoruri de calitate pentru toti peers si ii pot downgrada daca acestia prezinta o provocare ce este contracarata cu succes. Pentru ca aceasta metoda nu este anonima, cererea de inregistrare a unei dovezi de proprietate legata de blockchain adresata nodurilor nu poate fi contracarata prin reconectarea sub o alta adresa IP sau alte mecanisme asemanatoare. -Protocolul poate fi descris intr-u totul ca fiind stimulent-compatibil dupa cum urmeaza: -1. Minerii au stimulentul pentru a inregistra provocari block-urilor minate de alte noduri pentru ca daca o provocare este realizata cu succes si daca acestia mineaza block-ul urmator vor avea oportunitatea de a castiga o recompensa de 0.0625X prin includerea header-ului blocului invalid ca unchi. -2. Minerul unui block, si toti unchii din acel block, au cel putin doar stimulentul de a raspunde provocarilor. -3. Nodurile light au stimulentul de a respecta regulile de validitate ale block-ului, pentru ca toata lumea le respecta, un argument explicat mai pe larg in http://themonetaryfuture.blogspot.ca/2011/07/bitcoin-decentralization-and-nash.html. Fara protocolul provocare-raspuns, acest argument nu se aplica, din cauza costului determinarii daca un block este valid sau nu, care este prohibitiv de mare; cu protocolul , acest rationament nu se mai aplica. -4. Partenerii subtantiali (stakeholders) au stimulentul de a promova integritatea perceputa a sistemului pentru a maximiza valoarea unitatilor de valuta detinute, si astfel pot dori sa ajute activ prin introducerea de provocari si raspunsuri acolo unde este posibil. -5. Statistic vorbind, mult mai mult de 0,01% din agentii din inteeriorul agentilor economici din lumea reala, fie ca sunt motivati sau nu de puterea economica, tind sa fie motivati de considerente altruiste/ideologice.Cota de piata a organizatiilor de binefacere din intreaga lume este o dovada mai mult decat suficienta. - -Comparatia cu Bitcoin -In Bitcoin, se poate crea un protocol provocare-raspuns pentru a atinge o functionalitate similara prin cateva principii similare, dar este un singur mod cheie in care un astfel de protocol in Bitcoin ar fi inadecvat: Taxele pentru mineri. Deoarece Bitcoin nu include un mecanism Arbore-Merkle pentru adaugarea taxelor de tranzactii, singurul mod prin care se poate demonstra ca un block are o anumita suma de taxe de tranzactii este prin procesarea fiecarei tranzactii. Mai mult de atat,in Bitcoin taxele pentru tranzactii merg in totalitate la miner. Astfel, in Bitcoin un nod light nu are cum sa determine daca un anumit block este valid sau daca ii percepe creatorului sau taxe excesive, si se poate baza doar pe majoritatea calculata ca sursa de informatii. In Ethereum, toate schimbarile aduse starii sunt incorporate in stacktrace, astfel nu exista aceasta slabiciune si, avand in vedere ipoteza securitatii subrede ca cel putin un nod intreg cu minim 0.01% putere de minare este onesta, are 100% din proprietatile de securitate pe care le au nodurile intregi. - - - - - - diff --git a/pages/other-languages/[Romanian]-CLL.md b/pages/other-languages/[Romanian]-CLL.md deleted file mode 100644 index 3532dec16..000000000 --- a/pages/other-languages/[Romanian]-CLL.md +++ /dev/null @@ -1,151 +0,0 @@ ---- -name: CLL -category: ---- - -ECLL: Limbaj de programare ethereum, ce seamana cu C++. - -Scopul ECLL este de a furniza un limbaj simplu si accesibil utilizatorilor, folosit pentru a scrie contracte, dar in acelasi timp poate compila usor si eficient script-ul Ethereum. ECLL indeparteaza concepte precum indici, accesaul direct la memorie si favorizarea unei sintaxe traditionale de conditionale, bucle, matrice si variabile. Suportul pentru funcii si suportul de prima clasa pentru functii vor fi atribuite unei viitoare versiuni a acestui limbaj, denumita EHLL ("Ethereum High Level Language"), mai puternica dar mai putin eficienta. - -Specificarea va avea loc in trei parti. Prima parte va defini limbajul ca un arbore de sintaxa abstract, formalizat folosind o sintaxa S-expression, in stilul LISP; a doua parte va oferi specificatiile fiecarei operatiuni efectuate in parte, si a treia va arata cum se poate transpune AST in text. - - - -###Sintaxa arborescenta - -O expresie se defineste astfel: -- un numar e o expresie -- un nume variabil e o expresie -- `("arr" a b) `este o expresie, unde `a` si `b` sunt expresii. Aceasta este echivalentul in C `a[b]`. -- `(OP a b)` e o expresie, unde `OP` se afla in setul `(+ - * / % s/ s% ^ < > <= >= ==)` -- `(OP a)` e o expresie, unde `a` se afla in setul `(- !) ` -- Valorile speciale `tx.datan`, `tx.value`, `tx.sender`, `contract.address`, `block.number`, `block.difficulty`, `block.timestamp`, `block.parenthash` and `block.basefee` sunt expresii -- `("pseudo" a b)` este o expresie, unde `a` este o pseudomatrice and `b` este o expresie -- `("fun" a b...)` este o expresie, unde `a` este o returning function and `b...` contine numarul valid de argumente. - -O pseudofunctie se defineste astfel: -- `block.contract_storage` este o pseudofunctie - -Un pseudoarray se defineste astfel: -- `tx.data` si `contract.storage` sunt pseudomatrici -- `("pfun" a b...)` unde `a` este o pseudofunctie si `b...` contine numarul valid de argumente este o pseudomultime. -`contract.storage` este o pseudomatrice mutabila, si celelalte doua sunt pseudomatrici immutabile. - -O returning function se defineste astfel: -- `block.account_balance`, `sha256`, `sha3`, `ripemd160`, `ecvalid` sunt returning functions -- `array` este o returning function - -O multireturning function se defineste astfel: -- `ecsign` and `ecrecover` sunt multireturning functions - -O multiexpresie se defineste astfel: -- `("mfun" a b...)` unde a este o multireturning function si `b...` contine numarul valid de argumente este o multiexpresie - -O acting function este definita dupa cum urmeaza: -`mktx` este o acting function -O expresie left-hand-side se defineste astfel: -- o variabila este o expresie left-hand-side. -- `("arr" a b)` este o expresie left-hand-side, unde `a` este o expresie left-hand-side si `b` este o expresie -- `("pseudo" a b)` este o expresie left-hand-side, unde `a` este o pseudomatrice mutabila si `b` este o expresie. - -O afirmatie se defineste astfel: -- `("afun" a b...)` unde `a` este o acting function si `b...` contine numarul valid de argumente si o afirmatie -- `("set" a b)` unde `a` este o expresie left-hand-side si `b` este o expresie si o afirmatie -- `("mset" a... b)` unde `a...` este o lista de expresii left-hand-side cu numarul valid de argumente si `b` este o multiexpression si o afirmatie. -- `("seq" a...)` unde `a...` reprezinta afirmatii -- `("if" a b)` unde `a` este o expresie `b` e o afirmatie -- `("if" a1 b1 "elif" a2 b2 "elif" a3 b3 ...)` unde `ak` sunt expresii and `bk` sunt afirmatii -- `("if" a1 b1 "elif" a2 b2 "elif" a3 b3 ... "else" c)` unde `ak` sunt expresii iar `bk` si `c` sunt afirmatii -- `("while" a b)` unde `a` este o expresie si `b` este o afirmatie -- `"exit"`. - -###Definitii: - -Pre-compilarea, daca sunt `n` variabile, fiecarei variabile ii va fi repartizata un index in `[0,n-1]`. Fie `ind(x)` indexul variabilei `x`, si fie `M[x]` contractul de memorie la indexul `x` -In contextul unei expresii right-hand-side: -Aritmetica functioneaza in modul evident. `(* (+ 3 5) (+ 4 8))`, de exemplu, este returnat ca 96. - -• `a && b` este o prescurtare pentru `!(!(a) + !(b))` - -• `a || b` este o prescurtare pentru `!(!(a + b))` -• O variabila `x` trebuie sa devina `M[ind(x)]` -• `("arr" a b)` returneaza `M[M[ind(a)]+b]` -• `tx.datan` returneaza numarul de campuri de date din tranzactie. -• `("pseudo" "tx.data" i)` returneaza campul de date ith in tranzactie sau zero daca `i >= tx.datan` -• `tx.sender`, `tx.value`, `block.basefee`, `block.difficulty`, `block.timestamp`, `block.parenthash` and `contract.address` returneaza valorile evidente. -• `("pseudo "contract.storage" i)` returneaza stocarea contractului la index `i`. -• `("fun" "block.account_balance" a)` returneaza balanta adresei `a` -• `("pseudo" ("pfun" "block.contract_storage" a) b)` returneaza stocarea contractului apartinand contului `a` la indexul `b` -• `("mfun" "ecsign" hash key)` retuneaza ternarul `v,r,s` din semnatura -• `("mfun" "ecrcover" h v r s)` returneaza cheia publica `x,y` -• `("mfun" "sha256" len arr)` returneaza hash-ul SHA256 al sirului de lungimea len incepand de la `M[ind(arr)]`. La fel si `sha3` si `ripemd160work`. -• `("fun" "array")` returneaza `2^160 + M[2^256 - 1]` si seteaza `M[2^256 - 1] <- 2^160 + M[2^256 - 1]` -In contextul unei expresii left-hand-side: -• O variabila `x` returneaza `ind(x)` -• `("arr" a b)` returneaza `a + b` unde `a` si `b` au fost deja evaluate -• `("pseudo" a b)` returneaza un obiectcare, daca este setat, modifica valoarea pseudomatricei referente la indexul `a` la `b` in loc sa faca un memory set. -In contextul unei afirmatii: -• `("afun" "mktx" dest value dn ds)` creeaza o tranzactie trimitand `value` ether la `dest` cu campurile de date `dn` incepand de la `M[ind(ds)]` -• `("set" a b) sets M[a] <- b` unde `a` si `b` au fost deja evaluate -• `("mset" a... b)` seteaza secvential indexul de memorie la fiecare din valorile `a...` la o valoare din multiexpresia `b` -• `("if" a b), ("while" a b)` si derivatele vor functiona asa cum functioneaza si in alte limbaje. -###Sintaxa -• Din punct de vedere aritmetic se realizeaza folosind notatii infixe folosind C++ operator cu prioritate: `^` then `* / % s/ s%` then `+ -` then `< <= > >=` then `==` then `&&` then `||`.Adica, formulele aritmetice se vor comporta cum se comporta in mod normal; de exemplu, `(+ (* 3 5) (* x y))` ar fi `(3 * 5 + x * y)` si `(* (+ 3 5) (+ x y))` ar fi `((3 + 5) * (x + y))` -• `("arr" a b)` si `("pseudo" a b)` vor fi reprezentate de `a[b]` -• `("fun" a b...)`, `("mfun" a b...)`, `("afun" a b...)` si `("pfun" a...)` vor fi toate reprezentate ca `a(b1,b2, ... ,bn)` -• Multiexpresiile vor fi reprezentate ca `a1, a2, ... an` -• `("set" a b)` si `("mset a... b)` vor fi reprezentate ca `a = b` si respectiv `a1, a2 ...` ,`an = b`. -• `("seq" a...)` consta in fiecare din afirmatiile de pe propria linie separata -• `("if" a b)` si `("while" a b)` vor fi reprezentate ca in Python, folosind keyword-ul direct urmat de expresia pentru `a` si afirmatia indented pentru `b` -• Valorile pot fi reprezentate fie ca numere intregi sau in string quotes, in care caz vor fi tratate ca hexadecimale. -• `exit` –se iese. - -###Exemple: - -Factorial: -```python - x = 1 - n = 1 - while x < 10: - n = n * x - x = x + 1 -``` -Secventa Fibonacci: -```python - a = array() - a[0] = 1 - a[1] = 1 - i = 2 - while i < 70: - a[i] = a[i-1] + a[i-2] - i = i + 1 - mktx("0676d13c8d2cf5e9e988cc3b5f6dfb5a6a3938fa",a[69],70,a) -``` -Un exemplu real – un contract simplu de expediere pentru a crea un cont transferabil: -```python - if tx.value < tx.basefee * 200: - exit - else: - a = contract.storage[2^256 - 1] - if !(tx.sender == a) && (tx.sender > 0): - exit - if tx.data[0] == 2^160: - contract.storage[2^256 - 1] = tx.data[1] - else: - if a == 0: - contract.storage[2^256 - 1] = tx.sender - o = array() - i = 0 - while i < tx.datan - 1: - o[i] = tx.data[i+1] - i = i + 1 - mktx(tx.data[0],tx.value - tx.basefee * 250,i,o) -``` -###Sintaxa alternativa: C++ style - -• `("seq" a...)` este implementat prin separarea afirmatiilor prin semicoloane. Randurile libere sunt ignorate. -• `("if" a b)` si `("while" a b)` vor fi reprezentate ca in C++, stocand `a` intre paranteze si `b` intre acolade. - -###Sintaxa alternativa: Lisp style - -AST este utilizat ca si cod direct , cu modificarea minora urmatoare:`("fun" a b...)`, `("pfun" a b...)` si `("mfun" a b...)` sunt inlocuite cu `(a b...)`. diff --git a/pages/other-languages/[Romanian]-Cuprins.md b/pages/other-languages/[Romanian]-Cuprins.md deleted file mode 100644 index 8ea88b630..000000000 --- a/pages/other-languages/[Romanian]-Cuprins.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -name: Cuprins -category: ---- - -### Ethereum este platforma pe care se vor dezvolta aplicatii descentralizate si noua generatie de smart-contracts. - -[Raportul Ethereum (whitepaper)](https://github.com/ethereum/wiki/wiki/%5BRomanian%5D-White-Paper) - -[RLP](https://github.com/ethereum/wiki/wiki/%5BRomanian%5D-RLP), specificatii pentru prefixul liniar recursiv, folosit pentru codificarea datelor in reteaua Ethereum. - -[Patricia Tree](https://github.com/ethereum/wiki/wiki/%5BRomanian%5D-Patricia-Tree) Specificatii pentru arborele Merkle Patricia (aka Trie), structura folosita pentru stocare si hashing necesare starii blockchainului ethereum. - -[Wire protocol](https://github.com/ethereum/wiki/wiki/%5BRomanian%5D-Wire-Protocol) Specificatii. - -[Serpent](https://github.com/ethereum/wiki/wiki/%5BRomanian%5D-Serpent-programming-language-operations), un limbaj de programare high-level folosit pentru scrierea de smart-contracts. Tutorial [aici](https://github.com/ethereum/wiki/wiki/%5BRomanian%5D-Serpent-programming-language-operations). - -[LLL](https://github.com/ethereum/cpp-ethereum/wiki/LLL), Specificatii pentru limbajul low-level "Lisp-like Language" , folosit pentru definirea contractelor in clientul ethereum incepand cu PoC-3. - -[Dagger](https://github.com/ethereum/wiki/wiki/%5BRomanian%5D-Dagger), Detalii despre algoritmul "proof-of-work". - -[Block Protocol 2.0](https://github.com/ethereum/wiki/wiki/%5BRomanian%5D-Block-Protocol-2.0) - -[Layers](https://github.com/ethereum/wiki/wiki/%5BRomanian%5D-Layers) - -[Clearinghouse](https://github.com/ethereum/wiki/wiki/%5BRomanian%5D-Clearinghouse) \ No newline at end of file diff --git a/pages/other-languages/[Romanian]-Dagger.md b/pages/other-languages/[Romanian]-Dagger.md deleted file mode 100644 index 89b6ec0eb..000000000 --- a/pages/other-languages/[Romanian]-Dagger.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -name: Dagger -category: ---- - -Pe parcursul a celor peste cinci ani de experienta cu Bitcoin si alte cryptocurrencies alternative, o proprietate importanta pentru functiile proof of work ce a fost descoperita este aceaa a “ duritatii memoriei” (memory-hardness)- calcularea unui proof of work valid ar trebui sa necesite nu doar un numar mare de calcule, dar si o memorie mare. Momentan, exista trei categorii majore de functii memory-hard folosite in mining : scrypt, Primecoin mining si the birthday problem. Cu toate acestea sunt imperfecte: nici una nu necesita cantitatea de memorie pe care o cere o functie memory-hard ideala, si supefa de atacuri time-memory tradeoff, unde functia poate fi calculata cu mult mai putina memorie decat este necesar, cu costul de a sacrifica din eficienta computationala. -Dagger este un algoritm proof of work care intentioneaza sa rezolve aceste probleme, furnizand un proof of work memory-hard bazat pe pe grafice aciclice dirijate (directed acyclic graphs –DAG) conectate moderat, care , desi departe de a fi optime, are proprietati de memory-hardness mult mai puternice decat orice alternativa folosita astazi. -Why Be Memory-Hard? -Principalul motiv pentru care memory hardness este importanta este acela de a face functia proof of work rezistenta la harware specializat. Cu Bitcoin, al carui algoritm de mining necesita doar un simplu calcul SHA256, companiile care au existat timp de un an, au creat "application-specific integrated circuits" (ASICs) specializate proiectate si configurate in silicon pentru singurul scop de a calcula milioane de hash-uri SHA256 intr-o incercare de a “mina” un block Bitcoin valid. Aceste cipuri (chips) nu au aplicatii legitime in afara minarii Bitcoin si crack-uirii parolelor, si prezenta acestora, care sunt de mii de ori mai eficiente per dolar si kilowatt/ora la calcularea hash-urilor fata de genericile CPU, fac imposibila o concurenta a utilizatorilor obisnuiti care folosesc hardware generic CPU si GPU. -Aceasta dominatie a hardware-ului specializat are cateva efecte daunatoare severe: -1. Neaga aspectul democratic al distributiei minarii cryptocurrency. Intr-un ecosistem dominat de hardvare generic, faptul ca toata lumea detine un computer garanteaza faptul ca toata lumea va avea sanse egale de a castiga cel putin o parte din oferta de bani initiala. Cu hardware-ul specializat, acest factor nu mai exista;potentialul de minare al fiecarui actor economic este linear (de fapt, usor superlinear) in cantitatea lor de capital pre-existent, poate chiar exacerband inegalitati deja existente in ceea ce priveste capitalul. -2. Creste risipa de resurse. Intr-o piata eficienta,venitul marginal se apropie de costul marginal. Cum venitul din minare este o functie liniara a banilor cheltuiti pe harware-ul de minare si electricitate, implicit venitul total se apropie de costul total. Prin urmare, intr-un ecosistem dominat de hardware specializat, cantitatea de resurse irosite se apropie de 100% din nivelul de securitate al retelei. Intr-un ecosistem dominat de CPU si GPU, deoarece deja toata lumea detine un computer, nimeni nu trebuie sa achizitioneze hardware specializat pentru primele cateva hash-uri pe secunda care detin putere de minare.Deci, venitul este sublinear in cost- toata lumea primeste o parte din venit “pe gratis”. Astfel, cantitatea de resurse irosita de retea este potential mai mica decat parametrul sau de securitate. -3. Centralizeaza minarea in mainile catorva actori. (ie. Producatorii ASIC), facand 51% din atacuri posibile si cu potentialul de a deschide reteaua pentru presiuni de reglementare. -Hardware-ul specializat este atat de puternic deoarece include mii de circuite create special pentru a calcula functia proof of work, permitand hardware-ului sa realizeze aceasta functie de mii de ori in paralel. l. Memory hardness atenueaza aceasta problema stabilind ca principal factor de limitare nu puterea CPU, ci memoria. Se poate face, deasemenea, o imbunatatire modesta prin orientarea clock speed a CPU, dar masura in care astfel de optimizari pot fi facute este fundamental limitata la o valoare foarte scazuta , din considerente tehnologice. Astfel, imbunatatirea prin paralelizare intampina un obstacol: efectuarea a zece calcule memory-hard in paralel nicesita de zece ori mai multa memorie. Producatorii hardware-ului specializat pot ambala cu siguranta terabytes de memorie in dispozitivele lor, insa efectul este atenuat de doi factori. In primul rand, neprofesionistii pot atinge acelasi efect doar prin achizitionarea unor memory cards, iar in al doile arand, memoria este mult mai scumpa ca productie (daca masuram in echivalentul unui laptop) decat SHA256 chips; RAM-ul folosit in computerele obisnuite este deja optim, in esenta. -Obiectii la Memory-Hardness -1. Toti algoritmii vor fi vulnerabili la ASICs, in cele din urma. Acest punct de vedere a devenit mai popular in special dupa recentul anunt al unei companii care produce ASICs pentru Scrypt, si afirma, in esenta, ca teoretic, orice algoritm poate fi facut mai bine cu hardware specializat, asa ca nu are rost sa se incerce directionarea algoritmilor spre hardware-ul general. Ce scapa din vedere acest argument, totusi, este ca speedup-ul din aplicarea hardware-ului specializat la Scrypt-ul moderat memory-hard, a fost demonstrat ca este mult mai jos decat Bitcoin-ul. Mai mult de atat, exista motive pentru a sugera ca acest trend va continua- dupa cum am descris mai sus, memoria din hardware-ul obisnuit este mult mai aproape de un nivel optim fata de circuitele de calcul. -2. Botnets vor prelua controlul asupra procesului de minare. Acest punct poate fi abordat din doua directii: empiric si teoretic. Empiric, botnets pana acum nu au fost implicati substantial in montarea a 51% din atacuri in altcoins, in general sunt multumiti cu extragerea venitului ca mineri “legitimi”. Teoretic, prezentarea publica a botnets ca amenintare este in mare sprijinita de performanta lor in network flooding/denial a service attacks- situatie unde fiecare computer dintr-un botnet este utilizat doar pentru numarul de conexiuni pe care le poate face. In contextul minarii totusi , computerele infectate cu botnet tind sa utilizeze sisteme de operare mai vechi si au specificatii mai slabe, insemnand ca vor avea o performanta mult mai scazuta, la fel ca si impactul asupra retelei, decat sugereaza initial marimea lor. -Alternative existente -Existenta fiecarui nou algoritm, protocol cryptografic primitiv, spre deosebire de tehnologii existente si mai bine testate trebuie sa aiba intotdeauna o justificare puternica; intr-o zona atat de delicata precum cryptocurrency, prudenta este foarte importanta, atat pentru ca sistemul se va ocupa de un capital de milioane de dolari, dar si pentru ca daca se face o singura greseala, nu exista nici o modalitate de upgrade la o versiune mai noua printr-un bugfix. Scopul acestei sectiuni va fi listarea a trei alternative existente si demonstrarea ineficientei lor. -Scrypt -Scrypt este algoritmul folosit de Litecoin, Dogecoin si de majoritatea noilor cryptocurrencies aparute. Odescriere simplificata a algoritmilor asemanatori Scrypt este urmatoarea: -1. Fie H[0] = D+N unde D sta la baza datelor iar N este nonce. -2. Pentru i de la 1 la N fie H[i] = f(H[0] ... H[i-1]) unde f este o functie asemanatoare hash-urilor care ia mai multe intrari, -3. Pentru i de la 1 la M fie R[i] = random([1 ... M]) -4. SCRYPT(D,N) = f(H[R[0]] ... H[R[M]]. Daca SCRYPT(D,N) este destul de scazut, atunci N este un nonce invalid. -Ideea este ca nu exista o modalitate de a calcula practic SCRYPT(D) fara a construi intreaga multime H si de a o pastra in memorie pentru ultimul pas. Totusi, algoritmii Scrypt au o proprietate care limiteaza, in mod inerent, cat de memory-hard pot fi: verificarea necesita calcularea unei runde a intregii functii, astfel ca functia este la fel de memory-hard de verificat pe cat este de calculat. Astfel, in timp ce scrypt poate fi viabil pentru atingerea memory-hardness in jurul a catorva megabytes per theread, este un non-starter pentru memory hardness in zona sutelor de megabytes per thread. De fapt, sute de megabytes per thread sunt discutabil necesari; deja exista companii http://www.cryptocoinsnews.com/2013/11/22/alpha-technologies-offer-scrypt-mining-asics/ care lucreaza pe ASICs pentru scrypt in ziua de astazi. -Primecoin -Algoritmul Primecoin nu este creat pentru a fi memory-hard, dar are aceasta proprietate intr-o anumita masura. Algoritmul cere minerilor sa gaseasca asa-numitele lanturi Cunningham de numere prime- lanturi de forma [ n+1, 2n+1, 4n+1 ... n*2^k+1 ] pentru un k suficient de mare. Dupa cum s-a dovedit, este foarte dificil sa se faca asta pentru orice lungime semnificativa fara a completa intai o data structure cunoscuta ca sita. Avantajul Primecoin este acela ca verificarea este aproape instanta si memory-cheap; tot ce trbuie sa fac utilizatorul este sa ruleze testul primality Fermat pentru a se asigura ca toate valorile sunt numere prime. Cu toate acestea, algoritmul Primecoin are doua slabiciuni in aceasta privinta: -1. '''Time-memory tradeoff''' – un ASIC are optiunea de a inlatura mare parte din memoria necesara prin sacrificarea eficientei de calcul; chiar si cu doar 100 KB per thread un miner poate fi destul de eficient. -2. '''All clear effect''' – dupa cum s-a dovedit, este posibil ca GPU si ASIC sa aiba thread-uri multiple care sa imparta aceeasi memorie. Cum minarea Primecoin necesita ca sita sa fie umpluta doar o singura data, un ASIC poate calcula o sita intai si apoi sa ruleze mii de thread-uri prin ea. -Birthday attack -Algoritmul birthday attack este ingenios, si functioneaza dupa cum urmeaza: -1. Fie H[i] = sha256(D + N + i) pentru i de la 0 la 232 - 1 cu data D si nonce N. -2. Daca abs(H[i] - H[j]) este suficient de scazuta, atunci (N,i,j) este o solutie tripla valida. -Ingenuitatea protocolului vine din faptul ca in timp ce calculeaza eficient, birthday attack necesita stocarea hash-urilor intr-o structura astfel incat fiecare hash nou sa poata fi comparat cu cele anterioare lui, verificarea solutiilor necesita doar checking two hashes. Algoritmul este rezistent impotriva efectelor all-clear deoarece memoria trebuie eliberata (flushed) la fiecare 232 runde. Cu toate acestea, sunt cateva shortcut-uri time-memory tradeoff attacks. In primul rand, se poate optimiza prin doar prin stocarea primilor cativa bytes ai fiecarui hash in loc de primul hash. In al doilea rand, se pot stoca doar hash-uri cu primii doi bits fiind 00; acest lucru scoate din discutie 75% din solutiile posibile, reducand time efficiency de 4x,dar crescand space efficiency de 4x. In cele din urma, exista potential pentru optimizare prin examinarea diferitelor optiuni intre stocarea hash-urilor intr-un sir mare, un arbore red-black sau bianr, si alte structuri mai complexe; algoritmul optim poate fi destul de complicat. - Dagger intentioneaza sa rezolve toate aceste probleme, are o valuta ce este memory-hard pentru computer, dar este memory-easy de verificat, nu are un efect clar , nu are time-memory tradeoff, chiar si la o ratie de 1:1, and for which a close-to-optimal algorithm is the naive one. -Algorithm specification: -Esential, algoritmul Dagger functioneaza prin crearea unui grafic aciclic directionat (termenul tehnic pentru un arbore in care fiecare nod poate avea mai multi parinti) cu un total de 223 - 1 de noduri intr-o secventa. Daca minerul gaseste un nod intre indexul 222 si 223 astfel incat hash-ul rezultat sa fie sub 2256 divizat de parametrul de dificultate, rezultatul este un proof of work valid. -Fie D data de baza (eg. In cazul Bitcoin-ului, header-ul block), N fie nonce si || operatorul concatenarii sirului (ie. 'foo' || 'bar' == 'foobar') . Intregul cod pentru algoritm se desfasoara dupa cum urmeaza: -D(data,xn,0) = sha3(data) -D(data,xn,n) = - with v = sha3(data + xn + n) - L = 2 if n < 2^21 else 11 if n < 2^22 else 3 - a[k] = floor(v/n^k) mod n for 0 <= k < 2 - a[k] = floor(v/n^k) mod 2^22 for 2 <= k < L - sha3(v ++ D(data,xn,a[0]) ++ D(data,xn,a[1]) ++ ... ++ D(data,xn,a[L-1])) -Proprietati: -Obiectiv: gasirea xn, n astfel incat n > 2^22 si D(data,xn,n) < 2^256 / diff -1. Cu 228 bytes (256 MB) de memorie, algoritmul optim trebuie sa administreze D de la start la finish. -2. O potentiala problema este evaluarea lenta; parti din arbore pot fi evaluate doar in masura in care se poate reduce numarul de hash-uri necesare. Cu toate acestea, din cauza unul nod (pseudo-) aleatoriu din 225 este luat de 228 ori, putem estima statistic ca fiecare nod are un 1 / e8 rest ramas nefolosit – doar in jur de 0.03%. Astfel, beneficiul de pe urma evaluarii lente nu este substantiala. -3. Este posibil ca algoritmul sa functioneze cu mult mai putina memorie folosindu-se evaluarea lenta.Totusi, testele empirice arata ca sunt necesare intre 3000 si 25000 de hash-uri pentru calcularea unui nonce. -4. Verificarea necesita, de asemenea 3000-25000 hash-uri. -5. Pentru ca fraza 2^21 to 2^22 necesita 11 parinti, atacurile time-memory-tradeoff sunt slabite destul de sever – incercarea de a stoca 2^21 noduri in loc de 2^23 reduce uzarea memoriei cu un factor de 4, dar incetineste calcularea cu un factor de 20. Astfel, nu exista nici un time-memory tradeoff attcal, sunt necesari aproape 256 MB pentru un nivel de eficienta rezonabil. -Concluzie -Acest algoritm ofera o functie de minare proof of work cu proprietati ale mamory hardness ce nu sunt ideale, dar cu toate acestea reprezinta o imbunatatire majora fata de orice algoritm anterior. Este nevoie de 512 M pentru evaluare, 112 KB si 4078 hash-uri pentru a verifica,It takes 512 MB to evaluate, 112 KB memory and 4078 hashes to verify, and even the tinest time-memory tradeoff is not worthwhile to implement because of the bottom-level branching adjustment. These parameters allow Dagger to be much more daring in its memory requirements than Primecoin or scrypt, asking for 512 MB of RAM for a single thread. Because the primary determinant of hardness is memory, and not computation, specialized hardware has only a tiny advantage; even an optimal Dagger mining ASIC would have little to offer over a hobbyist purchasing hundreds of gigabytes of memory cards off the shelf and plugging them into a medium-power GPU. And even in such an equilibrium, mining with ordinary CPUs will likely continue to be practical. -Acknowledgements -• Thanks to Adam Back and Charles Hoskinson, for discussion and critique of earlier drafts of the protocol -• See also: Fabien Coelho's paper, in which Fabien Coelho had independently discovered a similar algorithm in 2005. diff --git a/pages/other-languages/[Romanian]-Layers.md b/pages/other-languages/[Romanian]-Layers.md deleted file mode 100644 index 00c3a18fe..000000000 --- a/pages/other-languages/[Romanian]-Layers.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -name: Layers -category: ---- - -###Layers - -Networking daemon - -Scop:networking daemon trebuie sa se poata conecta la alte noduri Ethereum, si sa accepte si sa imparta datele, pentru a servi drept coloana de sprijin pentru reteaua Ethereum. Daemon-ul in sine trebuie sa fie cat mai neutru posibil; ideal ar trebui sa fie util ca parte a oricarei valute sau protocol cryptographic fara modificari. Trebuie sa includa trasaturi anti DDoS, si poate sa mentina un running score care sa previna orice IP singur de a face mai mult de un request pe secunda. -Interfata: -1. De fiecare data cand Daemon-ul primeste un nou mesaj (i.e. H(M) nu este egal cu H(Mprev) pentru orice Mprev primit anterior), ar trebui sa trimita o cerere POST la http://localhost: containing the data, unde outputport poate fi setat in fisierul ~/.ethereum/ethereum.conf (1242 implicit, in cazul in care nu este setat) -2. the daemon should listen on port, unde inputport poate fi setat in fisierul ~/.ethereum/ethereum.conf (1243 implicit, daca nu este setat), si daca primeste un mesaj intr-un post care il solicita ar trebui sa impinga datele spre toate nodurile conectate ale retelei. Dependente: internet, noduri bootstrapping - - -Ethereum Core - -Layer de comunicare (Communication Layer) - -1.Process_network_message(sir) -> msg sau tranzactie sau block -2.Create_network_message - -IO Layer (ie. De obicei baza de date) - -1. Insert object(value) (key = sha256(value)) -2. Get object (key) -> value -Data layer -1. get_transaction -2. get_block -3. get_address_balance / nonce -4. get_contract_memory_at_index -5. get_contract_root -6. get_object (Merkle trie nodes, etc) -7. block class -8. transaction class -Manager -1. get_latest_block -2. add_block (including validation and total difficulty calculation) -3. apply_transactions_to_block (for miners) -Application Layer -1. Wallet -2. Full -3. SPV -4. Graphical block explorer -5. Miner -Clase -Clasa Block -Scop: clasa block trebuia sa poata analiza block-uri, sa le serializeze si sa poata manipula anumite operatiuni de actualizare la block-uri. -Interfata: -Interface: -1. deserialize: string -> void (constructor) -2. get_balance: number address -> number -3. get_contract_state: number address, number index -> number -4. update_balance: number address, number newbalance -> void -5. update_contract_state: number address, number index, number newvalue -> void -6. get_contract_size: number address -> number -7. serialize: void -> string -Clasa Tranzactii -Scop: clasa tranzactii trebuie sa poata analiza tranzactiile, sa le semneze si sa le serializeze. Retineti ca metoda de serializare poate esua pentru tranzactii fara semnatura, tranzactiile care sunt create intr-un block si nu sunt deserializate nu ar trebui sa fie, de fapt, serializate sau stocate, in nici o forma. -Interfata: -1. deserialize: string -> void (constructor) -2. sign: privkey -> void -3. serialize: void -> string -4. create: number address, number value, number fee, array[number] data -> void (constructor) -5. hash: void -> number -6. to, from, value, fee, data (accessible and settable member variables) diff --git a/pages/other-languages/[Romanian]-Limbajul-de-programare-Serpent.md b/pages/other-languages/[Romanian]-Limbajul-de-programare-Serpent.md deleted file mode 100644 index 4e0ed3513..000000000 --- a/pages/other-languages/[Romanian]-Limbajul-de-programare-Serpent.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -name: Limbajul de Programare Serpent -category: ---- - -###Operatiile limbajului de programare Serpent - -Aritmetica - -• Aritmetica normala functioneaza dupa cum ne asteptam:: x = 20 + 7 * 5 fixeaza x ca 55 -• Numerele negative nu exista: x = 0 - 1 seteaza x la 115792089237316195423570985008687907853269984665640564039457584007913129639935 -• Decimalele nu exista: x = 7 / 4 seteaza x la 1 -• Se poate folosi #/ si #% pentru a se putea pretinde ca numerele sunt numere intregi: x = (0-9) #/ 3 + 5 seteaza x la 2, pe cand y = (0-9) / 3 + 5seteaza y la 38597363079105398474523661669562635951089994888546854679819194669304376546647 -• Aritmetica deviaza 2^256: x = 3 ^ (2 ^ 254) setand x la 1 (aceasta este o consecinta a Teoremei Euler) -• Folositi x = y | z, x = y & z si x = y xor z pentru operatii bitwise -Variable -• Variablele functioneaza ca orice fel de limbaj : x = 25 atunci y = x + 5 seteaza y la 30 -• Folositi x = array(n) pentru a initializa o multime de valori n 32-byte -• Folositi x[i] = v pentru a seta valori in multimi si v = x[i] pentru a obtine valori in multimi -• Folositi x = bytes(n) pentru a initializa un sir/multime de bytes de n bytes -• Folositi setch(x,i,v) pentru a seta to set and v = getch(x,i) to get -• Use array literals to declare arrays inline: x = [1,2,3] -Variables are encoded into EVM code by assigning a memory index to each variable, with 32 bytes of spacing between variables. In the last example, x literally is the memory index of the start of the array, which is itself stored in a dynamically allocated slice of memory. Note that bounds-checking is not performed; array(3)[5] = 10 will have completely unknown and likely compiler-dependent consequences on code execution. -Pseudovariables -Ethereum provides the following pseudovariables and pseudoarrays: -• block.prevhash - previous block hash -• block.number - block number -• block.timestamp - block timestamp -• block.difficulty - block difficulty -• block.coinbase - address of block miner -• block.gaslimit - maximum amount of gas that can be spent in the block -• tx.gasprice - amount paid by transaction for gas -• tx.origin - original sender of transaction (NOT the sender of the current message, which is different in a nested call situation) -• tx.gas - current amount of gas remaining -• msg.datasize - length of the data provided by the message, measured as the number of complete 32-byte chunks -• msg.sender - sender of the message -• msg.value - value of the message -• contract.balance - balance of the contract -• msg.data[i] - the ith 32-byte chunk in message data -• contract.storage[i] - the contract's long term storage, at index i -Functions -• send(to, value, gas) - sends value ether to to, allowing the computation the given amount of gas. -• x = msg(to, value, gas, datastart, datalen) - sends a message to to, using the data at memory indices datastart ... datastart+datalen*32-1, with the given amount of ether and gas, and sets x to the first 32 bytes of the result. -• msg(to, value, gas, datastart, datalen, outputstart, outputlen) - sends a message toto, using the data at memory indicesdatastart ... datastart+datalen*32-1, with the given amount of ether and gas, and pastes the result to memory indicesoutputstart ... outputstart+outputlen*32-1` -• x = create(endowment, gas, datastart, datalen) - creates a new contract using code from the given indices in memory as above, and return the address of the contract -• x = sha3(v) - returns the SHA3 of the given 32-byte value -• x = byte(y,z) - sets x to the zth byte of y -A lot of these commands require data to be loaded from memory; this is actually fairly easy to manage. Consider the following equivalent examples: -x = msg(0xf345747062de4d05d897d62c4696febbedcb36b8, 10^18, tx.gas - 100, [10,20,30], 3) -And: -a = array(3) -a[0] = 10 -a[1] = 20 -a[2] = 30 -y = array(1) -msg(0xf345747062de4d05d897d62c4696febbedcb36b8, 10^18, tx.gas - 100, a, 3, y, 1) -x = y[0] -Conditionals and Loops -Best to learn by example: -if x > 5: - y = 7 -And: -x = 248 -while x > 1: - if (x % 2) == 0: - x = x / 2 - else: - x = 3 * x + 1 -Note that if x > 5: y = 7 on one line is invalid. -Comments -x = 4 //this is a comment and does not appear in the compiled code - // this also is a comment on its own line - /* this style is not supported however */ -Halting -• stop - this keyword by itself on one line stops execution -• return(x) - returns the 32 bytes of value x -• return(memstart, len) - returns the memory at indices memstart ... memstart+32*len-1 -• suicide(a) - destroys the contract, sending all remaining balance to a -Last edited by vbuterin, 3 days ago diff --git a/pages/other-languages/[Romanian]-Wire-Protocol.md b/pages/other-languages/[Romanian]-Wire-Protocol.md deleted file mode 100644 index fdab9c747..000000000 --- a/pages/other-languages/[Romanian]-Wire-Protocol.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -name: Wire Protocol -category: ---- - -###Wire Protocol - -Comunicatiile peer-to-peer intre noduri care opereaza clienti Ethereum sunt create pentru a fi guvernate de un simplu protocol wire, care utilizeaza tehnologii si standarde Ethereum existente , cum ar fi RLP, care este practic oriunde. - -Acest document are ca scop explicarea acestui tip de protocol intr-un mod comprehensibil. - -###Low-level - -Nodurile Ethereum se pot conecta intre ele doar prin TCP.Perechile (peers) sunt libere sa promoveze si sa accepte conexiuni pe orice port/porturi doresc, cu toate acestea va exista un port default -30303; pe care conexiunea poate fi ascultata si facuta. -Desi TCP furnizeaza un mediu orientat spre conexiuni, nodurile Ethereum functioneaza in termeni de pachete. Aceste pachete sunt formate ca jetoane(token) de 4 biti de sincronizare (0x22400891), 4 biti de “sarcina utila”, pentru a fi interpretate ca un intreg endian si, finalmente, o structura de date N-byte serializata RLP, unde N este “sarcina utila” mentionata mai sus. Pentru a clarifica, sarcina utila specifica numarul de biti din pachetul care “urmeaza” dupa primii 8. -Continutul sarcinei utile -Exista un numar de diferite tipuri de sarcini utile care pot fi codate in RLP. Acest “tip” este intotdeauna determinat de prima intrare a RPL, interpretata ca un numar intreg: -Hello -• `[0x00, PROTOCOL_VERSION, NETWORK_ID, CLIENT_ID, CAPABILITIES, LISTEN_PORT, NODE_ID]` -• Primul pachet trimis prin conexiune, si trimis o data de ambele parti. Nici un alt mesaj nu poate fi trimis pana cand “Hello” este primit. -• PROTOCOL_VERSION este unul dintre: -o 0x00 pentru PoC-1; -o 0x01 pentru PoC-2; -o 0x07 pentru PoC-3. -• NETWORK_ID trebuie sa fie 0. -• CLIENT_ID Specifica identitatea software-ului clientului, ca un sir lizibil (e.x."Ethereum(++)/1.0.0"). -• LISTEN_PORT specifica portul pe care asculta clientul (pe interfata pe care se efectueaza conexiunea curenta). Daca se indica 0, clientul nu asculta. -• CAPABILITIES specifica capacitatile clientului ca un set de “flags”; in prezent sunt folositi trei biti: 0x01 pentru descoperirea perechilor, 0x02 pentru relocarea tranzactiilor, 0x04 pentru interogarea block-chain-ului. -• NODE_ID este optional si specifica un hash de 512 biti, (cu potential de a fi utilizat ca public key) care identifica acest nod. - -Disconnect -• `[0x01, REASON]` -• Informeaza perechea ca o deconectare este iminenta, daca se primeste acest mesaj, perechea trebuie sa se deconecteze automat. Cand se efectueaza operatiunea de trimitere, gazdele dau perechilor o sansa de lupta (a fighting chance) (a se citi: asteptati 2 secunde) pentru a se deconecta, inainte de a se deconecta ei insisi. -• REASON este un intreg optional care specifica unul dintr-un numar de motive pentru care se efectueaza deconectarea: -• 0x00 Deconectare solicitata; -• 0x01 eroare de sub-sistem TCP; -• 0x02 Protocol incorect; -• 0x03 Pereche inutila; -• 0x04 Prea multe perechi; -• 0x05 Deja conectat; -• 0x06 Bloc geneza incorect/gresit; -• 0x07 Protocoale de retea incompatibile; -• 0x08 Clientul a renuntat. -Ping -• `[0x02]` -• Solicita un raspuns imediat la Pong de la pereche. -Pong -• `[0x03]` -• Raspunde la pachetul Ping al perechii. -GetPeers -• `[0x10]` -• Solicita perechii sa enumere cateva alte perechi cunoscute pentru ca noi sa ne putem conecta la ele. Aceasta enumerare ar trebui sa contina si perechea solicitata. -Peers -• `[0x11, [IP1, Port1, Id1], [IP2, Port2, Id2], ... ]` -• Specifica un numar de perechi cunoscute. IP este o multime de 4 biti “ABCD” care trebuie interpretata ca adresa IP A.B.C.D. Port este o multime care trebuie intrepretata ca un intreg de 16 biti endian. Id este hash-ul de 512 biti care se comporta ca unicul identificator al nodului. - Tranzactii -• `[0x12, [nonce, receiving_address, value, ... ], ... ]` -• Specifica unei tranzactii(unor tranzactii) ca perechea trebuie sa se asigure ca este inclusa in sirul tranzactiei.Elementele din lista (cele care il urmeaza primul 0x12) sunt tranzactii in formatul descris in specificatiile Ethereum principale. - Blocks -• `[0x13, [block_header, transaction_list, uncle_list], ... ]` -• Specifica block-ului/-urilor ca perechea trebuie sa stie despre (atat scria, nu inteleg despre ce e vorba). Elementele din lista (cele care il urmeaza pe primul, 0x13) sunt blocks in formatul descris in specificatiile Ethereum principale. - GetChain -• [0x14, Parent1, Parent2, ..., ParentN, Count] -• Solicita perechii sa trimita Count (a se interpreta ca numar) block-uri in block chain-ul canonic curent, care sunt copii ai Parent1 (a se interpreta ca SHA3 block hash). Daca Parent1 nu este prezent in block chain, ar trebui sa actionezeca si cum solicitarea ar fi facuta pentru Parent2 &c. pana la ParentN. Daca parintele desemnat este capul block chain-ului actual, un rapuns gol trebuie trimis.Daca nici unul dintre parinti nu sunt in block chain-ul canonic curent, NotInChain trebuie trimis impreuna cu ParentN (i.e. ultimul Parent din lista de parinti). Daca nu sunt trecuti parinti, atunci nu este necesar un raspuns. - NotInChain -• [0x15, Hash] -• Comunica perechii ca un anume hash nu a fost gasit in block chain-ul sau. - GetTransactions -• [0x16] -• Solicita perechii sa trimita toate tranzactiile aflate in acel moment in sir. Vedeti in sectiunea “Tranzactii”. -Exemple de pachete -0x22400891000000088400000043414243 -Un pachet Hello care mentioneaza ca id-ul clientului este “ABC”. -Peer 1: 0x22400891000000028102 -Peer 2: 0x22400891000000028103 -Un Ping si Pong-ul returnat. -Managementul sesiunii -Dupa conectare, toti clientii(i.e. de ambele parti ale conexiunii) trebuie sa trimita un mesaj Hello. Dupa primirea mesajului Hello si dupa verificarea compatibilitatii retelei si versiunilor, o sesiune este activa si orice alte mesaje pot fi trimise. -In orice moment, un mesaj Disconnect poate fi trimis. - - - diff --git a/pages/other-languages/[chinese]-ethereum-toc.md b/pages/other-languages/[chinese]-ethereum-toc.md deleted file mode 100644 index b88ddfd16..000000000 --- a/pages/other-languages/[chinese]-ethereum-toc.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -name: Ethereum TOC -category: ---- - -中文读者可以在以太坊中文社区( www.1tf.org )获知最新信息。 - -白皮书:[以太坊(Ethereum ):下一代智能合约和去中心化应用平台](https://github.com/ethereum/wiki/wiki/White-Paper-%5BChinese%5D) - -[Serpent语言指南](https://github.com/ethereum/wiki/wiki/%5B%E4%B8%AD%E6%96%87%5D-Serpent%E6%8C%87%E5%8D%97) - -[以太坊开发计划](https://github.com/ethereum/wiki/wiki/%E4%BB%A5%E5%A4%AA%E5%9D%8A%E5%BC%80%E5%8F%91%E8%AE%A1%E5%88%92) - -[术语表](https://github.com/ethereum/wiki/wiki/%E6%9C%AF%E8%AF%AD%E8%A1%A8) - -[网络状态监控](https://github.com/ethereum/wiki/wiki/Network-Status-%28Chinese%29) \ No newline at end of file diff --git a/pages/other-languages/[chinese]-rlp.md b/pages/other-languages/[chinese]-rlp.md deleted file mode 100644 index 6bbb33f4f..000000000 --- a/pages/other-languages/[chinese]-rlp.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -name: RLP -category: ---- - -RLP (递归长度前缀)提供了一种适用于任意二进制数据数组的编码,RLP已经成为以太坊中对对象进行序列化的主要编码方式。 RLP的唯一目标就是解决结构体的编码问题;对原子数据类型(比如,字符串,整数型,浮点型)的编码则交给更高层的协议;以太坊中要求数字必须是一个大端字节序的、没有零占位的存储的格式(也就是说,一个整数0和一个空数组是等同的)。 - -对于在 RLP 格式中对一个字典数据的编码问题,有两种建议的方式,一种是通过二维数组表达键值对,比如`[[k1,v1],[k2,v2]...]`,并且对键进行字典序排序;另一种方式是通过以太坊文档中提到的高级的[基数树](https://github.com/ethereum/wiki/wiki/Patricia-Tree) 编码来实现。 - -### 定义 - -RLP 编码函数接受一个item。定义如下: - -* 将一个字符串作为一个item(比如,一个 byte 数组) -* 一组item列表(list)作为一个item - -例如,一个空字符串可以是一个item,一个字符串"cat"也可以是一个item,一个含有多个字符串的列表也行,复杂的数据结构也行,比如这样的`["cat",["puppy","cow"],"horse",[[]],"pig",[""],"sheep"]`。注意在本文后续内容中,说"字符串"的意思其实就相当于"一个确定长度的二进制字节信息数据";而不要假设或考虑关于字符的编码问题。 - -RLP 编码定义如下: - -* 对于 `[0x00, 0x7f]` 范围内的单个字节, RLP 编码内容就是字节内容本身。 -* 否则,如果是一个 0-55 字节长的字符串,则RLP编码有一个特别的数值 **0x80** 加上字符串长度,再加上字符串二进制内容。这样,第一个字节的表达范围为 `[0x80, 0xb7]`. -* 如果字符串长度超过 55 个字节,RLP 编码由定值 **0xb7** 加上字符串长度的长度,加上字符串长度长度,加上字符串二进制内容组成。比如,一个长度为 1024 的字符串,将被编码为`\xb9\x04\x00` 后面再加上字符串内容。第一字节的表达范围是`[0xb8, 0xbf]`。 -* 如果列表的内容(它的所有项的组合长度)是0-55个字节长,它的RLP编码由0xC0加上所有的项的RLP编码串联起来的长度得到的单个字节,后跟所有的项的RLP编码的串联组成。 第一字节的范围因此是[0xc0, 0xf7] -* 如果列表的内容超过55字节,它的RLP编码由0xC0加上所有的项的RLP编码串联起来的长度的长度得到的单个字节,后跟所有的项的RLP编码串联起来的长度的长度,再后跟所有的项的RLP编码的串联组成。 第一字节的范围因此是[0xf8, 0xff] 。 - -用Python代码表达以上逻辑: - -```python -def rlp_encode(input): - if isinstance(input,str): - if len(input) == 1 and chr(input) < 128: return input - else: return encode_length(len(input),128) + input - elif isinstance(input,list): - output = '' - for item in input: output += rlp_encode(item) - return encode_length(len(output),192) + output - -def encode_length(L,offset): - if L < 56: - return chr(L + offset) - elif L < 256**8: - BL = to_binary(L) - return chr(len(BL) + offset + 55) + BL - else: - raise Exception("input too long") - -def to_binary(x): - return '' if x == 0 else to_binary(int(x / 256)) + chr(x % 256) -``` - -### 例子 - -字符串 "dog" = [ 0x83, 'd', 'o', 'g' ] - -列表 [ "cat", "dog" ] = `[ 0xc8, 0x83, 'c', 'a', 't', 0x83, 'd', 'o', 'g' ]` - -空字符串 ('null') = `[ 0x80 ]` - -空列表 = `[ 0xc0 ]` - -数字15 ('\x0f') = `[ 0x0f ]` - -数字 1024 ('\x04\x00') = `[ 0x82, 0x04, 0x00 ]` - -The [set theoretical representation](http://en.wikipedia.org/wiki/Set-theoretic_definition_of_natural_numbers) of two, `[ [], [[]], [ [], [[]] ] ] = [ 0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc1, 0xc0 ]` - -字符串 "Lorem ipsum dolor sit amet, consectetur adipisicing elit" = `[ 0xb8, 0x38, 'L', 'o', 'r', 'e', 'm', ' ', ... , 'e', 'l', 'i', 't' ]` diff --git a/pages/other-languages/[chinese]-white-paper.md b/pages/other-languages/[chinese]-white-paper.md deleted file mode 100644 index 1456f5b13..000000000 --- a/pages/other-languages/[chinese]-white-paper.md +++ /dev/null @@ -1,477 +0,0 @@ ---- -name: White Paper -category: ---- - -### 以太坊(Ethereum ):下一代智能合约和去中心化应用平台 - -翻译:巨蟹 、少平 - -译者注:中文读者可以到以太坊爱好者网站(www.ethfans.org)和论坛(www.bbs.ethfans.org)获取最新的以太坊信息。 - -当中本聪在2009年1月启动比特币区块链时,他同时向世界引入了两种未经测试的革命性的新概念。第一种就是比特币(bitcoin),一种去中心化的点对点的网上货币,在没有任何资产担保、内在价值或者中心发行者的情况下维持着价值。到目前为止,比特币已经吸引了大量的公众注意力, 就政治方面而言它是一种没有中央银行的货币并且有着剧烈的价格波动。然而,中本聪的伟大试验还有与比特币同等重要的一部分:基于工作量证明的区块链概念使得人们可以就交易顺序达成共识。作为应用的比特币可以被描述为一个先申请(first-to-file)系统:如果某人有50BTC并且同时向A和B发送这50BTC,只有被首先被确认的交易才会生效。没有固有方法可以决定两笔交易哪一笔先到,这个问题阻碍了去中心化数字货币的发展许多年。中本聪的区块链是第一个可靠的去中心化解决办法。现在,开发者们的注意力开始迅速地转向比特币技术的第二部分,区块链怎样应用于货币以外的领域。 - -常被提及的应用包括使用链上数字资产来代表定制货币和金融工具(彩色币),某种基础物理设备的所有权(智能资产),如域名一样的没有可替代性的资产(域名币)以及如去中心化交易所,金融衍生品,点到点赌博和链上身份和信誉系统等更高级的应用。另一个常被问询的重要领域是“智能合约”- 根据事先任意制订的规则来自动转移数字资产的系统。例如,一个人可能有一个存储合约,形式为“A可以每天最多提现X个币,B每天最多Y个,A和B一起可以随意提取,A可以停掉B的提现权”。这种合约的符合逻辑的扩展就是去中心化自治组织(DAOs)-长期的包含一个组织的资产并把组织的规则编码的智能合约。以太坊的目标就是提供一个带有内置的成熟的图灵完备语言的区块链,用这种语言可以创建合约来编码任意状态转换功能,用户只要简单地用几行代码来实现逻辑,就能够创建以上提及的所有系统以及许多我们还想象不到的的其它系统。 - -### 目录 - -* 历史 - * 作为状态转换系统的比特币 - * 挖矿 - * 默克尔树 - * 替代区块链应用 - * 脚本 -* 以太坊 - * 以太坊账户 - * 消息和交易 - * 以太坊状态转换功能 - * 代码执行 - * 区块链和挖矿 -* 应用 - * 令牌系统 - * 金融衍生品 - * 身份和信誉系统 - * 去中心化文件存储 - * 去中心化自治组织 - * 进一步的应用 -* 杂项和关注 - * 改进版幽灵协议的实施 - * 费用 - * 计算和图灵完备 - * 货币和发行 - * 挖矿的中心化 - * 扩展性 -* 综述:去中心化应用 -* 结论 - * 注解和进阶阅读 - -### 历史 - -去中心化的数字货币概念,正如财产登记这样的替代应用一样,早在几十年以前就被提出来了。1980和1990年代的匿名电子现金协议,大部分是以乔姆盲签技术(Chaumian blinding)为基础的。这些电子现金协议提供具有高度隐私性的货币,但是这些协议都没有流行起来,因为它们都依赖于一个中心化的中介机构。1998年,戴伟(Wei Dai)的b-money首次引入了通过解决计算难题和去中心化共识创造货币的思想,但是该建议并未给出如何实现去中心化共识的具体方法。2005年,芬尼(Hal Finney)引入了“可重复使用的工作量证明机制”(reusable proofs of work)概念,它同时使用b-money的思想和Adam Back提出的计算困难的哈希现金(Hashcash)难题来创造密码学货币。但是,这种概念再次迷失于理想化,因为它依赖于可信任的计算作为后端。 - -因为货币是一个先申请应用,交易的顺序至关重要,所以去中心化的货币需要找到实现去中心化共识的方法。比特币以前的所有电子货币协议所遇到的主要障碍是,尽管对如何创建安全的拜占庭问题容错(Byzantine-fault-tolerant)多方共识系统的研究已经历时多年,但是上述协议只解决了问题的一半。这些协议假设系统的所有参与者是已知的,并产生如“如果有N方参与到系统中,那么系统可以容忍N/4的恶意参与者”这样形式的安全边界。然而这个假设的问题在于,在匿名的情况下,系统设置的安全边界容易遭受女巫攻击,因为一个攻击者可以在一台服务器或者僵尸网络上创建数以千计的节点,从而单方面确保拥有多数份额。 - -中本聪的创新是引入这样一个理念:将一个非常简单的基于节点的去中心化共识协议与工作量证明机制结合在一起。节点通过工作量证明机制获得参与到系统的权利,每十分钟将交易打包到“区块”中,从而创建出不断增长的区块链。拥有大量算力的节点有更大的影响力,但获得比整个网络更多的算力比创建一百万个节点困难得多。尽管比特币区块链模型非常简陋,但是实践证明它已经足够好用了,在未来五年,它将成为全世界两百个以上的货币和协议的基石。 - -### 作为状态转换系统的比特币 - -![](https://camo.githubusercontent.com/e7a1fc59abdd42654fa8c54c0f847eb2c8fda72e/687474703a2f2f766974616c696b2e63612f66696c65732f73746174657472616e736974696f6e2e706e673f32) - -从技术角度讲,比特币账本可以被认为是一个状态转换系统,该系统包括所有现存的比特币所有权状态和“状态转换函数”。状态转换函数以当前状态和交易为输入,输出新的状态。例如,在标准的银行系统中,状态就是一个资产负债表,一个从A账户向B账户转账X美元的请求是一笔交易,状态转换函数将从A账户中减去X美元,向B账户增加X美元。如果A账户的余额小于X美元,状态转换函数就会返回错误提示。所以我们可以如下定义状态转换函数: - - APPLY(S,TX) ­> S' or ERROR - -在上面提到的银行系统中,状态转换函数如下: - - APPLY({ Alice: $50, Bob: $50 },"send $20 from Alice to Bob") = { Alice: $30,Bob: $70 } - -但是: - - APPLY({ Alice: $50, Bob: $50 },"send $70 from Alice to Bob") = ERROR - -比特币系统的“状态”是所有已经被挖出的、没有花费的比特币(技术上称为“未花费的交易输出,unspent transaction outputs 或UTXO”)的集合。每个UTXO都有一个面值和所有者(由20个字节的本质上是密码学公钥的地址所定义[1])。一笔交易包括一个或多个输入和一个或多个输出。每个输入包含一个对现有UTXO的引用和由与所有者地址相对应的私钥创建的密码学签名。每个输出包含一个新的加入到状态中的UTXO。 - -在比特币系统中,状态转换函数`APPLY(S,TX)->S’`大体上可以如下定义: - -1. 交易的每个输入: - * 如果引用的UTXO不存在于现在的状态中(`S`),返回错误提示 - * 如果签名与UTXO所有者的签名不一致,返回错误提示 -2. 如果所有的UTXO输入面值总额小于所有的UTXO输出面值总额,返回错误提示 -3. 返回新状态`S’`,新状态`S`中移除了所有的输入UTXO,增加了所有的输出UTXO。 - -第一步的第一部分防止交易的发送者花费不存在的比特币,第二部分防止交易的发送者花费其他人的比特币。第二步确保价值守恒。比特币的支付协议如下。假设Alice想给Bob发送11.7BTC。事实上,Alice不可能正好有11.7BTC。假设,她能得到的最小数额比特币的方式是:6+4+2=12。所以,她可以创建一笔有3个输入,2个输出的交易。第一个输出的面值是11.7BTC,所有者是Bob(Bob的比特币地址),第二个输出的面值是0.3BTC,所有者是Alice自己,也就是找零。 - -### 挖矿 - -![](https://camo.githubusercontent.com/e8e2a0c15c17b066e7f17056f7697819b9a1aa33/687474703a2f2f766974616c696b2e63612f66696c65732f626c6f636b5f706963747572652e706e67) - -如果我们拥有可信任的中心化服务机构,状态转换系统可以很容易地实现,可以简单地将上述功能准确编码。然而,我们想把比特币系统建成为去中心化的货币系统,为了确保每个人都同意交易的顺序,我们需要将状态转换系统与一个共识系统结合起来。比特币的去中心化共识进程要求网络中的节点不断尝试将交易打包成“区块”。网络被设计为大约每十分钟产生一个区块,每个区块包含一个时间戳、一个随机数、一个对上一个区块的引用(即哈希)和上一区块生成以来发生的所有交易列表。这样随着时间流逝就创建出了一个持续增长的区块链,它不断地更新,从而能够代表比特币账本的最新状态。 - -依照这个范式,检查一个区块是否有效的算法如下: - -1. 检查区块引用的上一个区块是否存在且有效。 -2. 检查区块的时间戳是否晚于以前的区块的时间戳,而且早于未来2小时[2]。 -3. 检查区块的工作量证明是否有效。 -4. 将上一个区块的最终状态赋于`S[0]`。 -5. 假设TX是区块的交易列表,包含n笔交易。对于属于0……n-1的所有i,进行状态转换`S[i+1] = APPLY(S[i],TX[i])`。如果任何一笔交易i在状态转换中出错,退出程序,返回错误。 -6. 返回正确,状态`S[n]`是这一区块的最终状态。 - -本质上,区块中的每笔交易必须提供一个正确的状态转换,要注意的是,“状态”并不是编码到区块的。它纯粹只是被校验节点记住的抽象概念,对于任意区块都可以从创世状态开始,按顺序加上每一个区块的每一笔交易,(妥妥地)计算出当前的状态。另外,需要注意矿工将交易收录进区块的顺序。如果一个区块中有A、B两笔交易,B花费的是A创建的UTXO,如果A在B以前,这个区块是有效的,否则,这个区块是无效的。 - -区块验证算法的有趣部分是“工作量证明”概念:对每个区块进行SHA256哈希处理,将得到的哈希视为长度为256比特的数值,该数值必须小于不断动态调整的目标数值,本书写作时目标数值大约是2^190。工作量证明的目的是使区块的创建变得困难,从而阻止女巫攻击者恶意重新生成区块链。因为SHA256是完全不可预测的伪随机函数,创建有效区块的唯一方法就是简单地不断试错,不断地增加随机数的数值,查看新的哈希数值是否小于目标数值。如果当前的目标数值是2^192,就意味着平均需要尝试2^64次才能生成有效的区块。一般而言,比特币网络每隔2016个区块重新设定目标数值,保证平均每十分钟生成一个区块。为了对矿工的计算工作进行奖励,每一个成功生成区块的矿工有权在区块中包含一笔凭空发给他们自己25BTC的交易。另外,如果交易的输入大于输出,差额部分就作为“交易费用”付给矿工。顺便提一下,对矿工的奖励是比特币发行的唯一机制,创世状态中并没有比特币。 - -为了更好地理解挖矿的目的,让我们分析比特币网络出现恶意攻击者时会发生什么。因为比特币的密码学基础是非常安全的,所以攻击者会选择攻击没有被密码学直接保护的部分:交易顺序。攻击者的策略非常简单: - -1. 向卖家发送100BTC购买商品(尤其是无需邮寄的电子商品)。 -2. 等待直至商品发出。 -3. 创建另一笔交易,将相同的100BTC发送给自己的账户。 -4. 使比特币网络相信发送给自己账户的交易是最先发出的。 - -一旦步骤(1)发生,几分钟后矿工将把这笔交易打包到区块,假设是第270000个区块。大约一个小时以后,在此区块后面将会有五个区块,每个区块间接地指向这笔交易,从而确认这笔交易。这时卖家收到货款,并向买家发货。因为我们假设这是数字商品,攻击者可以即时收到货。现在,攻击者创建另一笔交易,将相同的100BTC发送到自己的账户。如果攻击者只是向全网广播这一消息,这一笔交易不会被处理。矿工会运行状态转换函数`APPLY(S,TX)`,发现这笔交易将花费已经不在状态中的UTXO。所以,攻击者会对区块链进行分叉,将第269999个区块作为父区块重新生成第270000个区块,在此区块中用新的交易取代旧的交易。因为区块数据是不同的,这要求重新进行工作量证明。另外,因为攻击者生成的新的第270000个区块有不同的哈希,所以原来的第270001到第270005的区块不指向它,因此原有的区块链和攻击者的新区块是完全分离的。在发生区块链分叉时,区块链长的分支被认为是诚实的区块链,合法的的矿工将会沿着原有的第270005区块后挖矿,只有攻击者一人在新的第270000区块后挖矿。攻击者为了使得他的区块链最长,他需要拥有比除了他以外的全网更多的算力来追赶(即51%攻击)。 - -### 默克尔树 - -![](https://camo.githubusercontent.com/52e0d1b4436e61cca69cd3e3e62dda7b9bcb3b54/68747470733a2f2f7777772e657468657265756d2e6f72672f67685f77696b692f7370765f626974636f696e2e706e67) - -左:仅提供默克尔树(Merkle tree)上的少量节点已经足够给出分支的合法证明。 -右:任何对于默克尔树的任何部分进行改变的尝试都会最终导致链上某处的不一致。 - -比特币系统的一个重要的可扩展特性是:它的区块存储在多层次的数据结构中。一个区块的哈希实际上只是区块头的哈希,区块头是包含时间戳、随机数、上个区块哈希和存储了所有的区块交易的默克尔树的根哈希的长度大约为200字节的一段数据。 - -默克尔树是一种二叉树,由一组叶节点、一组中间节点和一个根节点构成。最下面的大量的叶节点包含基础数据,每个中间节点是它的两个子节点的哈希,根节点也是由它的两个子节点的哈希,代表了默克尔树的顶部。默克尔树的目的是允许区块的数据可以零散地传送:节点可以从一个源下载区块头,从另外的源下载与其有关的树的其它部分,而依然能够确认所有的数据都是正确的。之所以如此是因为哈希向上的扩散:如果一个恶意用户尝试在树的下部加入一个伪造的交易,所引起的改动将导致树的上层节点的改动,以及更上层节点的改动,最终导致根节点的改动以及区块哈希的改动,这样协议就会将其记录为一个完全不同的区块(几乎可以肯定是带着不正确的工作量证明的)。 - -默克尔树协议对比特币的长期持续性可以说是至关重要的。在2014年4月,比特币网络中的一个全节点-存储和处理所有区块的全部数据的节点-需要占用15GB的内存空间,而且还以每个月超过1GB的速度增长。目前,这一存储空间对台式计算机来说尚可接受,但是手机已经负载不了如此巨大的数据了。未来只有商业机构和爱好者才会充当完整节点。简化支付确认(SPV)协议允许另一种节点存在,这样的节点被成为“轻节点”,它下载区块头,使用区块头确认工作量证明,然后只下载与其交易相关的默克尔树“分支”。这使得轻节点只要下载整个区块链的一小部分就可以安全地确定任何一笔比特币交易的状态和账户的当前余额。 - -### 其它的区块链应用 - -将区块链的思想应用到其它领域的想法早就出现了。在2005年,尼克萨博提出了“用所有权为财产冠名”的概念,文中描述了复制数据库技术的发展如何使基于区块链的系统可以应用于登记土地所有权,创建包括例如房产权、违法侵占和乔治亚州土地税等概念的详细框架。然而,不幸的是在那时还没有实用的复制数据库系统,所以这个协议被没有被付诸实践。不过,自2009年比特币系统的去中心化共识开发成功以来,许多区块链的其它应用开始快速出现。 - -* **域名币(namecoin)**- 创建于2010年,被称为去中心化的名称注册数据库。像Tor、Bitcoin和BitMessage这样的去中心化协议,需要一些确认账户的方法,这样其他人才能够与用户进行交互。但是,在所有的现存的解决方案中仅有的可用的身份标识是象`1LW79wp5ZBqaHW1jL5TciBCrhQYtHagUWy`这样的伪随机哈希。理想的情况下,人们希望拥有一个带有象“george”这样的名称的账户。然而,问题是如果有人可以创建“george”账户,那么其他人同样也可以创建“george”账户来假扮。唯一的解决方法是先申请原则(first-to-file),只有第一个注册者可以成功注册,第二个不能再次注册同一个账户。这一问题就可以利用比特币的共识协议。域名币是利用区块链实现名称注册系统的最早的、最成功的系统。 -* **彩色币(Colored coins)**- 彩色币的目的是为人们在比特币区块链上创建自己的数字货币,或者,在更重要的一般意义上的货币 – 数字令牌提供服务。依照彩色币协议,人们可以通过为某一特别的比特币UTXO指定颜色,发行新的货币。该协议递归地将其它UTXO定义为与交易输入UTXO相同的颜色。这就允许用户保持只包含某一特定颜色的UTXO,发送这些UTXO就像发送普通的比特币一样,通过回溯全部的区块链判断收到的UTXO颜色。 -* **元币(Metacoins)**- 元币的理念是在比特币区块链上创建新的协议,利用比特币的交易保存元币的交易,但是采用了不同的状态转换函数APPLY’。因为元币协议不能阻止比特币区块链上的无效的元币交易,所以增加一个规则如果APPLY'(S,TX)返回错误,这一协议将默认APPLY'(S,TX) = S。这为创建任意的、先进的不能在比特币系统中实现的密码学货币协议提供了一个简单的解决方法,而且开发成本非常低,因为挖矿和网络的问题已经由比特币协议处理好了。 - -因此,一般而言,建立共识协议有两种方法:建立一个独立的网络和在比特币网络上建立协议。虽然像域名币这样的应用使用第一种方法已经获得了成功,但是该方法的实施非常困难,因为每一个应用需要创建独立的区块链和建立、测试所有状态转换和网络代码。另外,我们预测去中心化共识技术的应用将会服从幂律分布,大多数的应用太小不足以保证自由区块链的安全,我们还注意到大量的去中心化应用,尤其是去中心化自治组织,需要进行应用之间的交互。 - -另一方面,基于比特币的方法存在缺点,它没有继承比特币可以进行简化确认支付(SPV) 的特性。比特币可以实现简化确认支付,因为比特币可以将区块链深度作为有效性确认代理。在某一点上,一旦一笔交易的祖先们距离现在足够远时,就可以认为它们是合法状态的一部分。与之相反,基于比特币区块链的元币协议不能强迫区块链不包括不符合元币协议的交易。因此,安全的元币协议的简化支付确认需要后向扫描所有的区块,直到区块链的初始点,以确认某一交易是否有效。目前,所有基于比特币的元币协议的“轻”实施都依赖可信任的服务器提供数据,这对主要目的之一是消除信任需要的密码学货币而言,只是一个相当次优的结果。 - -### 脚本 - -即使不对比特币协议进行扩展,它也能在一定程度上实现”智能合约”。比特币的UTXO可以被不只被一个公钥拥有,也可以被用基于堆栈的编程语言所编写的更加复杂的脚本所拥有。在这一模式下,花费这样的UTXO,必须提供满足脚本的数据。事实上,基本的公钥所有权机制也是通过脚本实现的:脚本将椭圆曲线签名作为输入,验证交易和拥有这一UTXO的地址,如果验证成功,返回1,否则返回0。更加复杂的脚本用于其它不同的应用情况。例如,人们可以创建要求集齐三把私钥中的两把才能进行交易确认的脚本(多重签名),对公司账户、储蓄账户和某些商业代理来说,这种脚本是非常有用的。脚本也能用来对解决计算问题的用户发送奖励。人们甚至可以创建这样的脚本“如果你能够提供你已经发送一定数额的的狗币给我的简化确认支付证明,这一比特币UTXO就是你的了”,本质上,比特币系统允许不同的密码学货币进行去中心化的兑换。 - -然而,比特币系统的脚本语言存在一些严重的限制: - -* **缺少图灵完备性** – 这就是说,尽管比特币脚本语言可以支持多种计算,但是它不能支持所有的计算。最主要的缺失是循环语句。不支持循环语句的目的是避免交易确认时出现无限循环。理论上,对于脚本程序员来说,这是可以克服的障碍,因为任何循环都可以用多次重复if 语句的方式来模拟,但是这样做会导致脚本空间利用上的低效率,例如,实施一个替代的椭圆曲线签名算法可能将需要256次重复的乘法,而每次都需要单独编码。 -* **价值盲(Value-blindness)**。UTXO脚本不能为账户的取款额度提供精细的的控制。例如,预言机合约(oracle contract)的一个强大应用是对冲合约,A和B各自向对冲合约中发送价值1000美元的比特币,30天以后,脚本向A发送价值1000美元的比特币,向B发送剩余的比特币。虽然实现对冲合约需要一个预言机(oracle)决定一比特币值多少美元,但是与现在完全中心化的解决方案相比,这一机制已经在减少信任和基础设施方面有了巨大的进步。然而,因为UTXO是不可分割的,为实现此合约,唯一的方法是非常低效地采用许多有不同面值的UTXO(例如对应于最大为30的每个k,有一个2^k的UTXO)并使预言机挑出正确的UTXO发送给A和B。 -* **缺少状态** – UTXO只能是已花费或者未花费状态,这就没有给需要任何其它内部状态的多阶段合约或者脚本留出生存空间。这使得实现多阶段期权合约、去中心化的交换要约或者两阶段加密承诺协议(对确保计算奖励非常必要)非常困难。这也意味着UTXO只能用于建立简单的、一次性的合约,而不是例如去中心化组织这样的有着更加复杂的状态的合约,使得元协议难以实现。二元状态与价值盲结合在一起意味着另一个重要的应用-取款限额-是不可能实现的。 -* **区块链盲(Blockchain-blindness)**- UTXO看不到区块链的数据,例如随机数和上一个区块的哈希。这一缺陷剥夺了脚本语言所拥有的基于随机性的潜在价值,严重地限制了博彩等其它领域应用。 - -我们已经考察了在密码学货币上建立高级应用的三种方法:建立一个新的区块链,在比特币区块链上使用脚本,在比特币区块链上建立元币协议。建立新区块链的方法可以自由地实现任意的特性,成本是开发时间和培育努力。使用脚本的方法非常容易实现和标准化,但是它的能力有限。元币协议尽管非常容易实现,但是存在扩展性差的缺陷。在以太坊系统中,我们的目的是建立一个能够同时具有这三种模式的所有优势的通用框架。 - -## 以太坊 - -以太坊的目的是基于脚本、竞争币和链上元协议(on-chain meta-protocol)概念进行整合和提高,使得开发者能够创建任意的基于共识的、可扩展的、标准化的、特性完备的、易于开发的和协同的应用。以太坊通过建立终极的抽象的基础层-内置有图灵完备编程语言的区块链-使得任何人都能够创建合约和去中心化应用并在其中设立他们自由定义的所有权规则、交易方式和状态转换函数。域名币的主体框架只需要两行代码就可以实现,诸如货币和信誉系统等其它协议只需要不到二十行代码就可以实现。智能合约-包含价值而且只有满足某些条件才能打开的加密箱子-也能在我们的平台上创建,并且因为图灵完备性、价值知晓(value-awareness)、区块链知晓(blockchain-awareness)和多状态所增加的力量而比比特币脚本所能提供的智能合约强大得多。 - -### 以太坊账户 - -在以太坊系统中,状态是由被称为“账户”(每个账户由一个20字节的地址)的对象和在两个账户之间转移价值和信息的状态转换构成的。以太坊的账户包含四个部分: - -· 随机数,用于确定每笔交易只能被处理一次的计数器 -· 账户目前的以太币余额 -· 账户的合约代码,如果有的话 -· 账户的存储(默认为空) -以太币(Ether)是以太坊内部的主要加密燃料,用于支付交易费用。一般而言,以太坊有两种类型的账户:外部所有的账户(由私钥控制的)和合约账户(由合约代码控制)。外部所有的账户没有代码,人们可以通过创建和签名一笔交易从一个外部账户发送消息。每当合约账户收到一条消息,合约内部的代码就会被激活,允许它对内部存储进行读取和写入,和发送其它消息或者创建合约。 - -### 消息和交易 - -以太坊的消息在某种程度上类似于比特币的交易,但是两者之间存在三点重要的不同。第一,以太坊的消息可以由外部实体或者合约创建,然而比特币的交易只能从外部创建。第二,以太坊消息可以选择包含数据。第三,如果以太坊消息的接受者是合约账户,可以选择进行回应,这意味着以太坊消息也包含函数概念。 - -以太坊中“交易”是指存储从外部账户发出的消息的签名数据包。交易包含消息的接收者、用于确认发送者的签名、以太币账户余额、要发送的数据和两个被称为STARTGAS和GASPRICE的数值。为了防止代码的指数型爆炸和无限循环,每笔交易需要对执行代码所引发的计算步骤-包括初始消息和所有执行中引发的消息-做出限制。STARTGAS就是限制,GASPRICE是每一计算步骤需要支付矿工的费用。如果执行交易的过程中,“用完了瓦斯”,所有的状态改变恢复原状态,但是已经支付的交易费用不可收回了。如果执行交易中止时还剩余瓦斯,那么这些瓦斯将退还给发送者。创建合约有单独的交易类型和相应的消息类型;合约的地址是基于账号随机数和交易数据的哈希计算出来的。 - -消息机制的一个重要后果是以太坊的“头等公民”财产-合约与外部账户拥有同样权利,包括发送消息和创建其它合约的权利。这使得合约可以同时充当多个不同的角色,例如,用户可以使去中心化组织(一个合约)的一个成员成为一个中介账户(另一个合约),为一个偏执的使用定制的基于量子证明的兰波特签名(第三个合约)的个人和一个自身使用由五个私钥保证安全的账户(第四个合约)的共同签名实体提供居间服务。以太坊平台的强大之处在于去中心化的组织和代理合约不需要关心合约的每一参与方是什么类型的账户。 - -### 以太坊状态转换函数 - -以太坊的状态转换函数:`APPLY(S,TX) -> S'`,可以定义如下: - -1. 检查交易的格式是否正确(即有正确数值)、签名是否有效和随机数是否与发送者账户的随机数匹配。如否,返回错误。 -2. 计算交易费用:`fee=STARTGAS * GASPRICE`,并从签名中确定发送者的地址。从发送者的账户中减去交易费用和增加发送者的随机数。如果账户余额不足,返回错误。 -3. 设定初值`GAS = STARTGAS`,并根据交易中的字节数减去一定量的瓦斯值。 -4. 从发送者的账户转移价值到接收者账户。如果接收账户还不存在,创建此账户。如果接收账户是一个合约,运行合约的代码,直到代码运行结束或者瓦斯用完。 -5. 如果因为发送者账户没有足够的钱或者代码执行耗尽瓦斯导致价值转移失败,恢复原来的状态,但是还需要支付交易费用,交易费用加至矿工账户。 -6. 否则,将所有剩余的瓦斯归还给发送者,消耗掉的瓦斯作为交易费用发送给矿工。 -例如,假设合约的代码如下: - -```python -if !self.storage[calldataload(0)]: - self.storage[calldataload(0)] = calldataload(32) -``` - -需要注意的是,在现实中合约代码是用底层以太坊虚拟机(EVM)代码写成的。上面的合约是用我们的高级语言Serpent语言写成的,它可以被编译成EVM代码。假设合约存储器开始时是空的,一个值为10以太,瓦斯为2000,瓦斯价格为0.001以太并且64字节数据,第一个三十二字节的快代表号码2和第二个代表词`CHARLIE`。的交易发送后,状态转换函数的处理过程如下: - -1. 检查交易是否有效、格式是否正确。 -2. 检查交易发送者至少有2000*0.001=2个以太币。如果有,从发送者账户中减去2个以太币。 -3. 初始设定gas=2000,假设交易长为170字节,每字节的费用是5,减去850,所以还剩1150。 -4. 从发送者账户减去10个以太币,为合约账户增加10个以太币。 -5. 运行代码。在这个合约中,运行代码很简单:它检查合约存储器索引为2处是否已使用,注意到它未被使用,然后将其值置为CHARLIE。假设这消耗了187单位的瓦斯,于是剩余的瓦斯为1150 - 187 = 963。 -6. 向发送者的账户增加963*0.001=0.963个以太币,返回最终状态。 -如果没有合约接收交易,那么所有的交易费用就等于GASPRICE乘以交易的字节长度,交易的数据就与交易费用无关了。另外,需要注意的是,合约发起的消息可以对它们产生的计算分配瓦斯限额,如果子计算的瓦斯用完了,它只恢复到消息发出时的状态。因此,就像交易一样,合约也可以通过对它产生的子计算设置严格的限制,保护它们的计算资源。 - -### 代码执行 - -以太坊合约的代码使用低级的基于堆栈的字节码的语言写成的,被称为“以太坊虚拟机代码”或者“EVM代码”。代码由一系列字节构成,每一个字节代表一种操作。一般而言,代码执行是无限循环,程序计数器每增加一(初始值为零)就执行一次操作,直到代码执行完毕或者遇到错误,`STOP`或者`RETURN`指令。操作可以访问三种存储数据的空间: - -* **堆栈**,一种后进先出的数据存储,32字节的数值可以入栈,出栈。 -* **内存**,可无限扩展的字节队列。 -* **合约的长期存储**,一个秘钥/数值的存储,其中秘钥和数值都是32字节大小,与计算结束即重置的堆栈和内存不同,存储内容将长期保持。 - -代码可以象访问区块头数据一样访问数值,发送者和接受到的消息中的数据,代码还可以返回数据的字节队列作为输出。 - -EVM代码的正式执行模型令人惊讶地简单。当以太坊虚拟机运行时,它的完整的计算状态可以由元组`(block_state, transaction, message, code, memory, stack, pc, gas)`来定义,这里`block_state`是包含所有账户余额和存储的全局状态。每轮执行时,通过调出代码的第`pc`(程序计数器)个字节,当前指令被找到,每个指令都有定义自己如何影响元组。例如,`ADD`将两个元素出栈并将它们的和入栈,将`gas`(瓦斯)减一并将`pc`加一,`SSTORE`将顶部的两个元素出栈并将第二个元素插入到由第一个元素定义的合约存储位置,同样减少最多200的gas值并将`pc`加一,虽然有许多方法通过即时编译去优化以太坊,但以太坊的基础性的实施可以用几百行代码实现。 - -### 区块链和挖矿 - -虽然有一些不同,但以太坊的区块链在很多方面类似于比特币区块链。它们的区块链架构的不同在于,以太坊区块不仅包含交易记录和最近的状态,还包含区块序号和难度值。以太坊中的区块确认算法如下: - -1. 检查区块引用的上一个区块是否存在和有效。 -2. 检查区块的时间戳是否比引用的上一个区块大,而且小于15分钟。 -3. 检查区块序号、难度值、 交易根,叔根和瓦斯限额(许多以太坊特有的底层概念)是否有效。 -4. 检查区块的工作量证明是否有效。 -5. 将`S[0]`赋值为上一个区块的`STATE_ROOT`。 -6. 将`TX`赋值为区块的交易列表,一共有`n`笔交易。对于属于`0……n-1`的`i`,进行状态转换`S[i+1] = APPLY(S[i],TX[i])`。如果任何一个转换发生错误,或者程序执行到此处所花费的瓦斯(gas)超过了`GASLIMIT`,返回错误。 -7. 用`S[n]`给`S_FINAL`赋值, 向矿工支付区块奖励。 -8 检查`S-FINAL`是否与`STATE_ROOT`相同。如果相同,区块是有效的。否则,区块是无效的。 - -这一确认方法乍看起来似乎效率很低,因为它需要存储每个区块的所有状态,但是事实上以太坊的确认效率可以与比特币相提并论。原因是状态存储在树结构中(tree structure),每增加一个区块只需要改变树结构的一小部分。因此,一般而言,两个相邻的区块的树结构的大部分应该是相同的,因此存储一次数据,可以利用指针(即子树哈希)引用两次。一种被称为“帕特里夏树”(“Patricia Tree”)的树结构可以实现这一点,其中包括了对默克尔树概念的修改,不仅允许改变节点,而且还可以插入和删除节点。另外,因为所有的状态信息是最后一个区块的一部分,所以没有必要存储全部的区块历史-这一方法如果能够可以应用到比特币系统中,经计算可以对存储空间有10-20倍的节省。 - -## 应用 - -一般来讲,以太坊之上有三种应用。第一类是金融应用,为用户提供更强大的用他们的钱管理和参与合约的方法。包括子货币,金融衍生品,对冲合约,储蓄钱包,遗嘱,甚至一些种类的全面的雇佣合约。第二类是半金融应用,这里有钱的存在但也有很重的非金钱的方面,一个完美的例子是为解决计算问题而设的自我强制悬赏。最后,还有在线投票和去中心化治理这样的完全的非金融应用。 - -### 令牌系统 - -链上令牌系统有很多应用,从代表如美元或黄金等资产的子货币到公司股票,单独的令牌代表智能资产,安全的不可伪造的优惠券,甚至与传统价值完全没有联系的用来进行积分奖励的令牌系统。在以太坊中实施令牌系统容易得让人吃惊。关键的一点是理解,所有的货币或者令牌系统,从根本上来说是一个带有如下操作的数据库:从A中减去X单位并把X单位加到B上,前提条件是(1)A在交易之前有至少X单位以及(2)交易被A批准。实施一个令牌系统就是把这样一个逻辑实施到一个合约中去。 - -用Serpent语言实施一个令牌系统的基本代码如下: - -```python -def send(to, value): - if self.storage[from] >= value: - self.storage[from] = self.storage[from] value - self.storage[to] = self.storage[to] + value -``` - -这从本质上来说是本文将要进一步描述的“银行系统”状态转变功能的一个最小化实施。需要增加一些额外的代码以提供在初始和其它一些边缘情况下分发货币的功能,理想情况下会增加一个函数让其它合约来查询一个地址的余额。就足够了。理论上,基于以太坊的充当子货币的令牌系统可能包括一个基于比特币的链上元币所缺乏的重要功能:直接用这种货币支付交易费的能力。实现这种能力的方法是在合约里维护一个以太币账户以用来为发送者支付交易费,通过收集被用来充当交易费用的内部货币并把它们在一个不断运行的拍卖中拍卖掉,合约不断为该以太币账户注资。这样用户需要用以太币“激活”他们的账户,但一旦账户中有以太币它将会被重复使用因为每次合约都会为其充值。 - -### 金融衍生品和价值稳定的货币 - -金融衍生品是“智能合约”的最普遍的应用,也是最易于用代码实现的之一。实现金融合约的主要挑战是它们中的大部分需要参照一个外部的价格发布器;例如,一个需求非常大的应用是一个用来对冲以太币(或其它密码学货币)相对美元价格波动的智能合约,但该合约需要知道以太币相对美元的价格。最简单地方法是通过由某特定机构(例如纳斯达克)维护的“数据提供“合约进行,该合约的设计使得该机构能够根据需要更新合约,并提供一个接口使得其它合约能够通过发送一个消息给该合约以获取包含价格信息的回复。 - -当这些关键要素都齐备,对冲合约看起来会是下面的样子: - -1. 等待A输入1000以太币。. -2. 等待B 输入1000以太币。 -3. 通过查询数据提供合约,将1000以太币的美元价值,例如,x美元,记录至存储器。 -4. 30天后,允许A或B“重新激活“合约以发送价值x美元的以太币(重新查询数据提供合约以获取新价格并计算)给A并将剩余的以太币发送给B。 -这样的合约在密码学商务中有非同寻常的潜力。密码学货币经常被诟病的一个问题就是其价格的波动性;虽然大量的用户和商家可能需要密码学资产所带来的安全和便利,可他们不太会乐意面对一天中资产跌去23%价值的情形。直到现在,最为常见的推荐方案是发行者背书资产;思想是发行者创建一种子货币,对此种子货币他们有权发行和赎回,给予(线下)提供给他们一个单位特定相关资产(例如黄金,美元)的人一个单位子货币。发行者承诺当任何人送还一个单位密码学资产时。发还一个单位的相关资产。这种机制能够使任何非密码学资产被“升级“为密码学资产,如果发行者值得信任的话。 -然而实践中发行者并非总是值得信任的,并且一些情况下银行体系太脆弱,或者不够诚实守信从而使这样的服务无法存在。金融衍生品提供了一种替代方案。这里将不再有提供储备以支撑一种资产的单独的发行者,取而代之的是一个由赌一种密码学资产的价格会上升的投机者构成的去中心化市场。与发行者不同,投机者一方没有讨价还价的权利,因为对冲合约把他们的储备冻结在了契约中。注意这种方法并非是完全去中心化的,因为依然需要一个可信任的提供价格信息的数据源,尽管依然有争议这依然是在降低基础设施需求(与发行者不同,一个价格发布器不需要牌照并且似乎可归为自由言论一类)和降低潜在欺诈风险方面的一个巨大的进步。 - -### 身份和信誉系统 - -最早的替代币,域名币,尝试使用一个类比特币块链来提供一个名称注册系统,在那里用户可以将他们的名称和其它数据一起在一个公共数据库注册。最常用的应用案例把象“bitcoin.org“(或者再域名币中,”bitcoin.bit“)一样的域名与一个IP地址对应的域名系统。其它的应用案例包括电子邮件验证系统和潜在的更先进的信誉系统。这里是以太坊中提供与域名币类似的的名称注册系统的基础合约: - -```python -def register(name, value): - if !self.storage[name]: - self.storage[name] = value -``` - -合约非常简单;就是一个以太坊网络中的可以被添加但不能被修改或移除的数据库。任何人都可以把一个名称注册为一个值并永远不变。一个更复杂的名称注册合约将包含允许其他合约查询的“功能条款“,以及一个让一个名称的”拥有者“(即第一个注册者)修改数据或者转让所有权的机制。甚至可以在其上添加信誉和信任网络功能。 - -### 去中心化存储 - -在过去的几年里出现了一些大众化的在线文件存储初创公司,最突出的是Dropbox,它寻求允许用户上传他们的硬盘备份,提供备份存储服务并允许用户访问从而按月向用户收取费用。然而,在这一点上这个文件存储市场有时相对低效;对现存服务的粗略观察表明,特别地在“神秘谷“20-200GB这一既没有免费空间也没有企业级用户折扣的水平上,主流文件存储成本每月的价格意味着支付在一个月里支付整个硬盘的成本。以太坊合约允许去中心化存储生态的开发,这样用户通过将他们自己的硬盘或未用的网络空间租出去以获得少量收益,从而降低了文件存储的成本。 - -这样的设施的基础性构件就是我们所谓的“去中心化Dropbox合约“。这个合约工作原理如下。首先,某人将需要上传的数据分成快,对每一块数据加密以保护隐私,并且以此构建一个默克尔树。然后创建一个含以下规则的合约,每N个块,合约将从默克尔树中抽取一个随机索引(使用能够被合约代码访问的上一个块的哈希来提供随机性), 然后给第一个实体X以太以支撑一个带有类似简化验证支付(SPV)的在树中特定索引处的块的所有权证明。当一个用户想重新下载他的文件,他可以使用微支付通道协议(例如每32k字节支付1萨博)恢复文件;从费用上讲最高效的方法是支付者不到最后不发布交易,而是用一个略微更合算的带有同样随机数的交易在每32k字节之后来代替原交易。 - -这个协议的一个重要特征是,虽然看起来象是一个人信任许多不准备丢失文件的随机节点,但是他可以通过秘密分享把文件分成许多小块,然后通过监视合同得知每个小块都还被某个节点的保存着。如果一个合约依然在付款,那么就提供了某个人依然在保存文件的证据。 - -### 去中心化自治组织 - -通常意义上“去中心化自治组织(DAO, decentralized autonomous organization)”的概念指的是一个拥有一定数量成员或股东的虚拟实体,依靠比如67%多数来决定花钱以及修改代码。成员会集体决定组织如何分配资金。分配资金的方法可能是悬赏,工资或者更有吸引力的机制比如用内部货币奖励工作。这仅仅使用密码学块链技术就从根本上复制了传统公司或者非营利组织的法律意义以实现强制执行。至此许多围绕DAO的讨论都是围绕一个带有接受分红的股东和可交易的股份的“去中心化自治公司(DAC,decentralized autonomous corporation)”的“资本家”模式;作为替代者,一个被描述为“去中心化自治社区(decentralized autonomous community)”的实体将使所有成员都在决策上拥有同等的权利并且在增减成员时要求67%多数同意。每个人都只能拥有一个成员资格这一规则需要被群体强制实施。 - -下面是一个如何用代码实现DO的纲要。最简单地设计就是一段如果三分之二成员同意就可以自我修改的代码。虽然理论上代码是不可更改的,然而通过把代码主干放在一个单独的合约内并且把合约调用的地址指向一个可更改的存储依然可以容易地绕开障碍而使代码变得可修改,在一个这样的DAO合约的简单实现中有三种交易类型,由交易提供的数据区分: - -* `[0,i,K,V]` 注册索引为i 的对存储地址索引为K 至 v 的内容的更改建议。 -* `[0,i]` 注册对建议i 的投票。 -* `[2,i]` 如有足够投票则确认建议i。 - -然后合约对每一项都有具体的条款。它将维护一个所有开放存储的更改记录以及一个谁投票表决的表。还有一个所有成员的表。当任何存储内容的更改获得了三分之二多数同意,一个最终的交易将执行这项更改。一个更加复杂的框架会增加内置的选举功能以实现如发送交易,增减成员,甚至提供委任制民主一类的投票代表(即任何人都可以委托另外一个人来代表自己投票,而且这种委托关系是可以传递的,所以如果A委托了B然后B委托了C那么C将决定A的投票)。这种设计将使DAO作为一个去中心化社区有机地成长, 使人们最终能够把挑选合适人选的任务交给专家,与当前系统不同,随着社区成员不断改变他们的站队假以时日专家会容易地出现和消失。 -一个替代的模式是去中心化公司,那里任何账户可以拥有0到更多的股份,决策需要三分之二多数的股份同意。一个完整的框架将包括资产管理功能-可以提交买卖股份的订单以及接受这种订单的功能(前提是合约里有订单匹配机制)。代表依然以委任制民主的方式存在,产生了“董事会”的概念。 - -更先进的组织治理机制可能会在将来实现;现在一个去中心化组织(DO)可以从去中心化自治组织(DAO)开始描述。DO和DAO的区别是模糊的,一个大致的分割线是治理是否可以通过一个类似政治的过程或者一个“自动”过程实现,一个不错的直觉测试是“无通用语言”标准:如果两个成员不说同样的语言组织还能正常运行吗?显然,一个简单的传统的持股式公司会失败,而象比特币协议这样的却很可能成功,罗宾·汉森的“futarchy”,一个通过预测市场实现组织化治理的机制是一个真正的说明“自治”式治理可能是什么样子的好例子。注意一个人无需假设所有DAO比所有DO优越;自治只是一个在一些特定场景下有很大优势的,但在其它地方未必可行的范式,许多半DAO可能存在。 - -### 进一步的应用 - -1. **储蓄钱包**。 假设Alice想确保她的资金安全,但她担心丢失或者被黑客盗走私钥。她把以太币放到和Bob签订的一个合约里,如下所示,这合同是一个银行: - * Alice单独每天最多可提取1%的资金。 - * Bob单独每天最多可提取1%的资金,但Alice可以用她的私钥创建一个交易取消Bob的提现权限。 - * Alice 和 Bob 一起可以任意提取资金。 -一般来讲,每天1%对Alice足够了,如果Alice想提现更多她可以联系Bob寻求帮助。如果Alice的私钥被盗,她可以立即找到Bob把她的资金转移到一个新合同里。如果她弄丢了她的私钥,Bob可以慢慢地把钱提出。如果Bob表现出了恶意,她可以关掉他的提现权限。 - -2. **作物保险**。一个人可以很容易地以天气情况而不是任何价格指数作为数据输入来创建一个金融衍生品合约。如果一个爱荷华的农民购买了一个基于爱荷华的降雨情况进行反向赔付的金融衍生品,那么如果遇到干旱,该农民将自动地收到赔付资金而如果有足量的降雨他会很开心因为他的作物收成会很好。 - -3. **一个去中心化的数据发布器**。 对于基于差异的金融合约,事实上通过过“谢林点”协议将数据发布器去中心化是可能的。谢林点的工作原理如下:N方为某个指定的数据提供输入值到系统(例如ETH/USD价格),所有的值被排序,每个提供25%到75%之间的值的节点都会获得奖励,每个人都有激励去提供他人将提供的答案,大量玩家可以真正同意的答案明显默认就是正确答案,这构造了一个可以在理论上提供很多数值,包括ETH/USD价格,柏林的温度甚至某个特别困难的计算的结果的去中心化协议。 - -5.**云计算**。EVM技术还可被用来创建一个可验证的计算环境,允许用户邀请他人进行计算然后选择性地要求提供在一定的随机选择的检查点上计算被正确完成的证据。这使得创建一个任何用户都可以用他们的台式机,笔记本电脑或者专用服务器参与的云计算市场成为可能,现场检查和安全保证金可以被用来确保系统是值得信任的(即没有节点可以因欺骗获利)。虽然这样一个系统可能并不适用所有任务;例如,需要高级进程间通信的任务就不易在一个大的节点云上完成。然而一些其它的任务就很容易实现并行;SETI@home, folding@home和基因算法这样的项目就很容易在这样的平台上进行。 - -6.**点对点赌博**。任意数量的点对点赌博协议都可以搬到以太坊的区块链上,例如Frank Stajano和Richard Clayton的Cyberdice。 最简单的赌博协议事实上是这样一个简单的合约,它用来赌下一个区块的哈稀值与猜测值之间的差额, 据此可以创建更复杂的赌博协议,以实现近乎零费用和无欺骗的赌博服务。 - -7.**预测市场**。 不管是有神谕还是有谢林币,预测市场都会很容易实现,带有谢林币的预测市场可能会被证明是第一个主流的作为去中心化组织管理协议的“futarchy”应用。 - -8.链上去中心化市场,以身份和信誉系统为基础。 - -## 杂项和关注 - -### 改进版幽灵协议的实施 - - “幽灵“协议("Greedy Heaviest Observed Subtree" (GHOST) protocol)是由Yonatan Sompolinsky 和 Aviv Zohar在2013年12月引入的创新。幽灵协议提出的动机是当前快速确认的块链因为区块的高作废率而受到低安全性困扰;因为区块需要花一定时间(设为t)扩散至全网,如果矿工A挖出了一个区块然后矿工B碰巧在A的区块扩散至B之前挖出了另外一个区块,矿工B的区块就会作废并且没有对网络安全作出贡献。此外,这里还有中心化问题:如果A是一个拥有全网30%算力的矿池而B拥有10%的算力,A将面临70%的时间都在产生作废区块的风险而B在90%的时间里都在产生作废区块。因此,如果作废率高,A将简单地因为更高的算力份额而更有效率,综合这两个因素,区块产生速度快的块链很可能导致一个矿池拥有实际上能够控制挖矿过程的算力份额。 - -正如Sompolinsky 和 Zohar所描述的,通过在计算哪条链“最长”的时候把废区块也包含进来,幽灵协议解决了降低网络安全性的第一个问题;这就是说,不仅一个区块的父区块和更早的祖先块,祖先块的作废的后代区块(以太坊术语中称之为“叔区块”)也被加进来以计算哪一个区块拥有支持其的最大工作量证明。我们超越了Sompolinsky 和 Zohar所描述的协议以解决第二个问题 – 中心化倾向,以太坊付给以“叔区块”身份为新块确认作出贡献的废区块87.5%的奖励,把它们纳入计算的“侄子区块”将获得奖励的12.5%,不过,交易费用不奖励给叔区块。 -以太坊实施了一个只下探到第五层的简化版本的幽灵协议。其特点是,废区块只能以叔区块的身份被其父母的第二代至第五代后辈区块,而不是更远关系的后辈区块(例如父母区块的第六代后辈区块,或祖父区块的第三代后辈区块)纳入计算。这样做有几个原因。首先,无条件的幽灵协议将给计算给定区块的哪一个叔区块合法带来过多的复杂性。其次,带有以太坊所使用的补偿的无条件的幽灵协议剥夺了矿工在主链而不是一个公开攻击者的链上挖矿的激励。最后,计算表明带有激励的五层幽灵协议即使在出块时间为15s的情况下也实现了了95%以上的效率,而拥有25%算力的矿工从中心化得到的益处小于3%。 - -### 费用 - -因为每个发布的到区块链的交易都占用了下载和验证的成本,需要有一个包括交易费的规范机制来防范滥发交易。比特币使用的默认方法是纯自愿的交易费用,依靠矿工担当守门人并设定动态的最低费用。因为这种方法是“基于市场的”,使得矿工和交易发送者能够按供需来决定价格,所以这种方法在比特币社区被很顺利地接受了。然而,这个逻辑的问题在于,交易处理并非一个市场;虽然根据直觉把交易处理解释成矿工给发送者提供的服务是很有吸引力的,但事实上一个矿工收录的交易是需要网络中每个节点处理的,所以交易处理中最大部分的成本是由第三方而不是决定是否收录交易的矿工承担的。于是,非常有可能发生公地悲剧。 - -然而,当给出一个特殊的不够精确的简化假设时,这个基于市场的机制的漏洞很神奇地消除了自己的影响。论证如下。假设: - -1. 一个交易带来 k 步操作, 提供奖励 kR给任何收录该交易的矿工,这里 R 由交易发布者设定, k 和 R 对于矿工都是事先(大致上)可见的。 -2. 每个节点处理每步操作的成本都是 C (即所有节点的效率一致)。 -3. 有 N 个挖矿节点,每个算力一致(即全网算力的1/N)。 -4. 没有不挖矿的全节点。 - -当预期奖励大于成本时,矿工愿意挖矿。这样,因为矿工有1/N 的机会处理下一个区块,所以预期的收益是 kR/N , 矿工的处理成本简单为 kC. 这样当 kR/N > kC, 即 R > NC时。矿工愿意收录交易。注意 R 是由交易发送者提供的每步费用,是矿工从处理交易中获益的下限。 NC 是全网处理一个操作的成本。所以,矿工仅有动机去收录那些收益大于成本的交易。 -然而,这些假设与实际情况有几点重要的偏离: - -1. 因为额外的验证时间延迟了块的广播因而增加了块成为废块的机会,处理交易的矿工比其它的验证节点付出了更高的成本。 -2. 不挖矿的全节点是存在的。 -3. 实践中算力分布可能最后是极端不平均的。 -4. 以破坏网络为己任的投机者,政敌和疯子确实存在,并且他们能够聪明地设置合同使得他们的成本比其它验证节点低得多。 -上面第1点驱使矿工收录更少的交易,第2点增加了 NC; 因此这两点的影响至少部分互相抵消了. 第3点和第4点是主要问题;作为解决方案我们简单地建立了一个浮动的上限:没有区块能够包含比BLK_LIMIT_FACTOR 倍长期指数移动平均值更多的操作数。具体地: - -`blk.oplimit = floor((blk.parent.oplimit * (EMAFACTOR - 1) + floor(parent.opcount * BLK_LIMIT_FACTOR)) /EMA_FACTOR)` - -BLK_LIMIT_FACTOR 和 EMA_FACTOR 是暂且被设为 65536 和 1.5 的常数,但可能会在更深入的分析后调整。 -回复 - -### 计算和图灵完备 - -需要强调的是以太坊虚拟机是图灵完备的; 这意味着EVM代码可以实现任何可以想象的计算,包括无限循环。EVM代码有两种方式实现循环。首先, JUMP 指令可以让程序跳回至代码前面某处,还有允许如 `while x < 27: x = x * 2 ` 一样的条件语句的JUMPI 指令实现条件跳转。其次,合约可以调用其它合约,有通过递归实现循环的潜力。这很自然地导致了一个问题:恶意用户能够通过迫使矿工和全节点进入无限循环而不得不关机吗? 这问题出现是因为计算机科学中一个叫停机问题的问题:一般意义上没有办法知道,一个给定的程序是否能在有限的时间内结束运行。 - -正如在状态转换章节所述,我们的方案通过为每一个交易设定运行执行的最大计算步数来解决问题,如果超过则计算被恢复原状但依然要支付费用。消息以同样的方式工作。为显示这一方案背后的动机,请考虑下面的例子: - -* 一个攻击者创建了一个运行无限循环的合约,然后发送了一个激活循环的交易给矿工,矿工将处理交易,运行无限循环直到瓦斯耗尽。即使瓦斯耗尽交易半途停止,交易依然正确(回到原处)并且矿工依然从攻击者哪里挣到了每一步计算的费用。 -* 一个攻击者创建一个非常长的无限循环意图迫使矿工长时间内一直计算致使在计算结束前若干区块已经产生于是矿工无法收录交易以赚取费 用。然而,攻击者需要发布一个 STARTGAS 值以限制可执行步数,因而矿工将提前知道计算将耗费过多的步数。 -* 一个攻击者看到一个包含诸如 send(A,self.storage); self.storage = 0格式的合约然后发送带有只够执行第一步的费用的而不够执行第二步的交易(即提现但不减少账户余额)。合约作者无需担心防卫类似攻击,因为如果执行中途停止则所有变更都被回复。 -* 一个金融合约靠提取九个专用数据发布器的中值来工作以最小化风险,一个攻击者接管了其中一个数据提供器,然后把这个按DAO章节所述的可变地址调用机制设计成可更改的数据提供器转为运行一个无限循环,以求尝试逼迫任何从此金融合约索要资金的尝试都会因瓦斯耗尽而中止。然而,该金融合约可以在消息里设置瓦斯限制以防范此类问题。 -图灵完备的替代是图灵不完备,这里 JUMP 和 JUMPI 指令不存在并且在某个给定时间每个合约只允许有一个拷贝存在于调用堆栈内。在这样的系统里,上述的费用系统和围绕我们的方案的效率的不确定性可能都是不需要的,因为执行一个合约的成本将被它的大小决定。此外,图灵不完备甚至不是一个大的限制,在我们内部设想的所有合约例子中,至今只有一个需要循环,而且即使这循环也可以被26个单行代码段的重复所代替。考虑到图灵完备带来的严重的麻烦和有限的益处,为什么不简单地使用一种图灵不完备语言呢?事实上图灵不完备远非一个简洁的解决方案。为什么?请考虑下面的合约: - -```python -C0: call(C1); call(C1); -C1: call(C2); call(C2); -C2: call(C3); call(C3); -... -C49: call(C50); call(C50); -C50: (作一个图灵机的步计算和记录结果在合约的长期存储) -``` - -现在,发送一个这样的交易给A,这样,在51个交易中,我们有了一个需要花费2^50 步计算的合约,矿工可能尝试通过为每一个合约维护一个最高可执行步数并且对于递归调用其它合约的合约计算可能执行步数从而预先检测这样的逻辑炸弹,但是这会使矿工禁止创建其它合约的合约(因为上面26个合约的创建和执行可以很容易地放入一个单独合约内)。另外一个问题点是一个消息的地址字段是一个变量,所以通常来讲可能甚至无法预先知道一个合约将要调用的另外一个合约是哪一个。于是,最终我们有了一个惊人的结论:图灵完备的管理惊人地容易,而在缺乏同样的控制时图灵不完备的管理惊人地困难- 那为什么不让协议图灵完备呢? - -### 货币和发行 - -以太坊网络包含自身的内置货币以太币,以太币扮演双重角色,为各种数字资产交易提供主要的流动性,更重要的是提供了了支付交易费用的一种机制。为便利及避免将来的争议期间(参见当前的mBTC/uBTC/聪的争论),不同面值的名称将被提前设置: - -* 1: 伟 -* 10^12: 萨博 -* 10^15: 芬尼 -* 10^18: 以太 - -这应该被当作是“元”和“分”或者“比特币”和“聪”的概念的扩展版,在不远的将来,我们期望“以太”被用作普通交易,“芬尼”用来进行微交易,“萨博”和“伟”用来进行关于费用和协议实施的讨论。 - -发行模式如下: - -* 通过发售活动,以太币将以每BTC 1337-2000以太的价格发售,一个旨在为以太坊组织筹资并且为开发者支付报酬的机制已经在其它一些密码学货币平台上成功使用。早期购买者会享受较大的折扣,发售所得的BTC将完全用来支付开发者和研究者的工资和悬赏,以及投入密码学货币生态系统的项目。 -* 0.099x (x为发售总量)将被分配给BTC融资或其它的确定性融资成功之前参与开发的早期贡献者,另外一个0.099x将分配给长期研究项目。 -* 自上线时起每年都将有0.26x(x为发售总量)被矿工挖出。 - -### 发行分解 -永久线性增长模型降低了在比特币中出现的财富过于集中的风险,并且给予了活在当下和将来的人公平的机会去获取货币,同时保持了对获取和持有以太币的激励,因为长期来看“货币供应增长率”是趋于零的。我们还推断,随着时间流逝总会发生因为粗心和死亡等原因带来的币的遗失,假设币的遗失是每年货币供应量的一个固定比例,则最终总的流通中的货币供应量会稳定在一个等于年货币发行量除以遗失率的值上(例如,当遗失率为1%时,当供应量达到30x时,每年有0.3x被挖出同时有0.3x丢失,达到一个均衡)。 - -![](http://bitcoin8btc.qiniudn.com/wp-content/uploads/2014/10/table.png) -除了线性的发行方式外,和比特币一样以太币的的供应量增长率长期来看也趋于零。 - -![](http://bitcoin8btc.qiniudn.com/wp-content/uploads/2014/10/supply.png) - -### 挖矿的中心化 - -比特币挖矿算法基本上是让矿工千万次地轻微改动区块头,直到最终某个节点的改动版本的哈希小于目标值(目前是大约2190)。然而,这种挖矿算法容易被两种形式的中心化攻击。第一种,挖矿生态系统被专门设计的因而在比特币挖矿这一特殊任务上效率提高上千倍的ASICs(专用集成电路)和电脑芯片控制。这意味着比特币挖矿不再是高度去中心化的和追求平等主义的,而是需要巨额资本的有效参与。第二种,大部分比特币矿工事实上不再在本地完成区块验证;而是依赖中心化的矿池提供区块头。这个问题可以说很严重:在本文写作时,最大的两个矿池间接地控制了大约全网50%的算力,虽然当一个矿池或联合体尝试51%攻击时矿工可以转换到其它矿池这一事实减轻了问题的严重性。 - -以太坊现在的目的是使用一个基于为每1000个随机数随机产生唯一哈希的函数的挖矿算法,用足够宽的计算域,去除专用硬件的优势。这样的策略当然不会使中心化的收益减少为零,但是也不需要。注意每单个用户使用他们的私人笔记本电脑或台式机就可以几乎免费地完成一定量的挖矿活动,但当到了100%的CPU使用率之后更多地挖矿就会需要他们支付电力和硬件成本。ASIC挖矿公司需要从第一个哈希开始就为电力和硬件支付成本。所以,如果中心化收益能够保持在(E + H) /E 以下,那么即使ASICs被制造出来普通矿工依然有生存空间。另外,我们计划将挖矿算法设计成挖矿需要访问整个区块链,迫使矿工存储完成的区块链或者至少能够验证每笔交易。这去除了对中心化矿池的需要;虽然矿池依然可以扮演平滑收益分配的随机性的角色,但这功能可以被没有中心化控制的P2P矿池完成地同样好。这样即使大部分普通用户依然倾向选择轻客户端,通过增加网络中的全节点数量也有助于抵御中心化。 - -### 扩展性 - -扩展性问题是以太坊常被关注的地方,与比特币一样,以太坊也遭受着每个交易都需要网络中的每个节点处理这一困境的折磨。比特币的当前区块链大小约为20GB,以每小时1MB的速度增长。如果比特币网络处理Visa级的2000tps的交易,它将以每三秒1MB的速度增长(1GB每小时,8TB每年)。以太坊可能也会经历相似的甚至更糟的增长模式,因为在以太坊区块链之上还有很多应用,而不是像比特币只是简单的货币,但以太坊全节点只需存储状态而不是完整的区块链历史这一事实让情况得到了改善。 - -大区块链的问题是中心化风险。如果块链大小增加至比如100TB,可能的场景将是只有非常小数目的大商家会运行全节点,而常规用户使用轻的SPV节点。这会增加对全节点合伙欺诈牟利(例如更改区块奖励,给他们自己BTC)的风险的担忧。轻节点将没有办法立刻检测到这种欺诈。当然,至少可能存在一个诚实的全节点,并且几个小时之后有关诈骗的信息会通过Reddit这样的渠道泄露,但这时已经太晚:任凭普通用户做出怎样的努力去废除已经产生的区块,他们都会遇到与发动一次成功的51%攻击同等规模的巨大的不可行的协调问题。在比特币这里,现在这是一个问题,但Peter Todd建议的一个改动可以缓解这个问题。 - -近期,以太坊会使用两个附加的策略以应对此问题。首先,因为基于区块链的挖矿算法,至少每个矿工会被迫成为一个全节点,这保证了一定数量的全节点。其次,更重要的是,处理完每笔交易后,我们会把一个中间状态树的根包含进区块链。即使区块验证是中心化的,只要有一个诚实的验证节点存在,中心化的问题就可以通过一个验证协议避免。如果一个矿工发布了一个不正确的区块,这区块要么是格式错,要么状态S[n]是错的。因为S[0]是正确的,必然有第一个错误状态S[i]但S[i-1]是正确的,验证节点将提供索引i,一起提供的还有处理APPLY(S[i-1],TX[i]) -> S[i]所需的帕特里夏树节点的子集。这些节点将受命进行这部分计算,看产生的S[i]与先前提供的值是否一致。 - -另外,更复杂的是恶意矿工发布不完整区块进行攻击,造成没有足够的信息去确定区块是否正确。解决方案是质疑-回应协议:验证节点对目标交易索引发起质疑,接受到质疑信息的轻节点会对相应的区块取消信任,直到另外一个矿工或者验证者提供一个帕特里夏节点子集作为正确的证据。 - -## 综述:去中心化应用 - - - -上述合约机制使得任何一个人能够在一个虚拟机上建立通过全网共识来运行命令行应用(从根本上来说是),它能够更改一个全网可访问的状态作为它的“硬盘”。然而,对于多数人来说,用作交易发送机制的命令行接口缺乏足够的用户友好使得去中心化成为有吸引力的替代方案。最后,一个完整的“去中心化应用”应该包括底层的商业逻辑组件【无论是否在以太坊完整实施,使用以太坊和其它系统组合(如一个P2P消息层,其中一个正在计划放入以太坊客户端)或者仅有其它系统的方式】和上层的图形用户接口组件。以太坊客户端被设计成一个网络浏览器,但包括对“eth” Javascript API对象的支持,可被客户端里看到的特定的网页用来与以太坊区块链交互。从“传统”网页的角度看来,这些网页是完全静态的内容,因为区块链和其它去中心化协议将完全代替服务器来处理用户发起的请求。最后,去中心化协议有希望自己利用某种方式使用以太坊来存储网页。 - -## 结论 - - - -以太坊协议最初是作为一个通过高度通用的语言提供如链上契约,提现限制和金融合约,赌博市场等高级功能的升级版密码学货币来构思的。以太坊协议将不直接“支持”任何应用,但图灵完备编程语言的存在意味着理论上任意的合约都可以为任何交易类型和应用创建出来。然而关于以太坊更有趣的是,以太坊协议比单纯的货币走得更远,围绕去中心化存储,去中心化计算和去中心化预测市场以及数十个类似概念建立的协议和去中心化应用,有潜力从根本上提升计算行业的效率,并通过首次添加经济层为其它的P2P协议提供有力支撑,最终,同样会有大批与金钱毫无关系的应用出现。 - -以太坊协议实现的任意状态转换概念提供了一个具有独特潜力的平台;与封闭式的,为诸如数据存储,赌博或金融等单一目的设计的协议不同,以太坊从设计上是开放式的,并且我们相信它极其适合作为基础层服务于在将来的年份里出现的极其大量的金融和非金融协议。 - -## 注解与进阶阅读 - -### 注解 - -1.一个有经验的读者会注意到事实上比特币地址是椭圆曲线公钥的哈希,而非公钥本身,然而事实上从密码学术语角度把公钥哈希称为公钥完全合理。这是因为比特币密码学可以被认为是一个定制的数字签名算法,公钥由椭圆曲线公钥的哈希组成,签名由椭圆曲线签名连接的椭圆曲线公钥组成,而验证算法包括用作为公钥提供的椭圆曲线公钥哈希来检查椭圆曲线公钥,以及之后的用椭圆曲线公钥来验证椭圆曲线签名。 - -2.技术上来说,前11个区块的中值。 - -3.在内部,2和“CHARLIE”都是数字,后一个有巨大的base256编码格式,数字可以从0到2^256-1。 - -### 进阶阅读 - -1. Intrinsic value: https://tinyurl.com/BitcoinMag-IntrinsicValue - -2. Smart property: https://en.bitcoin.it/wiki/Smart_Property - -3. Smart contracts: https://en.bitcoin.it/wiki/Contracts - -4. B-money: http://www.weidai.com/bmoney.txt - -5. Reusable proofs of work: http://www.finney.org/~hal/rpow/ - -6. Secure property titles with owner authority: http://szabo.best.vwh.net/securetitle.html - -7. Bitcoin whitepaper: http://bitcoin.org/bitcoin.pdf - -8. Namecoin: https://namecoin.org/ - -9. Zooko’s triangle: http://en.wikipedia.org/wiki/Zooko’s_triangle - -10. Colored coins whitepaper: https://tinyurl.com/coloredcoin-whitepaper - -11. Mastercoin whitepaper: https://github.com/mastercoin-MSC/spec - -12. Decentralized autonomous corporations, Bitcoin Magazine: https://tinyurl.com/Bootstrapping-DACs - -13. Simplified payment verification:https://en.bitcoin.it/wiki/Scalability#Simplifiedpaymentverification - -14. Merkle trees: http://en.wikipedia.org/wiki/Merkle_tree - -15. Patricia trees: http://en.wikipedia.org/wiki/Patricia_tree - -16. GHOST: http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf - -17. StorJ and Autonomous Agents, Jeff Garzik: https://tinyurl.com/storj-agents - -18. Mike Hearn on Smart Property at Turing Festival: http://www.youtube.com/watch?v=Pu4PAMFPo5Y - -19. Ethereum RLP: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP - -20. Ethereum Merkle Patricia trees: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree - -21. Peter Todd on Merkle sum trees:http://sourceforge.net/p/bitcoin/mailman/message/31709140/ \ No newline at end of file diff --git a/pages/other-languages/[french]-ethereum-toc.md b/pages/other-languages/[french]-ethereum-toc.md deleted file mode 100644 index 85eeef455..000000000 --- a/pages/other-languages/[french]-ethereum-toc.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -name: Ethereum TOC -category: ---- - -# Contrats Intelligents et Plateforme d'Application Décentralisée de nouvelle génération - -Lorsque Satoshi Nakamoto lance Bitcoin le premier réseaux décentralisé cryptographié (Blockchain) en Janvier 2009, il introduit simultanément deux concepts radicaux et très incertains. Le premier est le " bitcoin " , une monnaie décentralisée peer-to-peer qui conserve une valeur sans support financier d'un emetteur centralisé, ni valeur intrinsèque. Jusqu'à présent, le "bitcoin" comme monnaie a retenu l'essentiel de l'attention du public. D'une part en termes d'aspects politiques d'une monnaie sans banque centrale et d'autre part, à cause de son extrême volatilité à la hausse et à la baisse des prix. Le second concept, tout aussi important, qui emerge de l'expérience de Satoshi : un accord public sur l'ordre des transactions sous forme de preuve de travail, le Blockchain. Bitcoin peut être décrit comme un système du «premier à déposer son action» : si une entité dispose 50 BTC et envoie simultanément à A et à B la meme somme 50 BTC, seule l'opération qui sera validée en premiere sera confirmée. En partant de deux opérations, il n'existe pas de methode pour déterminer laquelle est venue en premiere, et pendant des décennies ce manque a entravé le développement d'une monnaie numérique décentralisée . Le blockchain de Satoshi était la première solution décentralisée crédible. Désormais, l'attention commence rapidement à se déplacer vers cette deuxième partie de la technologie, et vers l'utilisation du concept de blockchain pour autre chose que de l'argent. - -Les applications les plus communément citées utilisent un avoir numérique sur le blockchain pour représenter des monnaies et instruments financiers sur-mesure ("colored coins"), la proprieté d'un actif sous-jacent ("smart property"), des actifs non-fongible comme les noms de domaine ("Namecoin") ainsi que des applications plus développées comme une plateforme de bourse décentralisée, de dérivés financiers, de jeux en ligne P2P, d'identité ou de reputation. Un autre domaine important de recherche : les systèmes de "smart contracts" qui transfèrent des actifs numériques selon des règles préétablies. Par exemple, un contract de liquidité pourrait avoir la forme : "A peut retirer un montant X de ses fonds par jours, B peut retirer Y par jours, ensemble A et B peuvent retirer ce qu'ils désirent, enfin A peut restreindre l'habilité de B d'avoir accès à ses fonds. L'extension logique de ce qui précède est l'Organisation Autonome Décentralisée (OAD) - Des contracts intelligents qui contiennent les actifs et les statuts de l'organisation tout entière. Ethereum aspire à fournir un Blockchain fondé sur un language de programmation Turing-complet à part entière qui peut être utilisé pour créer des contracts qui encodent des fonctions d'états de transition arbitraire, permettant à l'utilisateur de créer les systèmes décris précédemment, ainsi que de nombreuses applications que nous n'avons pas encore imaginées, en rédigeant une suite logique en quelques lignes de code. - - - -**Table des matières :** - -1. Histoire -1.1. Bitcoin comme système d'états transitoires -1.2. Mining -1.3. Arbre de Merkle -1.4. Application alternative sur le blockchain -1.5. Scripting - - -2. Ethereum -2.1 Compte Ethereum -2.2 Messages and Transactions -2.3 Fonction de Transition d'Etat Ethereum -2.4 Code d'Execution -2.5 Blockchain et Mining - -3. Applications -3.1 Monnaies -3.2 Dérivés Financiers -3.3 Système d'Identité et de Reputation -3.4 Stockage de Fichiers Décentralisé -3.5 Organisation Autonome décentralisée -3.6 Nouvelles applications - -4. Miscellanées et préoccupations -4.1 Mise en oeuvre GHOST modifiée -4.2 Commissions -4.3 Calculs et Turing-Complet -4.4 Monnaie et émission de monnaie -4.5 Centralisation du minage -4.6 Extensibilité du modèle - -5. Conclusion -5.1 References et suggestions de lecture - - - -**Histoire** - -Le concept d'une monnaie digitale décentralisée, ainsi que les applications alternatives comme l'enregistrement de propriétés, existe depuis des décennies. Les protocols anonymes de monnaie éléctronique des années 1980 et 1990, principalement dépendant de cryptographie primitive connue sous le nom de signature aveugle de Chaum (Chaumian blinding), proposaient une monnaie avec un haut degré de confidentialité. Cependant, le protocole reposait sur un intermediaire centralisé, ce qui freina son adoption. En 1998, Wei Dai introduit b-money, la premiere proposition à introduire la création de monnaie par la résolution de problemes informatiques et un consensus décentralisé. En 2005, Hal Finney introduit le concept de preuves de travail réutilisables "reusable proofs of work", mêlant les travaux de recherche sur b-money à la résolution de la preuve de Hashcash pour créer le concept de cryptomonnaie. Encore une fois le système reposait sur un tiers. - -Parce qu'une monnaie repose sur le système du premier-déposant, où l'ordre de transaction est souvent d'une importance critique, une monnaie décentralisée requiert une solution provenant d'un consensus décentralisé. Les pré-Bitcoins ont dû faire face à l'obstacle de ne résoudre que la moitié du problème en se concentrant, pendant plusieurs années, sur la création d'un consensus multi-partie tolerant les pannes Byzantines. Les protocoles supposaient que tous les participants du système étaient connus et généraient des marges de sécurité de la forme : "S'il y a N Participants, Alors le système peut tolérer N/4 participants malicieux". Toutefois, dans un tel système, les marges de sécurité sont vulnérables aux attaques Sybil, où un individu peut créer des milliers de noeuds simulés sur un serveur ou un botnet et les utiliser pour sécuriser une part majoritaire. - -Satoshi innova en proposant l'association d'un protocol de consensus décentralisé très simple, basé sur des noeuds combinant les transactions dans un 'bloc" toutes les dix minutes créant une chaine de blocs ("blockchain") en expansion permanente, à la preuve de travail ("proof of work") comme mechanisme par lequel les noeuds gagnent le droit de participer au système. Tandis que les noeuds disposant d'une grande capacité de calcul ont une influence proportionnelle, il est plus facile de créer un million de noeuds que de concevoir une puissance de calcul supérieure à la moitié du réseaux. Malgré sa simplicité et sa crudité, le modèle de chaine de bloc du Bitcoin a su s'imposer, et pourrait être le berceau dans les cinq prochaines années de plusieurs centaines de monnaies et de protocols à travers le monde. - - -**Bitcoin comme système d'états transitoires** - -D'un point de vue technique, le registre de Bitcoin peut être perçu comme un système de transition d'états, où: -- Chaque "état" représente le statut de propriété de toutes les bitcoins qui existent. -- Une fonction de transition d'états prenant un état et une transaction, et produisant un nouvel état comme résultat. - -Dans un système bancaire traditionnel par exemple: -- L'état a un instant t serait un bilan financier -- Une transaction serait une requête de transfert de $X de A vers B -- La fonction de transition d'états réduirait le compte de A de $X et augmenterait celui de B de $X. Si A n'avait pas suffisamment de fonds, la fonction retournerait une erreur. - -Par conséquent, on peut formellement définir: - - APPLIQUER(S,TX) -> S' ou ERREUR - -Dans l'exemple précédent: - - APPLIQUER({ Alice: $50, Bob: $50 },"envoyer $20 de Alice vers Bob") = { Alice: $30, Bob: $70 } - -Mais - - APPLIQUER({ Alice: $50, Bob: $50 },"envoyer $70 de Alice vers Bob") = ERREUR - -L'"état" global dans Bitcoin est l'ensemble de toutes les "pièces" (bitcoins, en termes techniques ce sont des "Données de sorties de transactions non-depensées" ou unspent transaction outputs/UTXO en anglais). Chaque pièce a une valeur et un propriétaire (définie par une adresse de 20 octets qui correspond essentiellement a une clé publique de cryptographie). Une transaction contient une ou plusieurs données en entrée, avec chaque données contenant une référence a une UTXO existante et une signature cryptographique produite par la clé privée associée au propriétaire de l'adresse, et une ou plusieurs données de sortie telles que chacune contient une nouvelle UTXO a rajouter a l'état global. - -WIP (translating https://github.com/ethereum/wiki/wiki/White-Paper#bitcoin-as-a-state-transition-system) - -Signature Aveugle de Chaum : -http://www.hit.bme.hu/~buttyan/courses/BMEVIHIM219/2009/Chaum.BlindSigForPayment.1982.PDF -Hashcash : -http://fr.wikipedia.org/wiki/Hashcash -Attaque Sybil : -http://en.wikipedia.org/wiki/Sybil_attack \ No newline at end of file diff --git a/pages/other-languages/[german]-ethereum-toc.md b/pages/other-languages/[german]-ethereum-toc.md deleted file mode 100644 index 27b457994..000000000 --- a/pages/other-languages/[german]-ethereum-toc.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -name: Ethereum TOC -category: ---- - -### Willkommen bei Ethereum, der nächsten Generation von elektronischen Verträgen und der Plattform für dezentrale Anwendungen. - -[Ethereum whitepaper](https://github.com/ethereum/wiki/wiki/%5BGerman%5D-White-Paper) - -[RLP](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP), die Recursive Linear Prefix - Spezifikation für Kodierung der Daten ation, used for data encoding bei Ethereum. - -[Patricia Tree](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree), die Spezifikation des Merkle Patricia Baums (aka Trie), die Struktur zum Speichern und Hashen der Blockkette in Ethereum. - -[Wire protocol](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Wire-Protocol) Spezifikation. - -[CLL](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-CLL), die Spezifikation der "C-ähnlichen Programmiersprache" für die Gestaltung von Verträgen. - -[Dagger](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Dagger), die "proof-of-work" Spezifikation Ethereums. - -[Block Protocol 2.0](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Block-Protocol-2.0) - -[Layers](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Layers) - -[Clearinghaus](https://github.com/ethereum/wiki/wiki/%5BGerman%5D-Clearinghaus) diff --git a/pages/other-languages/[german]-rlp.md b/pages/other-languages/[german]-rlp.md deleted file mode 100644 index fd165990d..000000000 --- a/pages/other-languages/[german]-rlp.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -name: RLP -category: ---- - -Der Zweck von RLP ist es, beliebig verschachtelte Arrays von binären Daten zu kodieren. RLP wird als Hauptcodierungsverfahren verwendet, um Objekte in Ethereum in serieller Reihenfolge zu kodieren. Das heisst RLP kodiert Strukturen, spezielle Datentypen wie [Strings] (http://de.wikipedia.org/wiki/Zeichenkette), [Integers] (http://de.wikipedia.org/wiki/Integer_%28Datentyp%29) und [Floats] (http://de.wikipedia.org/wiki/Gleitkommazahl), bis hin zu höheren Protokollebenen. Integer werden in Ethereum standardmäßig im [Big Endian] (http://de.wikipedia.org/wiki/Byte-Reihenfolge) Binärfomat verarbeitet. -Wenn man RLP z.B. zum Kodieren eines Wörterbuchs verwendet, sind die beiden vorgeschalgenen Standardformen entweder `[[k1, v1], [k2, v2] ...]` mit Schlüsselwörtern in lexikographische Ordnung oder besser die Kodierung des [Patricia Baums] (https://github.com/ethereum/wiki/wiki/Patricia-Tree) (wie es Ethereum tut). - -### Definition -Die RLP-Koding erfolgt in einem Element. Ein Element wird wie folgt definiert: - -* Ein String (z.B. eine Byte Array) ist ein Element -* Eine Liste von Elementen ist ein Elemet - -Elemente können z.B. sein: -- ein leerer String -- ein String mit dem Wort "cat" -- eine Liste von beliebig vielen anderen Zeichen -- komplexere Daten wie `["cat",["puppy","cow"],"horse",[[]],"pig",[""],"sheep"]`. - -Bitte beachten: In dem Rest dieses Artikels wird "String" als Synonym für "eine bestimmte Anzahl von Bytes von binären Daten" verwendet. Es wird keine besondere Kodierung betrachtet und auch nichts über den Inhalt des Strings ausgesagt. - -Die RLP-Kodierung funktioniert wie folgt: -* Für ein einzelnes Byte innerhalb des Bereiches `[0x00, 0x7f]` erfolgt eine individuelle RLP-Kodierung. -* Ist ein String 0 bis 55 Byte lang enthält die RLP-Kodierung den Wert **0x80** + die Länge des Strings, gefolgt vom Stringinhalt. Der Wertebereich des ersten Bytes ist `[0x80, 0xb7]`. -* Ist ein String länger als 55 Byte, enthält die RLP-Kodierung das erste Byte mit dem Wert **0xb7** + die Länge für String+Stringlänge in Binärformat, gefolgt von der Länge des Strings, gefolgt vom Stringinhalt. Z.B. ein 1024 Byte langer String wird kodiert als `\xb9\x04\x00` gefolgt vom Stringinhalt. Der Wertebereich des ersten Bytes ist `[0xb8, 0xbf]`. -* Ist die Gesamtlänge der Nutzdaten einer Liste (z.B. die kombinierte Länge aller Elemente) zwischen 0 und 55 Bytes, enthält die RLP-Kodierung das Byte mit dem Inhalt **0xc0** + die Länge der Liste, gefolgt von der Verkettung der RLP-Kodierungen der Elemente. Der Wertebereich des ersten Bytes ist `[0xc0, 0xf7]`. -* Ist die Gesamtlänge der Nutzdaten einer Liste mehr als 55 Byte, enthält die RLP-Kodierung das Byte mit dem Inhalt **0xf7** + die Länge für Liste+Listenlänge in Binärformat, gefolgt von der Länge der Liste, gefolgt von der Verkettung der RLP-Kodierungen der Elemente. Der Wertebereich des ersten Bytes ist `[0xf8, 0xff]`. -Als Code sieht das so aus: -```python -def rlp_encode(input): - if isinstance(input,str): - if len(input) == 1 and chr(input) < 128: return input - else: return encode_length(len(input),128) + input - elif isinstance(input,list): - output = encode_length(len(input),192) - for item in input: output += rlp_encode(item) - return output -def encode_length(L,offset): - if L < 56: - return chr(L + offset) - elif L < 256**8: - BL = to_binary(L) - return chr(len(BL) + offset + 55) + BL - else: - raise Exception("input too long") -def to_binary(x): - return '' if x == 0 else to_binary(int(x / 256)) + chr(x % 256) -``` -### Beispiele - -Der String "dog" = [ 0x83, 'd', 'o', 'g' ] - -Die Liste [ "cat", "dog" ] = `[ 0xc8, 0x83, 'c', 'a', 't', 0x83, 'd', 'o', 'g' ]` - -Der leere String ('null') = `[ 0x80 ]` - -Die leere Liste = `[ 0xc0 ]` - -Der Integer 15 = `[ 0x0f ]` - -Der Integer 1024 = `[ 0x82, 0x04, 0x00 ]` - -Die [mengentheoretischen Darstellung] (http://en.wikipedia.org/wiki/Set-theoretic_definition_of_natural_numbers) von zwei, `[ [], [[]], [ [], [[]] ] ] = [ 0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc1, 0xc0 ]` - -Der String "Lorem ipsum dolor sit amet, consectetur adipisicing elit" = `[ 0xb8, 0x38, 'L', 'o', 'r', 'e', 'm', ' ', ... , 'e', 'l', 'i', 't' ]` diff --git a/pages/other-languages/[german]-white-paper.md b/pages/other-languages/[german]-white-paper.md deleted file mode 100644 index 6c12efa95..000000000 --- a/pages/other-languages/[german]-white-paper.md +++ /dev/null @@ -1,630 +0,0 @@ ---- -name: White Paper -category: ---- - -### Ethereum: Die nächste Generation elektronischer Verträge und die Plattform für dezentrale Anwendungen - -Als Satoshi Nakamoto Anfang 2009 zum ersten Mal die Bitcoin-Blockchain in Gang setzte stellte er mit dieser Veröffentlichung zwei fundamentale und bislang ungetestete Konzepte vor. Das erste Konzept ist „Bitcoin“, eine dezentrale Peer-to-Peer Onlinewährung, die ihren Wert behält, obwohl sie durch nichts hinterlegt ist, keinen intrinsischen Wert besitzt und von keiner zentralen Instanz herausgegeben wird. Bis jetzt hat Bitcoin als Währung den Großteil der öffentlichen Aufmerksamkeit auf sich gezogen. Vor allem die politischen Aspekte einer Währung ohne herausgebende Zentralbank als auch die extreme Volatilität der Bitcoins sorgten für medialen Aufruhr. Satoshis großartiges Experiment beinhaltet jedoch ein zweites, ebenso wichtiges Konzept: Die Idee einer auf Proof-of-Work basierenden Blockchain, die es erlaubt, allgemeine Übereinstimmung über die Reihenfolge von Transaktionen zu finden. Anwendungstechnisch kann Bitcoin als First-to-File System beschrieben werden. Wenn beispielsweise Instanz A 50 BTC besitzt und diese gleichzeitig an Instanz B und C versendet wird nur diejenige Transaktion verarbeitet, die zuerst bestätigt wird. Die Problemstellung, dass es keinen inhärenten Weg gibt um festzustellen, welche Transaktion zuerst ausgeführt wurde, behinderte jahrzzehntelang die Entwicklung eines dezentralen digitalen Zahlungsmittels. Satoshis Blockchain ist die erste ernstzunehmende dezentrale Lösung. Nun ist der Zeitpunkt erreicht, an dem sich das öffentliche Interesse immer mehr diesem zweiten Teil der Bitcoin-Technologie zuwendet. Die zentrale Frage lautet, wie das Konzept der Blockchain für Anwendungen abseits einer reinen Währung verwendet werden kann. - -In den letzten Monaten war ein großes Interesse an der Verwendung von Blockketten (wie beim Bitcoin) zu verzeichnen, die einen Mechanismus darstellen, der es der ganzen Welt erlaubt, sich über den Status von Dingen in einer öffentlichen Eigentumsdatenbank einig zu sein - und das für mehr Dinge als nur für Geld. -Die am häufigsten genannten Anwendungen bei der Nutzung von Online-Blockketten sind - -* digitale Wertanlagen, wie benutzerdefinierte Währungen oder Finanzinstrumente ("Farbige Münzen / Colored Coins"), -* "Elektronische Besitzstände / smart property" Dinge wie Autos, die einen "Colored Coin" in der Blockkette verfolgen, um den gegenwärtigen legitimen Besitzer festzustellen, -* erweiterte Anwendungen wie dezentrale Tauschbörsen, Finanzderivate, Peer-to-Peer-Glücksspiele, -* Online-Blockketten basierte Identitätsnachweise und Reputationssysteme. - -Die möglicherweise ambitionierteste aller Anwendungen ist das Konzept der autonomen Vermittlung oder die [Dezentrale Autonome Organisation] (http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/) (DAO) - autonome Instanzen, die auf Basis der Blockchain ohne jegliche zentrale Kontrolle und unter Verzicht auf alle Abhängigkeit von Rechtsverträgen und Organisationssatzungen operieren. *?Und dies zu Gunsten / zu Lasten von Ressourcen und Mitteln?*...autonom verwaltet durch Selbstregulierung der "Smart-Contracts" auf Basis einer kryptografischen Blockkette. - -Wie auch immer, die meisten derartiger Anwendungen sind heute schwierig zu implementieren, einfach wegen der Programmsprache des Bitcoin. Gerade die Protokolle der Kryptowährungen der nächsten Generation wie das Bitcoin-basierte Protokoll der "Colored Coins", auch "Metacoins" genannt, sind viel zu eingeschränkt, um diese Art von beliebig komplexen Berechnungen, wie sie für DAOs nötig sind, zu erlauben. - -Was dieses Projekt zu tun beabsichtigt, ist sich der Innovationen zu bedienen, die solche Protokolle mit sich bringen, sie zu vereinheitlichen, -einen vollwertigen *?TURING -vervollständigt?* (aber stark gebührenregulierten) kryptographischen Registers zu erstellen, welches es den Beteiligten erlaubt, beliebig komplexe Verträge, autonome Vermittlungen und Beziehungen zu kodieren, die vollständig über der Blockkette ausgehandelt werden. -Anstatt sich auf einen bestimmten Satz von Transaktionstypen zu beschränken, werden die Nutzer in der Lage sein, Ethereum wie eine Art "Lego für Krypto-Finanzsysteme" zu verwenden. Das heißt man wird in die Lage versetzt, jedes Leistungsmerkmal einfach durch Codierung mit der internen Skriptsprache des Protokolls zu implementieren. -Kundenspezifische Währungen, Finanzderivate, Identitätssysteme und dezentralisierte Organisationen werden einfach machbar sein, aber wichtiger, im Gegensatz zu früheren Systemen wird es ebenfalls möglich sein Transaktionstypen zu konstruieren, die sich die Entwickler von Ethereum heute noch nicht vorstellen können. -Alles in allem glauben wir, dass dieses Design ein großer Schritt in Richtung der Realisierung von "Cryptocurrency 2.0" ist und wir hoffen, dass Astraleums ein signifikanter Beitrag zum Cryptocurrency Ökosystem wird, wie es das Aufkommen von Web 2.0 wa, in Kontrast zum statischen-content-Internet von 1999. - - -### Inhaltsverzeichnis - -* [Warum eine neue Plattform?] (#warum-eine-neue-plattform?) - * [Colored Coins] (#colored-coins) - * [Metacoins] (#metacoins) -* [Philosophie](#philosophy) -* [Grundbeusteine](#basic-building-blocks) - * [Modifizierte GHOST Implementierung](#modified-ghost-implementation) - * [Ethereum Client P2P Protokoll](#ethereum-client-p2p-protocol) - * [Währunge und Währungsausgabe](#currency-and-issuance) - * [Datenformat](#data-format) - * [Mining Algorithmus](#mining-algorithm) - * [Transaktionen](#transactions) - * [Justierung des Schwierigkeitsgrades (Difficulty)](#difficulty-adjustment) - * [Belohung (Block Rewards)](#block-rewards) -* [Verträge](#contracts) - * [Anwendungen](#applications) - * [Unterwährungen](#sub-currencies) - * [Finanzderivate](#financial-derivatives) - * [Identifizierugs- und Reputationsysteme](#identity-and-reputation-systems) - * [Dezentrale Autonome Organisation](#decentralized-autonomous-organizations) - * [Spätere Anwendungen](#further-applications) - * [Wie funktioneren die Verträge?](#how-do-contracts-work) - * [Spezifikation der Prommiersprache](#language-specification) -* [Gebühren](#fees) -* [Fazit](#conclusion) -* [Refernzen und weiterführende Literatur](#references-and-further-reading) - -## Warum eine neue Plattform? -Wenn man eine neue Anwendung erstellt, vor allem in so heiklen Bereichen wie Kryptographie oder Kryptowährungen, ist die naheliegenste Intention, bestehende Protokolle möglichst umfänglich zu nutzen. -Es gibt keine Veranlassung eine neue Währung oder ein neues Protkoll zu erschaffen, wenn Probleme mit der vorhandenen Technologie gelöst werden können. -In der Tat kommt es einem Puzzle gleich, zu versuchen Probleme zu lösen, die mit elektronischen Besitztum, elektronischen Verträgen und Dezentrale Autonome Gesellschftsformen einhergehen, wenn man dies auf Basis des Bitcoins tun möchte. Dies war unser ursprünglicher Antrieb an einem Protokoll der nächsten Generation zu arbeiten. -Während das Bitcoin-Protokoll für das Handling einer Währung mehr als ausreichend ist, wurde im Laufe unserer Forschung aber auch deutlich, dass es schon für einfache elektronische Verträge oder Treuhandfunktionen mit Mehrfachunterschriften grundlegende Einschränkungen gibt, die eine weitergehende Nutzung nur in sehr begrenzten Umfang möglich machen würden. - -### Colored Coins - -Der erste Versuch zur Implementierung eines Systems zur Verarbeitung von elektronischen Besitzständen, kundenspezifischen Währungen und Vermögenswerten auf Basis der Blockkette wurde realisiert als ein "Overlay-Protokoll" auf dem Bitcoin. Um einen Vergleich anzustellen: Etwa so, wie [HTTP] (http://de.wikipedia.org/wiki/Http) als eine obere Schicht des [TCP-Protokolls] (http://de.wikipedia.org/wiki/Transmission_Control_Protocol), so wie im [Interent-Protkoll-Stack](http://de.wikipedia.org/wiki/Internet_Protocol) definiert. - -Das [Colored Coins - Protokoll] (https://docs.google.com/a/ursium.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit) lässt sich annähernd wie folgt beschreiben: - -1. Der Herausgeber eines Clored Coins legt fest, dass eine bestimmte Transaktionsausgabe H:i einen bestimmten Vermögenswert repräsentiert. (H sei dabei der Transaktions-Hash und i der *?Ausgabeindex?*). Er veröffentlicht eine Colored-Coin-Definition, die besagt, welchen Vermögenswert die *?Transaktionsausgabe?* entspricht (z.B. 1 Satoshi von H:i = eine Unze Gold, einzulösen bei der "Stephan Gold Company"). -2. Die anderen "installieren" die Colored-Coin-Definitions-Datei in ihrem Clored-Coin- Clientprogramm. -3. *?Ist die Color-Coin-Definition freigegen, die Ausgabe H:i ist die einzige Transaktionsausgabe, die diese Farbe hat.?* -4. Wenn eine Transaktion Eingänge mit der Farbe X enthält, dann haben die Ausgaben auch die Farbe X. D.h. wenn der Eigentümer von H:i sofort eine Transaktion vornimmt, um die Ausgaben auf 5 Empfänger zu splitten, dann werden die Ausgaben auch die Farbe X haben. -*?Hat?* ein Transaktion Eingänge unterschiedlicher Farben, dann wird eine "Color-Transfer-Richtlinie" oder ein "Color-Kernel" bestimmen, welche Farben welche Ausgaben sind (z.B. würde eine einfache Implementierung bedeutet, dass die Ausgabe 0 die selbe Farbe hat, wie die Eingabe 0, oder die Ausgabe 1 die selbe Farbe wie wie die Eingabe 1, usw.). -5. Wenn eine Colored-Coin-Client-Software feststellt, das eine neue Transaktions-Ausgabe empfangen wurde, verwendet es einen Rückwerts-Such-Algorithmus, basierend auf dem "Color-Kernel", um die Farbe der Ausgabe festzustellen. Die die Regeln deterministisch sind, werden alle Colored-Coin-Client-Programme damit einverstanden sein, welche Farbe die jeweiligen Ausgaben haben. - -Wie auch immer, das Protokoll hat einige fundamentale Schwachstellen: - -**Vereinfachte Zahlungsbestätigung beim Bitcoin ** - -![SPV in bitcoin](https://www.ethereum.org/gh_wiki/spv_bitcoin.png) - -_Links: Es genügt nur eine kleine Anzahl von Knoten im Merkle-Baum um einen Beweis für die Gültigkeit eines Zweigungs zu bekommen._ -_Rechts: Jeder Versuch, einen Teil des Merkle-Baums zu ändern, wird schließlich zu einer Inkonsistenz irgendwo in der Kette führen._ - -1. **Die Schwierigkeit einer vereinfachten Zahlungsüberprüfung** - Die Bitcoin ist [Merkle-Baum-Konstruktion] (http://de.wikipedia.org/wiki/Merkle-Signatur) ermöglicht dem Protokoll eine ["vereinfachte Zahlungsüberprüfung"] (https://en.bitcoin.it/wiki/Scalability#Simplified_payment_verification), in dem ein Client, der nicht die volle Blockkette geladen hat, schnell die Gültigkeit einer Transaktion-Ausgabe zu bestimmen, indem er bei einem anderen Knoten nach einem kryptografischen Beweis für die Gültigkeit eines einzigen Zweigs des Baumes anfragt. -Um sicher zu sein, muss die Client-Software nur den Block-Header herunter laden. Die Menge an Daten, die Bandbreite und die Prüfzeit reduziert sich um etwa den Faktor eintausend. -Mit Colored Coins ist dies viel schwieriger. Der Grund ist, dass man die Farbe einer Transaktionsausgabe nicht einfach durch Nachschlagen im Merkle-Baum bestimmen kann, sondern der Rückwärts-Such-Algorithmus verwendet werden muss. D.h. es müssen potentiell Tausende von Transaktionen geladen werden und es muss ein Merkle-Baum-Gültigkeitsnachweis für jede Transaktion eingeholt werden, bevor eine Client sicher sein kann, dass eine Transaktion eine bestimmte Farbe hat. -Nach über einem Jahr der Untersuchung, einschließlich der Hilfe von uns selbst, wurde keine Lösung für dieses Problem gefunden. - -2. **Inkompatibilität mit Scripting** - wie oben erwähnt, hat Bitcoin ein mäßig flexibles Scripting-System, die es dem Benutzer beispielsweise erlaubt, eine Transaktion in der Form zu unterzeichnen: "Ich gebe die Transaktion-Ausgabe frei für denjenigen, der bereit ist mir einen BTC zu zahlen". -Weitere Beispiele sind [Versicherungsverträge](http://en.wikipedia.org/wiki/Assurance_contract), [effiziente Microzahlungen](https://en.bitcoin.it/wiki/Contracts#Example_7:_Rapidly-adjusted_.28micro.29payments_to_a_pre-determined_party) und blockkettenbasierte Auktionen. -Allerdings ist dieses System von Natur aus nicht "farbbewusst", das heißt, man kann eine Transaktion nicht in der Form machen: "Ich stelle diese Transaktion-Ausgabe für jeden bereit, der mir eine Goldmünze - definiert mit der Entstehung von H:i - zahlt, denn die Skriptsprache hat keine Ahnung davon, dass das "Farben"-Konzept überhaupt existiert. -Während zwar der Austausch von zwei verschiedenfarbige Münzen ohne Vertrauensvorschuss möglich ist, gilt dies nicht für einen vollständigen dezentralen Austausch, da es keine Möglichkeit gibt, durchsetzbare Kauf-oder Verkaufaufträge zu platzieren. - -3. **Die gleichen Einschränkungen wie beim Bitcoin** - im Idealfall sollten Blockchain-Protokolle in der Lage sein, erweiterte Derivate, Wetten und viele andere Formen von bedingten Transfers zu unterstützen. Leider erben die Colored Coins die Grenzen des Bitcoin in Bezug auf die Unmöglichkeit, solche Vereinbarungen zu treffen. - -### Metacoins - -Ein anderes Konzept, wieder in dem Sinne des Aufsetzens auf das Bitcoinprotokoll (wie HTTP auf TCP) ist das des Metacoins. Es ist sehr einfach: -Das Metacoin-Protokoll bietet eine Möglichkeit Metacoin-Transaktionsdaten in die Ausgabe von Bitcoin-Transaktionen heineinzukodieren. Ein Metacoin-Knoten funktioniert durch die Bearbeitung aller Bitcoin-Transaktionen und der Überprüfung der Bitcoin-Transaktionen die gültigen Metacoin-Transaktionen entsprechen, um zu jedem Zeitpunkt die Coinmenge eines Accounts bestimmen zu können. -Zum Beispiel, ein einfaches Metacoin-Protokoll möge eine Transaktion verwenden, um 4 Ausgaben zu generieren: MARKER, FROM, TO und VALUE. -MARKER könnte eine bestimmter Marker-Adresse sein, um die Transaktion als eine Metacoin-Transaktion zu deklarieren. -FROM könnte die Adresse des Absenders sein. -TO könnte die Empfängeradresse der Coins sein und VALUE die Menge der Coins. -Da das Bitcoin-Protokoll keine Metacoins kennt und so auch nicht in der Lage ist, ungültige Metacoin-Transaktionen abzulehnen, muss das Metacoin-Protokoll *?alle Transaktionen zurück bis zu der ersten Ausgabe MARKER?* bearbeiten, um entsprechend reagieren zu können. -Der Teil der Transaktionsverabeitung des oben beschriebenen Metacoin-Protokolls könnte z.B. folgendermaßen aussehen: - - if tx.output[0] != MARKER: - break - else if balance[tx.output[1]] < decode_value(tx.output[3]): - break - else if not tx.hasSignature(tx.output[1]): - break - else: - balance[tx.output[1]] -= decode_value(tx.output[3]); - balance[tx.output[2]] += decode_value(tx.output[3]); - - -Der Vorteil eines Metacoin-Protokolls ist, dass es die Implementierung von erweiterten Transaktionstypen erlaubt (benutzerspezifische Währungen, dezentrale Austausch, Derivate, etc.), die mit dem in der unteren Schicht liegenden Bitcoin-Protokoll nicht möglich wären. -Metacoins, die auf das Bitcoinprotkoll aufgesetzt sind, haben jedoch eine erhebliche Schwachstelle. Eine vereinfachte Zahlungsbestätigung, schon schwierig mit Clored Coins, ist mit Metacoins komplett unmöglich. -Der Grund dafür ist, dass, während man *?SPV?* verwenden kann, um festzustellen, dass eine Transaktion 30 metacoins *?zur?* Adresse X gesendet hat, bedeutet die allein jedoch noch nicht, dass die Adresse X auch 30 metacoins hat. - Was ist, wenn der Absender der Transaktion nicht über 30 metacoins verfügt und so die Transaktion ungültig ist? Um irgend einen aktuellen Zusammenhang mit dem Metacoin herauszufinden, wie die Frage ob eine Transaktion gültig ist oder nicht, ist es letztendlich immer nötig, alle Transaktionen seit dem Launch des Metacoins zu scannen. - -In beiden Fällen ergibt sich folgende Schlussfolgerung. Der Versuch, erweiterte Protokolle aufgesetzt auf dem Bitcoin (wie HTTP auf TCP) zu bauen, ist bewundernswert. Und es ist in der Tat der richtige Weg bei der Umsetzung erweiterter dezentraler Anwendungen. Allerdings ist der Versuch Colored Coins auf Basis des Bitcoinprotokolls zu bauen, aufwändiger als der Bau von *?HTTP über SMTP?*. Die Absicht von SMTP war es, E-Mail-Nachrichten zu übertragen und nicht als Rückrad für die generische Internet-Kommunikation zu dienen. Man hätte viele ineffiziente und architektonisch hässlichen Praktiken umsetzen müssen, um dieses Ziel effektiv zu erreichen. - -Während der Bitcoin ein großartiges Protokoll für einfache Transaktionen und die Aufbewahrung von Werten ist, ist es weder dafür konzipiert noch in der Lage, als Basisschicht für Finanz-Peer-to-Peer-Protokolle im Allgemeinen zu dienen. Etherium löst die Fragen der Skalierbarkeit, indem es seine eigene Blockkette hostet und einen individuellen "Statusbaum" zusammen mit der Transaktionslite in jedem Block hinterlegt. Jeder "Statusbaum" stellt den aktuellen Status des gesamten Systems dar, einschließlich der Adressen, Guthaben und Vertrags-Stati. -Den Ethereu-Verträgen ist es erlaubt, Daten in dauerhaften Speichern abzulegen. Diese Speicher, kombiniert mit der *?Tuning complete?* Skript-Sprache ermöglicht es uns, eine ganze Währung innerhalb eines einzigen Vertrags zu kodieren, neben unzähligen anderen Varienten kryptographischer Vermögenswerte. -Somit hat Ethereum nicht die Absicht, die oben beschriebenen Colored Coin- und Metcoin- Protokolle zu ersetzen, sondern eine überlegene Basis-Schicht mit einem einzigartig leistungsfähigen Scripting-System zu schaffen, auf der beliebig erweiterbare Verträge, Währungen und andere dezentralen Anwendungen aufgesetzt werden können. -Wenn bestehende Colored Coin- und Metacoin-Projekte auf die Ethereum-Baisi wechseln, können sie die Vorteile der vereinfachten Zahlungsüberprüfung nutzen, hätten die Möglichkeit mit den auf Ethereum basierten Finanzderivaten und dezentralen Tauschbörsen kompatibel zu sein, und die Fähigkeit, auf einem einzigen Netzwerk zu zusammen zu arbeiten. -Jemand mit einer Idee für einen neuen Vertrag oder eine Art von Transaktionen, die die Dinge, die mit Kryptowährungen getan werden können, drastisch verbessern, muss nicht seinen eigenen Kryptocoin starten. Dies kann einfach durch die Implementierung auf Basis des Ethereum Script-Codes erfolgen. Kurz gesagt, Ethereu ist ein Fundament für Innovationen. - -## Philosophie - -The design behind Ethereum is intended to follow the following principles: - -1. **Simplicity** - the Ethereum protocol should be as simple as possible, even at the cost of some data storage or time inefficiency. An average programmer should ideally be able to follow and implement the entire specification, so as to fully realize the unprecedented democratizing potential that cryptocurrency brings and further the vision of Ethereum as a protocol that is open to all. Any optimization which adds complexity should not be included unless that optimization provides very substantial benefit. -2. **Universality** - a fundamental part of Ethereum's design philosophy is that Ethereum does not have "features". Instead, Ethereum provides an internal Turing-complete scripting language, which a programmer can use to construct any smart contract or transaction type that can be mathematically defined. Want to invent your own financial derivative? With Ethereum, you can. Want to make your own currency? Set it up as an Ethereum contract. Want to set up a full-scale Daemon or Skynet? You may need to have a few thousand interlocking contracts, and be sure to feed them generously, to do that, but nothing is stopping you with Ethereum at your fingertips. -3. **Modularity** - the parts of the Ethereum protocol should be designed to be as modular and separable as possible. Over the course of development, our goal is to create a program where if one was to make a small protocol modification in one place, the application stack would continue to function without any further modification. Innovations such as [Dagger](https://github.com/ethereum/wiki/wiki/Dagger), [Patricia trees](https://github.com/ethereum/wiki/wiki/Patricia-Tree) and [RLP](https://github.com/ethereum/wiki/wiki/RLP) should be implemented as separate libraries and made to be feature-complete even if Ethereum does not require certain features so as to make them usable in other protocols as well. Ethereum development should be maximally done so as to benefit the entire cryptocurrency ecosystem, not just itself. -4. **Agility** - details of the Ethereum protocol are not set in stone. Although we will be extremely judicious about making modifications to high-level constructs such as the C-like language and the address system, computational tests later on in the development process may lead us to discover that certain modifications to the algorithm or scripting language will substantially improve scalability or security. If any such opportunities are found, we will exploit them. -5. **Non-discrimination** - the protocol should not attempt to actively restrict or prevent specific categories of usage. All regulatory mechanisms in the protocol should be designed to directly regulate the harm and not attempt to oppose specific undesirable applications. A programmer can even run an infinite loop script on top of Ethereum for as long as they are willing to keep paying the per-computational-step transaction fee. - - -## Basic Building Blocks - -At its core, Ethereum starts off as a fairly regular memory-hard proof-of-work mined cryptocurrency without many extra complications. In fact, Ethereum is in some ways simpler than the Bitcoin-based cryptocurrencies that we use today. The concept of a transaction having multiple inputs and outputs, for example, is gone, replaced by a more intuitive balance-based model (to prevent transaction replay attacks, as part of each account balance we also store an incrementing nonce). Sequence numbers and lock times are also removed, and all transaction and block data is encoded in a single format. Instead of addresses being the RIPEMD160 hash of the SHA256 hash of the public key prefixed with 04, addresses are simply the last 20 bytes of the SHA3 hash of the public key. Unlike other cryptocurrencies, which aim to offer a large number of "features", Ethereum intends to take features away, and instead provide its users with near-infinite power through an all-encompassing mechanism known as "contracts". - -### Modified GHOST Implementation - -The "Greedy Heavist Observed Subtree" (GHOST) protocol is an innovation first introduced by Yonatan Sompolinsky and Aviv Zohar in [December 2013](http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf). The motivation behind GHOST is that blockchains with fast confirmation times currently suffer from reduced security due to a high stale rate - because blocks take a certain time to propagate through the network, if miner A mines a block and then miner B happens to mine another block before miner A's block propagates to B, miner B's block will end up wasted and will not contribute to network security. Furthermore, there is a centralization issue: if miner A is a mining pool with 30% hashpower and B has 10% hashpower, A will have a risk of producing stale blocks 70% of the time whereas B will have a risk of producing stale blocks 90% of the time. Thus, if the stale rate is high, A will be substantially more efficient simply by virtue of its size. With these two effects combined, blockchains which produce blocks quickly are very likely to lead to one mining pool having a large enough percentage of the network hashpower to have de facto control over the mining process. - -As descrived by Sompolinsky and Zohar, GHOST solves the first issue of network security loss by including stale blocks in the calculation of which chain is the "longest"; that is to say, not just the parent and further ancestors of a block, but also the stale descendants of the block's ancestor (in Ethereum jargon, "uncles") are added to the calculation of which block has the largest total proof of work backing it. To solve the second issue of centralization bias, we go beyond the protocol described by Sompolinsky and Zohar, and also provide block rewards to stales: a stale block receives 87.5% of its base reward, and the nephew that includes the stale block receives the remaining 12.5%. Transaction fees, however, are not awarded to uncles. - -Ethereum implements a simplified version of GHOST which only goes down one level. Specifically, a stale block can only be included as an uncle by the direct child of one of its direct siblings, and not any block with a more distant relation. This was done for several reasons. First, unlimited GHOST would include too many complications into the calculation of which uncles for a given block are valid. Second, unlimited GHOST with compensation as used in Ethereum removes the incentive for a miner to mine on the main chain and not the chain of a public attacker. Finally, calculations show that single-level GHOST has over 80% of the benefit of unlimited GHOST, and provides a stale rate comparable to the 2.5 minute Litecoin even with a 40-second block time. However, we will be conservative and still retain a Primecoin-like 60-second block time because individual blocks may take a longer time to verify. - - -### Ethereum Client P2P Protocol - -**P2P Protocol** -![SPV in bitcoin](https://www.ethereum.org/gh_wiki/minerchart.png) - -The Ethereum client P2P protocol is a fairly standard cryptocurrency protocol, and can just as easily be used for any other cryptocurrency; the only modification is the introduction of the GHOST protocol described above. The Ethereum client will be mostly reactive; if not provoked, the only thing the client will do by itself is have the networking daemon maintain connections and periodically send a message asking for blocks whose parent is the current block. However, the client will also be more powerful. Unlike bitcoind, which only stores a limited amount of data about the blockchain, the Ethereum client will also act as a fully functional backend for a block explorer. - -When the client reads a message, it will perform the following steps: - -1. Hash the data, and check if the data with that hash has already been received. If so, exit. -2. Determine the data type. If the data is a transaction, if the transaction is valid add it to the local transaction list, process it onto the current block and publish it to the network. If the data item is a message, respond to it. If the data item is a block, go to step 3. -3. Check if the parent of the block is already stored in the database. If it is not, exit. -4. Check if the proof of work on the block header and all block headers in the "uncle list" is valid. If any are not, exit. -5. Check if every block header in the "uncle list" in the block has the block's parent's parent as its own parent. If any is not, exit. Note that uncle block headers do not need to be in the database; they just need to have the correct parent and a valid proof of work. Also, make sure that uncles are unique and distinct from the parent. -6. Check if the timestamp of the block is at most 15 minutes into the future and ahead of the timestamp of the parent. Check if the difficulty of the block and the block number are correct. If either of these checks fails, exit. -7. Start with the state of the parent of the block, and sequentially apply every transaction in the block to it. At the end, add the miner rewards. If the root hash of the resulting state tree does not match the state root in the block header, exit. If it does, add the block to the database and advance to the next step. -8. Determine TD(block) ("total difficulty") for the new block. TD is defined recursively by TD(genesis_block) = 0 and TD(B) = TD(B.parent) + sum([u.difficulty for u in B.uncles]) + B.difficulty. If the new block has higher TD than the current block, set the current block to the new block and continue to the next step. Otherwise, exit. -9. If the new block was changed, apply all transactions in the transaction list to it, discarding from the transaction list any that turn out to be invalid, and rebroadcast the block and those transactions to the network. - -The "current block" is a pointer maintained by each node that refers to the block that the node deems as representing the current official state of the network. All messages asking for balances, contract states, etc, have their responses computed by looking at the current block. If a node is mining, the process is only slightly changed: while doing all of the above, the node also continuously mines on the current block, using its transaction list as the transaction list of the block. - - -### Currency and Issuance - -The Ethereum network includes its own built-in currency, ether. The main reason for including a currency in the network is twofold. First, like Bitcoin, ether is rewarded to miners so as to incentivize network security. Second, it serves as a mechanism for paying transaction fees for anti-spam purposes. Of the two main alternatives to fees, per-transaction proof of work similar to [Hashcash](http://en.wikipedia.org/wiki/Hashcash) and zero-fee laissez-faire, the former is wasteful of resources and unfairly punitive against weak computers and smartphones and the latter would lead to the network being almost immediately overwhelmed by an infinitely looping "logic bomb" contract. For convenience and to avoid future argument (see the current mBTC/uBTC/satoshi debate), the denominations will be pre-labelled: - -* 1: wei -* 10^3: (unspecified) -* 10^6: (unspecified) -* 10^9: (unspecified) -* 10^12: szabo -* 10^15: finney -* 10^18: ether - -This should be taken as an expanded version of the concept of "dollars" and "cents" or "BTC" and "satoshi" that is intended to be future proof. Szabo, finney and ether will likely be used in the foreseeable future, and the other units will be more . "ether" is intended to be the primary unit in the system, much like the dollar or bitcoin. The right to name the 103, 106 and 109 units will be left as a high-level secondary reward for the fundraiser subject to pre-approval from ourselves. - -The issuance model will be as follows: - -* Ether will be released in a fundraiser at the price of 1000-2000 ether per BTC, with earlier funders getting a better price to compensate for the increased uncertainty of participating at an earlier stage. The minimum funding amount will be 0.01 BTC. Suppose that X ether gets released in this way -* 0.225X ether will be allocated to the fiduciary members and early contributors who substantially participated in the project before the start of the fundraiser. This share will be stored in a time-lock contract; about 40% of it will be spendable after one year, 70% after two years and 100% after 3 years. -* 0.05X ether will be allocated to a fund to use to pay expenses and rewards in ether between the start of the fundraiser and the launch of the currency -* 0.225X ether will be allocated as a long-term reserve pool to pay expenses, salaries and rewards in ether after the launch of the currency -* 0.4X ether will be mined per year forever after that point - - -| Group | After 1 year | After 5 years -| ------------- | ------------- |-------------| -| Currency units | 1.9X | 3.5X | -| Fundraiser participants | 52.6% | 28.6% | -| Fiduciary members and early contributors | 11.8% | 6.42% | -| Additional pre-launch allocations | 2.63% | 1.42% | -| Reserve | 11.8% | 6.42% | -| Miners | 21.1% | 57.1% | - - -**Long-Term Inflation Rate (percent)** - -![SPV in bitcoin](https://www.ethereum.org/gh_wiki/inflation.svg) - -_Despite the linear currency issuance, just like with Bitcoin over time the inflation rate nevertheless tends to zero_ - - -For example, after five years and assuming no transactions, 28.6% of the ether will be in the hands of the fundraiser participants, 6.42% in the fiduciary member and early contributor pool, 6.42% paid to the reserve pool, and 57.1% will belong to miners. The permanent linear inflation model reduces the risk of what some see as excessive wealth concentration in Bitcoin, and gives individuals living in present and future eras a fair chance to acquire currency units, while at the same time retaining a strong incentive to obtain and hold ether because the inflation "rate" still tends to zero over time (eg. during year 1000001 the money supply would increase from 500001.5 * X to 500002 * X, an inflation rate of 0.0001%). Furthermore, much of the interest in Ethereum will be medium-term; we predict that if Ethereum succeeds it will see the bulk of its growth on a 1-10 year timescale, and supply during that period will be very much limited. - -We also theorize that because coins are always lost over time due to carelessness, death, etc, and coin loss can be modeled as a percentage of the total supply per year, that the total currency supply in circulation will in fact eventually stabilize at a value equal to the annual issuance divided by the loss rate (eg. at a loss rate of 1%, once the supply reaches 40X then 0.4X will be mined and 0.4X lost every year, creating an equilibrium). - - -### Data Format - -All data in Ethereum will be stored in [recursive length prefix encoding](https://github.com/ethereum/wiki/wiki/RLP), which serializes arrays of strings of arbitrary length and dimension into strings. For example, ['dog', 'cat'] is serialized (in byte array format) as [ 130, 67, 100, 111, 103, 67, 99, 97, 116]; the general idea is to encode the data type and length in a single byte followed by the actual data (eg. converted into a byte array, 'dog' becomes [ 100, 111, 103 ], so its serialization is [ 67, 100, 111, 103 ]. Note that RLP encoding is, as suggested by the name, recursive; when RLP encoding an array, one is really encoding a string which is the concatenation of the RLP encodings of each of the elements. Additionally, note that block number, timestamp, difficulty, memory deposits, account balances and all values in contract storage are integers, and Patricia tree hashes, root hashes, addresses, transaction list hashes and all keys in contract storage are strings. The main difference between the two is that strings are stored as fixed-length data (20 bytes for addresses, 32 bytes for everything else), and integers take up only as much space as they need. Integers are stored in big-endian base 256 format (eg. 32767 in byte array format as [ 127, 255 ]). - -A full block is stored as: - - [ - block_header, - transaction_list, - uncle_list - ] - -Where: - - transaction_list = [ - transaction 1, - transaction 2, - ... - ] - - uncle list = [ - uncle_block_header_1, - uncle_block_header_2, - ... - ] - - block_header = [ - parent hash, - sha3(rlp_encode(uncle_list)), - coinbase address, - state_root, - sha3(rlp_encode(transaction_list)), - difficulty, - timestamp, - extra_data, - nonce - ] - -Each transaction and uncle block header is itself a list. The data for the proof of work is the RLP encoding of the block WITHOUT the nonce. uncle_list and transaction_list are the lists of the uncle block headers and transactions in the block, respectively. nonce and extra_data are both limited to a maximum of 32 bytes, except the genesis block where the extra_data parameter will be much larger. - -The state_root is the root of a [Merkle Patricia tree](https://github.com/ethereum/wiki/wiki/Patricia-Tree) containing (key, value) pairs for all accounts where each address is represented as a 20-byte binary string. At the address of each account, the value stored in the Merkle Patricia tree is a string which is the RLP-serialized form of an object of the form: - - [ balance, nonce, contract_root, storage_deposit ] - -The nonce is the number of transactions made from the account, and is incremented every time a transaction is made. The purpose of this is to (1) make each transaction valid only once to prevent replay attacks, and (2) to make it impossible (more precisely, cryptographically infeasible) to construct a contract with the same hash as a pre-existing contract. balance refers to the account's balance, denominated in wei. contract_root is the root of yet another Patricia tree, containing the contract's memory, if that account is controlled by a contract. If an account is not controlled by a contract, the contract root will simply be the empty string. storage_deposit is a counter that stores paid storage fees; its function will be discussed in more detail further in this paper. - - -### Mining algorithm - -One highly desirable property in mining algorithms is resistance to optimization through specialized hardware. Originally, Bitcoin was conceived as a highly democratic currency, allowing anyone to participate in the mining process with a CPU. In 2010, however, much faster miners exploiting the rapid parallelization offered by graphics processing units (GPUs) rapidly took over, increasing network hashpower by a factor of 100 and leaving CPUs essentially in the dust. In 2013, a further category of specialized hardware, application-specific integrated circuits (ASICs) outcompeted the GPUs in turn, achieving another 100x speedup by using chips fabricated for the sole purpose of computing SHA256 hashes. Today, it is virtually impossible to mine without first purchasing a mining device from one of these companies, and some people are concerned that in 5-10 years' time mining will be entirely dominated by large centralized corporations such as AMD and Intel. - -To date, the main way of achieving this goal has been "memory-hardness", constructing proof of work algorithms that require not only a large number of computations, but also a large amount of memory, to validate, thereby making highly parallelized specialized hardware implementations less effective. There have been several implementations of memory-hard proof of work, all of which have their flaws: - -* **Scrypt** - Scrypt is a function which is designed to take 128 KB of memory [to compute](https://litecoin.info/User:Iddo/Comparison_between_Litecoin_and_Bitcoin#SHA256_mining_vs_scrypt_mining). The algorithm essentially works by filling a memory array with hashes, and then computing intermediate values and finally a result based on the values in the memory array. However, the 128 KB parameter is a very weak threshold, and ASICs for Litecoin are [already under development](https://axablends.com/merchants-accepting-bitcoin/litecoin-discussion/litecoin-scrypt-asic-miners/). Furthermore, there is a natural limit to how much memory hardness with Scrypt can be tweaked up to achieve, as the verification process takes just as much memory, and just as much computation, as one round of the mining process. -* **Birthday attacks** - the idea behind birthday-based proofs of work is simple: find values xn,i,j such that i < k, j < k and |H(data+xn+i) - H(data+xn+j)| < 2^256 / d^2. The d parameter sets the computational difficulty of finding a block, and the k parameter sets the memory hardness. Any birthday algorithm must somehow store all computations of H(data+xn+i) in memory so that future computations can be compared against them. Here, computation is memory-hard, but verification is memory-easy, allowing for extreme memory hardness without compromising the ease of verification. However, the algorithm is problematic for two reasons. First, there is a time-memory tradeoff attack where users 2x less memory can compensate with 2x more computational power, so its memory hardness is not absolute. Second, it may be easy to build specialized hardware devices for the problem, especially once one moves beyond traditional chip and processor architecture and into various classes of hardware-based hash tables or probabilistic analog computing. -* **Dagger** - the idea behind Dagger, an in-house algorithm developed by the Ethereum team, is to have an algorithm that is similar to Scrypt, but which is specially designed so that each individual nonce only depends on a small portion of the data tree that gets built up for each group of ~10 million nonces. Computing nonces with any reasonable level of efficiency requires building up the entire tree, taking up over 100 MB of memory, whereas verifying a nonce only takes about 100 KB. However, Dagger-style algorithms are vulnerable to devices that have multiple computational circuits sharing the same memory, and although this threat can be mitigated it is arguably impossible to fully remove. - - -As a default, we are currently considering a Dagger-like algorithm with tweaked parameters to minimize specialized hardware attacks, perhaps together with a proof of stake algorithm such as our own Slasher for added security if deemed necessary. However, in order to come up with a proof-of-work algorithm that is better than all existing competitors, our intention is to use some of the funds raised in the fundraiser to host a contest, similar to those used to determine the algorithm for the Advanced Encryption Standard (AES) in 2005 and the SHA3 hash algorithm in 2013, where research groups from around the world compete to develop ASIC-resistant mining algorithms, and have a selection process with multiple rounds of judging determine the winners. The contest will have prizes, and will be open-ended; we encourage research into memory-hard proofs of work, self-modifying proofs of work, proofs of work based on x86 instructions, multiple proofs of work with a human-driven incentive-compatible economic protocol for swapping one out in the future, and any other design that accomplishes the task. There will be opportunities to explore alternatives such as proof of stake, proof of burn and proof of excellence as well. - - -### Transactions - -A transaction is stored as: - - [ nonce, receiving_address, value, [ data item 0, data item 1 ... data item n ], v, r, s ] - -nonce is the number of transactions already sent by that account, encoded in binary form (eg. 0 -> '', 7 -> '\x07', 1000 -> '\x03\xd8'). (v,r,s) is the raw Electrum-style signature of the transaction without the signature made with the private key corresponding to the sending account, with 0 <= v <= 3. From an Electrum-style signature (65 bytes) it is possible to extract the public key, and thereby the address, directly. A valid transaction is one where (i) the signature is well-formed (ie. 0 <= v <= 3, 0 <= r < P, 0 <= s < N, 0 <= r < P - N if v >= 2), and (ii) the sending account has enough funds to pay the fee and the value. A valid block cannot contain an invalid transaction; however, if a contract generates an invalid transaction that transaction will simply have no effect. Transaction fees will be included automatically. If one wishes to voluntarily pay a higher fee, one is always free to do so by constructing a contract which forwards transactions but automatically sends a certain amount or percentage to the miner of the current block. - -Transactions sent to the empty string as an address are a special type of transaction, creating a "contract". - - -### Difficulty adjustment - -Difficulty is adjusted by the formula: - - D(genesis_block) = 2^36 - D(block) = - if anc(block,1).timestamp >= anc(block,501).timestamp + 60 * 500: D(block.parent) - floor(D(block.parent) / 1000) - else: D(block.parent) + floor(D(block.parent) / 1000) - -anc(block,n) is the nth generation ancestor of the block; all blocks before the genesis block are assumed to have the same timestamp as the genesis block. This stabilizes around a block time of 60 seconds automatically. The choice of 500 was made in order to balance the concern that for smaller values miners with sufficient hashpower to often produce two blocks in a row would have the incentive to provide an incorrect timestamp to maximize their own reward and the fact that with higher values the difficulty oscillates too much; with the constant of 500, simulations show that a constant hashpower produces a variance of about +/-20%. - - -### Block Rewards - -A miner receives three kinds of rewards: a static block reward for producing a block, fees from transactions, and nephew/uncle rewards as described in the GHOST section above. The miner will receive 100% of the block reward for themselves, but transaction fee rewards will be split, so that 50% goes to the miner and the remaining 50% is evenly split among the last 64 miners. The reason for this is to prevent a miner from being able to create an Ethereum block with an unlimited number of operations, paying all transaction fees to themselves, while still maintaining an incentive for miners to include transactions. As described in the GHOST section, uncles only receive 87.5% of their block reward, with the remaining 12.5% going to the including nephew; the transaction fees from the stale block do not go to anyone. - - -## Contracts - -In Ethereum, there are two types of entities that can generate and receive transactions: actual people (or bots, as cryptographic protocols cannot distinguish between the two) and contracts. A contract is essentially an automated agent that lives on the Ethereum network, has an Ethereum address and balance, and can send and receive transactions. A contract is "activated" every time someone sends a transaction to it, at which point it runs its code, perhaps modifying its internal state or even sending some transactions, and then shuts down. The "code" for a contract is written in a special-purpose low-level language consisting of a stack, which is not persistent, 2256 memory entries, which are also not persistent, and 2256 storage entries which constitute the contract's permanent state. Note that Ethereum users will not need to code in this low-level stack language; we will provide a simple [C-Like language](https://github.com/ethereum/wiki/wiki/CLL) with variables, expressions, conditionals, arrays and while loops, and provide a compiler down to Ethereum script code. - - -### Applications - -Here are some examples of what can be done with Ethereum contracts, with all code examples written in our C-like language. The variables tx.sender, tx.value, tx.fee, tx.data and tx.datan are properties of the incoming transaction, contract.storage, and contract.address of the contract itself, and block.contract_storage, block.account_balance, block.number, block.difficulty, block.parenthash, block.basefee and block.timestamp properties of the block. block.basefee is the "base fee" which all transaction fees in Ethereum are calculated as a multiple of; for more info see the "fees" section below. All variables expressed as capital letters (eg. A) are constants, to be replaced by actual values by the contract creator when actually releasing the contract. - - -### Sub-currencies - -Sub-currencies have many applications ranging from currencies representing assets such as USD or gold to company stocks and even currencies with only one unit issued to represent collectibles or smart property. Advanced special-purpose financial protocols sitting on top of Ethereum may also wish to organize themselves with an internal currency. Sub-currencies are surprisingly easy to implement in Ethereum; this section describes a fairly simple contract for doing so. - -The idea is that if someone wants to send X currency units to account A in currency contract C, they will need to make a transaction of the form (C, 100 * block.basefee, [A, X]), and the contract parses the transaction and adjusts balances accordingly. For a transaction to be valid, it must send 100 times the base fee worth of ether to the contract in order to "feed" the contract (as each computational step after the first 16 for any contract costs the contract a small fee and the contract will stop working if its balance drains to zero). - - if tx.value < 100 * block.basefee: - stop - elif contract.storage[1000]: - from = tx.sender - to = tx.data[0] - value = tx.data[1] - if to <= 1000: - stop - if contract.storage[from] < value: - stop - contract.storage[from] = contract.storage[from] - value - contract.storage[to] = contract.storage[to] + value - else: - contract.storage[MYCREATOR] = 10^18 - contract.storage[1000] = 1 - - -Ethereum sub-currency developers may also wish to add some other more advanced features: - -* Include a mechanism by which people can buy currency units in exchange for ether, perhaps auctioning off a set number of units every day. -* Allow transaction fees to be paid in the internal currency, and then refund the ether transaction fee to the sender. This solves one major problem that all other "sub-currency" protocols have had to date: the fact that sub-currency users need to maintain a balance of sub-currency units to use and units in the main currency to pay transaction fees in. Here, a new account would need to be "activated" once with ether, but from that point on it would not need to be recharged. -* Allow for a trust-free decentralized exchange between the currency and ether. Note that trust-free decentralized exchange between any two contracts is theoretically possible in Ethereum even without special support, but special support will allow the process to be done about ten times more cheaply. - - -### Financial derivatives - -The underlying key ingredient of a financial derivative is a data feed to provide the price of a particular asset as expressed in another asset (in Ethereum's case, the second asset will usually be ether). There are many ways to implement a data feed; one method, pioneered by the developers of [Mastercoin](http://mastercoin.org/), is to include the data feed in the blockchain. Here is the code: - - if tx.sender != FEEDOWNER: - stop - contract.storage[data[0]] = data[1] - -Any other contract will then be able to query index I of data store D by using block.contract_storage(D)[I]. A more advanced way to implement a data feed may be to do it off-chain - have the data feed provider sign all values and require anyone attempting to trigger the contract to include the latest signed data, and then use Ethereum's internal scripting functionality to verify the signature. Pretty much any derivative can be made from this, including leveraged trading, options, and even more advanced constructions like collateralized debt obligations (no bailouts here though, so be mindful of black swan risks). - -To show an example, let's make a hedging contract. The basic idea is that the contract is created by party A, who puts up 4000 ether as a deposit. The contract then lies open for any party to accept it by putting in 1000 ether. Say that 1000 ether is worth $25 at the time the contract is made, according to index I of data store D. If party B accepts it, then after 30 days anyone can send a transaction to make the contract process, sending the same dollar value worth of ether (in our example, $25) back to B and the rest to A. B gains the benefit of being completely insulated against currency volatility risk without having to rely on any issuers. The only risk to B is if the value of ether falls by over 80% in 30 days - and even then, if B is online B can simply quickly hop onto another hedging contract. The benefit to A is the implicit 0.2% fee in the contract, and A can hedge against losses by separately holding USD in another location (or, alternatively, A can be an individual who is optimistic about the future of Ethereum and wants to hold ether at 1.25x leverage, in which case the fee may even be in B's favor). - - if tx.value < 200 * block.basefee: - stop - if contract.storage[1000] == 0: - if tx.value < 1000 * 10^18: - stop - contract.storage[1000] = 1 - contract.storage[1001] = 998 * block.contract_storage(D)[I] - contract.storage[1002] = block.timestamp + 30 * 86400 - contract.storage[1003] = tx.sender - else: - ethervalue = contract.storage[1001] / block.contract_storage(D)[I] - if ethervalue >= 5000: - mktx(contract.storage[1003],5000 * 10^18,0,0) - else if block.timestamp > contract.storage[1002]: - mktx(contract.storage[1003],ethervalue * 10^18,0,0) - mktx(A,(5000 - ethervalue) * 10^18,0,0) - -More advanced financial contracts are also possible; complex multi-clause options (eg. "Anyone, hereinafter referred to as X, can claim this contract by putting in 2 USD before Dec 1. X will have a choice on Dec 4 between receiving 1.95 USD on Dec 29 and the right to choose on Dec 11 between 2.20 EUR on Dec 28 and the right to choose on Dec 18 between 1.20 GBP on Dec 30 and paying 1 EUR and getting 3.20 EUR on Dec 29") can be defined simply by storing a state variable just like the contract above but having more clauses in the code, one clause for each possible state. Note that financial contracts of any form do need to be fully collateralized; the Ethereum network controls no enforcement agency and cannot collect debt. - - -### Identity and Reputation Systems - -The earliest alternative cryptocurrency of all, [Namecoin](http://namecoin.org/), attempted to use a Bitcoin-like blockchain to provide a name registration system, where users can register their names in a public database alongside other data. The major cited use case is for a [DNS](http://en.wikipedia.org/wiki/Domain_Name_System) system, mapping domain names like "bitcoin.org" (or, in Namecoin's case, "bitcoin.bit") to an IP address. Other use cases include email authentication and potentially more advanced reputation systems. Here is a simple contract to provide a Namecoin-like name registration system on Ethereum: - - if tx.value < block.basefee * 200: - stop - if contract.storage[tx.data[0]] or tx.data[0] < 100: - stop - contract.storage[tx.data[0]] = tx.data[1] - -One can easily add more complexity to allow users to change mappings, automatically send transactions to the contract and have them forwarded, and even add reputation and web-of-trust mechanics. - - -### Decentralized Autonomous Organizations - -The general concept of a "decentralized autonomous organization" is that of a virtual entity that has a certain set of members or shareholders which, perhaps with a 67% majority, have the right to spend the entity's funds and modify its code. The members would collectively decide on how the organization should allocate its funds. Methods for allocating a DAO's funds could range from bounties, salaries to even more exotic mechanisms such as an internal currency to reward work. This essentially replicates the legal trappings of a traditional company or nonprofit but using only cryptographic blockchain technology for enforcement. So far much of the talk around DAOs has been around the "capitalist" model of a "decentralized autonomous corporation" (DAC) with dividend-receiving shareholders and tradable shared; an alternative, perhaps described as a "decentralized autonomous community", would have all members have an equal share in the decision making and require 67% of existing members to agree to add or remove a member. The requirement that one person can only have one membership would then need to be enforced collectively by the group. - -Some "skeleton code" for a DAO might look as follows. - -There are three transaction types: - -* [0,k] to register a vote in favor of a code change -* [1,k,L,v0,v1...vn] to register a code change at code k in favor of setting memory starting from location L to v0, v1 ... vn -* [2,k] to finalize a given code change - -Note that the design relies on the randomness of addresses and hashes for data integrity; the contract will likely get corrupted in some fashion after about 2^128 uses, but that is acceptable since nothing close to that volume of usage will exist in the foreseeable future. 2^255 is used as a magic number to store the total number of members, and a membership is stored with a 1 at the member's address. The last three lines of the contract are there to add C as the first member; from there, it will be C's responsibility to use the democratic code change protocol to add a few other members and code to bootstrap the organization. - - if tx.value < tx.basefee * 200: - stop - if contract.storage[tx.sender] == 0: - stop - k = sha3(32,tx.data[1]) - if tx.data[0] == 0: - if contract.storage[k + tx.sender] == 0: - contract.storage[k + tx.sender] = 1 - contract.storage[k] += 1 - else if tx.data[0] == 1: - if tx.value <= tx.datan * block.basefee * 200 or contract.storage[k]: - stop - i = 2 - while i < tx.datan: - contract.storage[k + i] = tx.data[i] - i = i + 1 - contract.storage[k] = 1 - contract.storage[k+1] = tx.datan - else if tx.data[0] == 2: - if contract.storage[k] >= contract.storage[2 ^ 255] * 2 / 3: - if tx.value <= tx.datan * block.basefee * 200: - stop - i = 3 - L = contract.storage[k+1] - loc = contract.storage[k+2] - while i < L: - contract.storage[loc+i-3] = tx.data[i] - i = i + 1 - if contract.storage[2 ^ 255 + 1] == 0: - contract.storage[2 ^ 255 + 1] = 1 - contract.storage[C] = 1 - -This implements the "egalitarian" DAO model where members have equal shares. One can easily extend it to a shareholder model by also storing how many shares each owner holds and providing a simple way to transfer shares. - -DAOs and DACs have already been the topic of a large amount of interest among cryptocurrency users as a future form of economic organization, and we are very excited about the potential that DAOs can offer. In the long term, the Ethereum fund itself intends to transition into being a fully self-sustaining DAO. - - -### Further Applications - -1. **Savings wallets**. Suppose that Alice wants to keep her funds safe, but is worried that she will lose or someone will hack her private key. She puts ether into a contract with Bob, a bank, as follows: Alice alone can withdraw a maximum of 1% of the funds per day, Alice and Bob together can withdraw everything, and Bob alone can withdraw a maximum of 0.05% of the funds. Normally, 1% per day is enough for Alice, and if Alice wants to withdraw more she can contact Bob for help. If Alice's key gets hacked, she runs to Bob to move the funds to a new contract. If she loses her key, Bob will get the funds out eventually. If Bob turns out to be malicious, she can still withdraw 20 times faster than he can. - -2. **Crop insurance**. One can easily make a financial derivatives contract but using a data feed of the weather instead of any price index. If a farmer in Iowa purchases a derivative that pays out inversely based on the precipitation in Iowa, then if there is a drought, the farmer will automatically receive money and if there is enough rain the farmer will be happy because their crops would do well. - -3. **A decentrally managed data feed**, using proof-of-stake voting to give an average (or more likely, median) of everyone's opinion on the price of a commodity, the weather or any other relevant data. - -4. **Smart multisignature escrow**. Bitcoin allows multisignature transaction contracts where, for example, three out of a given five keys can spend the funds. Ethereum allows for more granularity; for example, four out of five can spend everything, three out of five can spend up to 10% per day, and two out of five can spend up to 0.5% per day. Additionally, Ethereum multisig is asynchronous - two parties can register their signatures on the blockchain at different times and the last signature will automatically send the transaction. - -5. **Peer-to-peer gambling**. Any number of peer-to-peer gambling protocols, such as Frank Stajano and Richard Clayton's [Cyberdice](http://www.cl.cam.ac.uk/~fms27/papers/2008-StajanoCla-cyberdice.pdf), can be implemented on the Ethereum blockchain. The simplest gambling protocol is actually simply a contract for difference on the next block hash. From there, entire gambling services such as SatoshiDice can be replicated on the blockchain either by creating a unique contract per bet or by using a quasi-centralized contract. - -6. A full-scale **on-chain stock market**. Prediction markets are also easy to implement as a trivial consequence. - -7. An **on-chain decentralized marketplace**, using the identity and reputation system as a base. - -8. **Decentralized Dropbox**. One setup is to encrypt a file, build a Merkle tree out of it, put the Merkle root into a contract alongside a certain quantity of ether, and distribute the file across some secondary network. Every day, the contract would randomly select a branch of the Merkle tree depending on the block hash, and give X ether to the first node to provide that branch to the contract, thereby encouraging nodes to store the data for the long term in an attempt to earn the prize. If one wants to download any portion of the file, one can use a [micropayment-channel](https://bitcointalk.org/index.php?topic=244656.0)-style contract to download the file from a few nodes a block at a time. - - -### How do contracts work? - -A contract making transaction is encoded as follows: - - [ - nonce, - '', - value, - [ - data item 0, - data item 1, - ... - ], - v, - r, - s - ] - - -The data items will, in most cases, be script codes (more on this below). Contract creation transaction validation happens as follows: - -Deserialize the transaction, and extract its sending address from its signature. -Calculate the transaction's fee as NEWCONTRACTFEE plus storage fees for the code. Check that the balance of the creator is at least the transaction value plus the fee. If not, exit. -Take the last 20 bytes of the sha3 hash of the RLP encoding of the transaction making the contract. If an account with that address already exists, exit. Otherwise, create the contract at that address -Copy data item i to storage slot i in the contract for all i in [0 ... n-1] where n is the number of data items in the transaction, and initialize the contract with the transaction's value as its value. Subtract the value and fee from the creator's balance. - - -### Language Specification - -The contract scripting language is a hybrid of assembly language and Bitcoin's stack-based language, maintaining an index pointer that usually increments by one after every operation and continuously processing the operation found at the current index pointer. All opcodes are numbers in the range [0 ... 63]; labels further in this description such as STOP, EXTRO and BALANCE refer to specific values are defined further below. The scripting language has access to three kinds of memory: - -* **Stack** - a form of temporary storage that is reset to an empty list every time a contract is executed. Operations typically add and remove values to and from the top of the stack, so the total length of the stack will shrink and grow over the course of the program's execution. -* **Memory** - a temporary key/value store that is reset to containing all zeroes every time a contract is executed. Keys and values in memory are integers in the range [0 ... 2^256-1] -* **Storage** - a persistent key/value store that is initially set to contain all zeroes, except for some script code inserted at the beginning when the contract is created as described above. Keys and values in storage are integers in the range [0 ... 2^256-1] - -Whenever a transaction is sent to a contract, the contract executes its scripting code. The precise steps that happen when a contract receives a transaction are as follows: - -**Contract Script Interpretation ** - -![SPV in bitcoin](https://www.ethereum.org/gh_wiki/flowchart.png) - -1. The contract's ether balance increases by the amount sent -2. The index pointer is set to zero, and STEPCOUNT = 0 -3. Repeat forever: - -* if the command at the index pointer is STOP, invalid or greater than 63, exit from the loop -* set MINERFEE = 0, VOIDFEE = 0 -* set STEPCOUNT <- STEPCOUNT + 1 -* if STEPCOUNT > 16, set MINERFEE <- MINERFEE + STEPFEE -* see if the command is LOAD or STORE. If so, set MINERFEE <- MINERFEE + DATAFEE -* see if the command will modify a storage field, say modifying KEY from OLDVALUE to NEWVALUE. Let F(K,V) be 0 if V == 0 else (len(K) + len(V)) * STORAGEFEE in bytes. Set VOIDFEE <- VOIDFEE - F(KEY,OLDVALUE) + F(KEY,NEWVALUE). Computing len(K) ignores leading zero bytes. -* see if the command is EXTRO or BALANCE. If so, set MINERFEE <- MINERFEE + EXTROFEE -* see if the command is a crypto operation. If so, set MINERFEE <- MINERFEE + CRYPTOFEE -* if MINERFEE + VOIDFEE > CONTRACT.BALANCE, HALT and exit from the loop -* subtract MINERFEE from the contract's balance and add MINERFEE to a running counter that will be added to the miner's balance once all transactions are parsed. -* set DELTA = max(-CONTRACT.STORAGE_DEPOSIT,VOIDFEE) and CONTRACT.BALANCE <- CONTRACT.BALANCE - DELTA and CONTRACT.STORAGE_DEPOSIT <- CONTRACT.STORAGE_DEPOSIT + DELTA. Note that DELTA can be positive or negative; the only restriction is that the contract's deposit cannot go below zero. -* run the command -* if the command did not exit with an error, update the index pointer and return to the start of the loop. If the contract did exit with an error, break out of the loop. Note that a contract exiting with an error does not make the transaction or the block invalid; it simply means that the contract execution halts midway through. - -In the following descriptions, S[-1], S[-2], etc represent the topmost, second topmost, etc items on the stack. The individual opcodes are defined as follows: - -* (0) STOP - halts execution -* (1) ADD - pops two items and pushes S[-2] + S[-1] mod 2^256 -* (2) MUL - pops two items and pushes S[-2] * S[-1] mod 2^256 -* (3) SUB - pops two items and pushes S[-2] - S[-1] mod 2^256 -* (4) DIV - pops two items and pushes floor(S[-2] / S[-1]). If S[-1] = 0, halts execution. -* (5) SDIV - pops two items and pushes floor(S[-2] / S[-1]), but treating values above 2^255 - 1 as negative (ie. x -> 2^256 - x). If S[-1] = 0, halts execution. -* (6) MOD - pops two items and pushes S[-2] mod S[-1]. If S[-1] = 0, halts execution. -* (7) SMOD - pops two items and pushes S[-2] mod S[-1], but treating values above 2^255 - 1 as negative (ie. x -> 2^256 - x). If S[-1] = 0, halts execution. -* (8) EXP - pops two items and pushes S[-2] ^ S[-1] mod 2^256 -* (9) NEG - pops one item and pushes 2^256 - S[-1] -* (10) LT - pops two items and pushes 1 if S[-2] < S[-1] else 0 -* (11) LE - pops two items and pushes 1 if S[-2] <= S[-1] else 0 -* (12) GT - pops two items and pushes 1 if S[-2] > S[-1] else 0 -* (13) GE - pops two items and pushes 1 if S[-2] >= S[-1] else 0 -* (14) EQ - pops two items and pushes 1 if S[-2] == S[-1] else 0 -* (15) NOT - pops one item and pushes 1 if S[-1] == 0 else 0 -* (16) MYADDRESS - pushes the contract's address as a number -* (17) TXSENDER - pushes the transaction sender's address as a number -* (18) TXVALUE - pushes the transaction value -* (19) TXDATAN - pushes the number of data items -* (20) TXDATA - pops one item and pushes data item S[-1], or zero if index out of range -* (21) BLK_PREVHASH - pushes the hash of the previous block (NOT the current one since that's impossible!) -* (22) BLK_COINBASE - pushes the coinbase of the current block -* (23) BLK_TIMESTAMP - pushes the timestamp of the current block -* (24) BLK_NUMBER - pushes the current block number -* (25) BLK_DIFFICULTY - pushes the difficulty of the current block -* (26) BLK_NONCE - pushes the nonce of the current block -* (27) BASEFEE - pushes the base fee (x as defined in the fee section below) -* (32) SHA256 - pops two items, and then constructs a string by taking the ceil(S[-1] / 32) items in memory from index S[-2] to (S[-2] + ceil(S[-1] / 32) - 1) mod 2^256, prepending zero bytes to each one if necessary to get them to 32 bytes, and takes the last S[-1] bytes. Pushes the SHA256 hash of the string -* (33) RIPEMD160 - works just like SHA256 but with the RIPEMD-160 hash -* (34) ECMUL - pops three items. If (S[-2],S[-1]) are a valid point in secp256k1, including both coordinates being less than P, pushes (S[-2],S[-1]) * S[-3], using (0,0) as the point at infinity. Otherwise, pushes (2^256 - 1, 2^256 - 1). Note that there are no restrictions on S[-3] -* (35) ECADD - pops four items and pushes (S[-4],S[-3]) + (S[-2],S[-1]) if both points are valid, otherwise (2^256 - 1,2^256 - 1) -* (36) ECSIGN - pops two items and pushes (v,r,s) as the Electrum-style RFC6979 deterministic signature of message hash S[-1] with private key S[-2] mod N with 0 <= v <= 3 -* (37) ECRECOVER - pops four items and pushes (x,y) as the public key from the signature (S[-3],S[-2],S[-1]) of message hash S[-4]. If the signature has invalid v,r,s values (ie. v not in [27,28], r not in [0,P], s not in [0,N]), return (2^256 - 1,2^256 - 1) -* (38) ECVALID - pops two items and pushes 1 if (S[-2],S[-1]) is a valid secp256k1 point (including (0,0)) else 0 -* (39) SHA3 - works just like SHA256 but with the SHA3 hash, 256 bit version -* (48) PUSH - pushes the item in memory at the index pointer + 1, and advances the index pointer by 2. -* (49) POP - pops one item. -* (50) DUP - pushes S[-1] to the stack. -* (51) SWAP - pops two items and pushes S[-1] then S[-2] -* (52) MLOAD - pops two items and sets the item in memory at index S[-1] to S[-2] -* (53) MSTORE - pops two items and sets the item in memory at index S[-1] to S[-2] -* (54) SLOAD - pops two items and sets the item in storage at index S[-1] to S[-2] -* (55) SSTORE - pops two items and sets the item in storage at index S[-1] to S[-2] -* (56) JMP - pops one item and sets the index pointer to S[-1] -* (57) JMPI - pops two items and sets the index pointer to S[-2] only if S[-1] is nonzero -* (58) IND - pushes the index pointer -* (59) EXTRO - pops two items and pushes memory index S[-2] of contract S[-1] -* (60) BALANCE - pops one item and pushes balance of the account with that address, or zero if the address is invalid -* (61) MKTX - pops four items and initializes a transaction to send S[-2] ether to S[-1] with S[-3] data items. Takes items in memory from index S[-4] to index (S[-4] + S[-3] - 1) mod 2^256 as the transaction's data items. -* (63) SUICIDE - pops one item, destroys the contract and clears all storage, sending the entire balance plus the contract deposit to the account at S[-1] - - -As mentioned above, the intent is not for people to write scripts directly in Ethereum script code; rather, we will release compilers to generate ES from higher-level languages. The first supported language will likely be the simple C-like language used in the descriptions above, and the second will be a more complete first-class-function language with support for arrays and arbitrary-length strings. Compiling the C-like language is fairly simple as far as compilers go: variables can be assigned a memory index, and compiling an arithmetic expression essentially involves converting it to reverse Polish notation (eg. (3 + 5) * (x + y) -> PUSH 3 PUSH 5 ADD PUSH 0 MLOAD PUSH 1 MLOAD ADD MUL). First-class function languages are more involved due to variable scoping, but the problem is nevertheless tractable. The likely solution will be to maintain a linked list of stack frames in memory, giving each stack frame N memory slots where N is the total number of distinct variable names in the program. Variable access will consist of searching down the stack frame list until one frame contains a pointer to the variable, copying the pointer to the top stack frame for memoization purposes, and returning the value at the pointer. However, these are longer term concerns; compilation is separate from the actual protocol, and so it will be possible to continue to research compilation strategies long after the network is set running. - - -## Fees - -In Bitcoin, there are no mandatory transaction fees. Transactions can optionally include fees which are paid to miners, and it is up to the miners to decide what fees they are willing to accept. In Bitcoin, such a mechanism is already imperfect; the need for a 1 MB block size limit alongside the fee mechanism shows this all too well. In Ethereum, because of its Turing-completeness, a purely voluntary fee system would be catastrophic. Instead, Ethereum will have a system of mandatory fees, including a transaction fee and six fees for contract computations. The fees are currently set to: - -* TXFEE (100x) - fee for sending a transaction -* NEWCONTRACTFEE (100x) - fee for creating a new contract, not including the storage fee for each item in script code -* STEPFEE (1x) - fee for every computational step after than first sixteen in contract execution -* STORAGEFEE (5x) - per-byte fee for adding to contract storage. The storage fee is the only fee that is not paid to a miner, and is refunded when storage used by a contract is reduced or removed. -* DATAFEE (20x) - fee for accessing or setting a contract's memory from inside that contract -* EXTROFEE (40x) - fee for accessing memory from another contract inside a contract -* CRYPTOFEE (20x) - fee for using any of the cryptographic operations - - -The coefficients will be revised as more hard data on the relative computational cost of each operation becomes available. The hardest part will be setting the value of x. There are currently two main solutions that we are considering: - -* Make x inversely proportional to the square root of the difficulty, so x = floor(10^21 / floor(difficulty ^ 0.5)). This automatically adjusts fees down as the value of ether goes up, and adjusts fees down as computers get more powerful due to Moore's Law. -* Use proof of stake voting to determine the fees. In theory, stakeholders do not benefit directly from fees going up or down, so their incentives would be to make the decision that would maximize the value of the network. - -A hybrid solution is also possible, using proof of stake voting, but with the inverse square root mechanism as an initial policy. - - -## Conclusion - -The Ethereum protocol's design philosophy is in many ways the opposite from that taken by many other cryptocurrencies today. Other cryptocurrencies aim to add complexity and increase the number of "features"; Ethereum, on the other hand, takes features away. The protocol does not "support" multisignature transactions, multiple inputs and outputs, hash codes, lock times or many other features that even Bitcoin provides. Instead, all complexity comes from a universal, Turing-complete scripting language, which can be used to build up literally any feature that is mathematically describable through the contract mechanism. As a result, we have a protocol with unique potential; rather than being a closed-ended, single-purpose protocol intended for a specific array of applications in data storage, gambling or finance, Ethereum is open-ended by design, and we believe that it is extremely well-suited to serving as a foundational layer for a very large number of both financial and non-financial protocols in the years to come. - - -## References and Further Reading - -1. Colored coins whitepaper: https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit -2. Mastercoin whitepaper: https://github.com/mastercoin-MSC/spec -3. Decentralized autonomous corporations, Bitcoin Magazine: http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/ -4. Smart property: https://en.bitcoin.it/wiki/Smart_Property -5. Smart contracts: https://en.bitcoin.it/wiki/Contracts -6. Simplified payment verification: https://en.bitcoin.it/wiki/Scalability#Simplifiedpaymentverification -7. Merkle trees: http://en.wikipedia.org/wiki/Merkle_tree -8. Patricia trees: http://en.wikipedia.org/wiki/Patricia_tree -9. Bitcoin whitepaper: http://bitcoin.org/bitcoin.pdf -10. GHOST: http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf -11. StorJ and Autonomous Agents, Jeff Garzik: http://garzikrants.blogspot.ca/2013/01/storj-and-bitcoin-autonomous-agents.html -12. Mike Hearn on Smart Property at Turing Festival: http://www.youtube.com/watch?v=Pu4PAMFPo5Y -13. Ethereum RLP: http://wiki.ethereum.org/index.php/RLP -14. Ethereum Merkle Patricia trees: http://wiki.ethereum.org/index.php/Patricia_Tree -15. Ethereum Dagger: http://wiki.ethereum.org/index.php/Dagger -16. Ethereum C-like language: http://wiki.ethereum.org/index.php/CLL -17. Ethereum Slasher: http://blog.ethereum.org/?p=39/slasher-a-punitive-proof-of-stake-algorithm -18. Scrypt parameters: https://litecoin.info/User:Iddo/ComparisonbetweenLitecoinandBitcoin#SHA256miningvsscryptmining -19. Litecoin ASICs: https://axablends.com/merchants-accepting-bitcoin/litecoin-discussion/litecoin-scrypt-asic-miners/ \ No newline at end of file diff --git a/pages/other-languages/[italian]-ethereum-toc.md b/pages/other-languages/[italian]-ethereum-toc.md deleted file mode 100644 index 8431be229..000000000 --- a/pages/other-languages/[italian]-ethereum-toc.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -name: Ethereum TOC -category: ---- - -### Benvenuti. Ethereum: il contratto intelligente di nuova generazione e piattaforma di applicazioni decentralizzate. - -[Libro Bianco di Ethereum](https://github.com/ethereum/wiki/wiki/%5BItalian%5D-Libro-Bianco) - -[RLP](https://google.it), la caratteristica del prefisso lineare ricorsivo, utilizzato per la codifica dei dati attraverso Ethereum. - -[Patricia Tree](https://google.it) la caratteristica dell'albero Merkle Patricia (conosciuta anche come Trie), la struttura utilizzata per archiviare e processare attraverso la funzione di Hash lo stato della catena di blocchi in Ethereum. - -[Protocollo di connessione](https://google.it), caratteristiche. - -[Serpente](https://google.it), il linguaggio di alto livello usato per scrivere contratti. Vedi il tutorial qui. - -[LLL](https://google.it), caratteristica di Basso-Livello "Linguaggio di Basso Livello", usata per scrivere contratti nella serie PoC da Poc-3 - -[Dagger](https://google.com), Prova di lavoro "proof-of-work" di Ethereum. - -[Protocollo di Blocco 2.0](https://google.it) - -[Protocolli](https://google.it) - -[Camera di Compensazione](https://google.it) - -[Introduzione allo sviluppo su Ethereum](https://github.com/ethereum/wiki/wiki/%5BItalian%5D-Introduzione-allo-sviluppo-su-Ethereum) - -[Impostare il proprio ambiente di sviluppo Ethereum](https://github.com/ethereum/wiki/wiki/%5BItalian%5D-Impostare-il-proprio-ambiente-di-sviluppo-Ethereum) \ No newline at end of file diff --git a/pages/other-languages/[japanese]-design-rationale.md b/pages/other-languages/[japanese]-design-rationale.md deleted file mode 100644 index 56b1f9b4c..000000000 --- a/pages/other-languages/[japanese]-design-rationale.md +++ /dev/null @@ -1,610 +0,0 @@ ---- -name: Design Rationale -category: ---- - -Ethereum が既に試されテストされてきた5年前からあるビットコインのような -古くからある暗号通貨の様々なアイディアを借りて出来てきたとしても、 -Ethereumには現在のプロトコルの機能を提供するための大半の一般的な方法とは異なる様々な点がある。 -全くもって新しい経済的なアプローチをEthereumが開発しなければならなかった状況がある。 -何故ならば、既存の他のシステムによって提供されて来なかった機能をEthereumは提供しているためだ。 -この文書の目的は潜在的に自明ではないことを叙述し、もしくはEthereumのプロトコルを創りあげていく経過において、 -議論の的となる物事に対して為されてきた決定についてを叙述し、同様に我々のアプローチと、その他の代替手段の可能性におけるリスクを示すことである。 - -##原理 -Ethereumのプロトコルの仕様は幾つかの原理に基づいている。: - -1. **Sandwich Complexity Model**: -我々はボトムレベルのEthereumの構造は出来る限りシンプルであるべきだと信じている。 -そして、そのEthereuのインターフェイスは(開発者にとっての高位のプログラミングの言語、そしてユーザーにとってユーザーインターフェイスを含めて)出来る限り理解しやすいものであるべきだと信じている。 -複雑であることが避けられないのであれば、複雑なことはプロトコルの"中間層"に押しやられるべきだ。 -核となるコンセンサスの一部ではなく、エンドユーザーからも見ることが出来ない場所である。 -例えば、高位の言語のコンパイラ、Serializationとdeserializationを行うスクリプトの引数、ストレージデータにとる構造のモデル、そのleveldbストレージのインターフェース、そしてwire protocol等だ、しかしながらこれらの設定は絶対的なものではない。 - -2. **自由**:ユーザーはEthereumのプロトコルの目的に制限されるべきではない。 -そして我々はEthereumの特定のコントラクトや、特定の意図を持って作られたトランザクションに対して、賛成か反対かを選択的に述べようとするべきではない。このことは"本質的な中立状態"のコンセプトに基づく原則と似ている。 -この原理に従わない例を1つ上げると、ビットコインのトランザクションプロトコルの中で -ブロックチェーンを"オフレベル"の使い方(例えばデータストレージや、メタープロトコル)を阻害されることや、 -ブロックチェーンを"認められていない”使われ方で使っているアプリケーションへの攻撃の目的のために、 -あからさまな外面的なプロトコルの変更が(例えばOP_RETURNの規制が40バイトのこと)作られることが上げられる。 -Ethereum では、我々はトランザクションのフィーをインセンティブと強く連動するように設計する思想に強く賛成している。 -それはブロックチェーンの肥大を生み出す使い方をしてブロックチェーンを使うユーザーに対しては、彼ら自身にコストを内在化させるような使い方である。(例えば、[ピグー税](http://ja.wikipedia.org/wiki/%E3%83%94%E3%82%B0%E3%83%BC%E7%A8%8E)) - -3. **一般化**: Ethereum におけるプロトコルとOpcodesの仕様は、出来るだけ低レベルのコンセプトを内包するべきである。そのことによって、現在は有用には見えないかもしれないが将来的には有用になりうる任意の使い方で構成されることが出来るようになる。 -そしてそのために効率的に他の必要ではない機能を削ぎ落とすことに依って、ローレベルのコンセプトの設計は一層効率的になりうるだろう。 -この原理に従う例は、DAPPSのフィードの情報(とりわけ軽いクライアント)を取るための、ログ用のLOG OPCODEの選択の例がある。 -内部で早い頃から提案されたように、シンプルに全てのトランザクションとメッセージのログを取ることとは対照的な例だ。 -"メッセージ"のコンセプトには、"関数の呼び出し"、"外部の観察者に対してのイベントリッスン"を含む、多くのコンセプトが集まっていて、メッセージと、トランザクションとは切り分けることが妥当であった。 - -4. **我々は機能を持たない**: 一般化に対しての必然的な帰結として、我々は直感的にプロトコルのパーツとなるような非常にありふれたハイレベルのユースケースの構築を断ることがある。 -もし人々が本当にそれを欲しているならば、常にサブのプロトコル(例えばEtherをベースとしたサブの貨幣や、bitcoin/litecoin/dogecoin/sidechain等)として、契約の内部に作るだろうと考えているためだ。 -例をあげるとBitcoinのロックタイムのような機能がEthereumの中には無い。 -そのような機能は、"署名されたデータパケット"を送ったり、 -そしてそのデータのパケットは特定の契約の意味で有用かもしれない; - -5. **リスクを嫌悪しない**: もしリスクが増大していくような変更がとても大きい利益をもたらすのであれば、我々は高いリスクを受け入れる。(例えば一般化された状態遷移や、50倍の速度のブロック承認時間、コンセンサスの合意性、等だ) -これらの原則は全てEthreumの開発の方針であるが、絶対的でな方針ではない。 -例をあげると、開発の時間を減らし、とても多くの急激な変更を一度に行わないようにしたいと思ってしまってことで -ある変更を行うにあたって遅延をもたらしたことがある。その変更が明らかに将来のリリースに向けてメリットが有ることであったとしても。(例えば Ethereum1.1) - -## ブロックチェーンレベルでのプロトコル - -このセクションでは、Ethereumで為されたいくつかのブロックチェーンレベルでのプロトコルの変更についての詳細を記載する。 -どのようにしてトランザクションが機能しているのか、 -そしてどのようにしてデータがシリアライズされ保存されているのか、アカウントの背後にあるメカニズムについてを記載する。 - -### アカウントと、非UTXOs - -ビットコイン、そしてビットコインに付帯する多くのデリバティブ、ユーザーのバランスについてのデータは、 -使われていないトランザクションのアウトプットに基づく構造の中にある。 -システム内のすべての状態は、"Unspent Outputs"(例:コイン)から成り立っている。 -それは下記のような制約が有効であることのもとに、 -それぞれのコインが所持者と価値を持ち、トランザクションは1つ以上のコインを使い、1つ以上の新しいコインを作り出す。 - -1. あらゆる参照されているインプットは正しく、そして未だ使われていない状態である必要がある。 -2. 全てのインプットの場合において、トランザクションに記載されている署名はインプットの所持者のものと一致していなければならない。 -3. インプットの合計の価値は、アウトプットの合計の価値と等しいか、もしくは少なくなければならない。 - -システムにおける有るユーザーの残高は、上記のようにして、秘密鍵をもっているユーザーが有効な署名を作り出すことが出来るコインの合計の価値である。 - -![](https://bitcoin.org/img/dev/en-transaction-propagation.svg) -(Image from https://bitcoin.org/en/developer-guide) - -Ethereumは、より単純なアプローチに賛同し、ビットコインのスキームを投げ捨てる。状態はそれぞれが残高を所持しているアカウントの一覧を保持し、同様にEthereum特有のコードと内部のストレージデータを保持する。 -そして、もし送り手が、送る分の価値に値する十分な残高を持っているならば、トランザクションは正当なものであり、 -その場合において、送り手のアカウントから送った分の価値は引き落とされ、受け取り手は送られた価値を受け取る。 -もし受取り手のアカウントがコードを持っていたならば、コードは実行され内部のストレージも同時に変更されるかもしれない。 -もしくは受け取り手のアカウントのコードは新たな追加のメッセージを生成し、引き落としや、受け取りに繋がっている他のアカウントに送ることかもしれない。 - -UTXOsのメリットには下記がある。: -1. **高水準ののプライバシー**: -もしあるユーザーが各々のトランザクションで新しいアカウントを使うのであれば、 -アカウントとアドレスとを結びつけることは通常難しいだろう。 -このことはとても通貨にとって適している性質だ。だが、任意のDapps(分散形のアプリ)としては適していない。 -何故なら任意の分散形のアプリは複雑な塊となった情報のユーザーの状態を追いかける必要がよくあるため、 -通貨システムのように簡単なユーザーの状態が切り分けられる状態が、存在しないかもしれないからだ。 - -2. **潜在的にスケーラビリティのある仕組み**: -UTXOsは理論的にある種のスケーラビリティがあるパラダイムとよく適合している。 -何故なら我々は、マークルツリー上で所有権を証明している幾つかのコインの所有者だけに依存しているため -オーナーを含めた誰もがその所有権のデータを忘れると決めた場合でさえも、オーナーだけが損害を受けることで済むからだ。 -アカウントの考え方では、すべての人が有るアカウントに対応するマークルツリーの一片を失うことで -そのアカウントに対して送られているメッセージの実行が不可能になってしまう。 -しかしながらUTXOに依存しないスキームにも、スケーラビリティが確かにある。 - -アカウントによるメリットは下記がある: - -1. **大きなスペースの節約**: 例えばひとつのアカウントが5つのUTXOを持っているとした時、 -UTXOモデルからアカウントモデルに切り替えれば、 -必要なスペースは(20 + 32 + 8) * 5 = 300 bytes (20 はアドレスに, 32 はトランザクションIDに and 8は送信する価値に)から -20 + 8 + 2 = 30 bytes (20 はアドレスに, 8 は送信する価値に、2 はNonce(1度だけ使われる番号)に))となる。 -実際のスペースの節約はこれほど大きなものにはならない、何故ならアカウントはパトリシアツリー上に保存される必要があるためだ。 -しかしそうであったとしても大きな節約だ。 -加えて、トランザクションはより小さくすることが出来る(例えば、Ethereum上の100バイトと、Bitcoin上の200-250バイト)、何故ならばあらゆるトランザクションは1回の参照と1回の署名を行い、1つのアウトプットを出すだけを必要とするからだ。 - -2. **大きな代替性**: ある種のコインの元となるブロックチェーンレベルでないコンセプトの存在に対して、 -レッドリストやブラックリストを行うための仕組みを構築し、何に依拠しているコインなのかに判別を付けることは -技術的にも法的にも実用的な手段でなくなっている。 - -3. **シンプルさ**: -とりわけ一旦一層複雑なスクリプトが含まれたときに、より簡単にコードが書け、分かりやすくすること。 -任意の分散形のアプリケーションをUTXOの考え方という、狭い場所へと押しこむことも出来るが、 -根本的にスクリプトに対してどのようなUTXOに対して与えられたUTXOが使われる事が出来るかといったことを成約する能力を与え、 -スクリプトが判別できる「アプリケーションの状態のルートの変更」のマークルツリーによる証明、を含めることを必要とすることは -そんな概念は、ただアカウントという概念を使うことよりも一層複雑で汚いものだ。 - -4. **定量で軽量なクライアントによる参照** : -軽量なクライアントはあらゆる点において、特定の方向に状態のツリーをみていくことで、 -有るアカウントに関連する全てのデータにアクセスすることが可能である。 -UTXOの考え方では、参照は各々のトランザクションごとに変更してしまうものであり、 -長期的に稼働し、上記に述べたUTXO上の状態のルートを伝播するメカニズムを用いようとするDAppsに対しては、 -とりわけ重荷となる問題である。 - -我々は任意の状態とコードを含んでいるDappsとやり取りしなければならないという問題のために、 -アカウントを導入する事によるメリットは、代替手段を超える大きな方法であると決定している。 -加えて我々の"機能を持たない"という原理の志のもと、人々が本当にプライバシーを気にするのであれば、 -コインを混ぜるミキサーや、コインジョインの仕組みを -プロトコルの署名されたデータパケットを通じて、コントラクトの内側に設計出来るだろうと考えている。 - -1つのアカウントの思想の弱点は、リプレイアタックを防ぐために、 -全てのトランザクションは"nonce"一度だけ使う数値を持たなければならないことだ。 -そのようなアカウントは最後に使われたnonce を追跡し、nonceが最後のnonceが使われた丁度一回後の場合にのみトランザクションを受け入れるようにする。これは、もはや使われなくなったアカウントでさえも、決してアカウントの状態から切り取られることが出来ないということを意味する。この問題の簡単な解決策は、トランザクションがブロックの番号を保持することを求めるようにすることだ。 -一定の時間の後にしかリプレイが出来ないようにして、一定期間ごとにnonceをリセットする。 -マイナーや、他のユーザーは使われていないアカウントを状態から取り除くために、使われていないアカウントへの"ping"を必要とするだろう。ブロックチェーンプロトコル全体の一部として、完全に消し去ることはあまりにもコストの掛かって不可能なオペレーションであるためだ。Ethereum のバージョン1.0では開発の加速のためにこのメカニズムを採用しなかったが、1.1ではこのようなシステムを使うだろう。 - -## マークルパトリシアツリー -マークルパトリシアツリーは、アランレイナーによって構想され、Rippleのプロトコルの中に実装されたもので、 -Ethereumの基礎となるデータの構造であり、全てのアカウントの状態の保存に使われている。 -同様にトランザクションや、それぞれのブロック内のお釣りの保存にも使われている。 -MPTは[マークルツリー](https://en.wikipedia.org/wiki/Merkle_tree) と [パトリシアツリー](https://en.wikipedia.org/wiki/Radix_tree), -の組み合わせであり、両方の要素を取って、下記の要素に従う形で構造を作り出している。 - -1. 全てのユニークなKeyValueの組みは、独自のルートハッシュにマッピングされる。 -そしてツリー上のKeyVelueの組みのメンバーシップを偽装することは不可能である。 -(攻撃者が2^128以上のコンピューターパワーを持たない限り) -2. 変更すること、追加すること、削除することは対数的な時間の中で可能。 -これによって私達に効率的で更新が簡単な全体の状態を記載した我々のツリー上の"フィンガープリント"の方法を提供してくれる。 -EthererumのMPT(Merkle Patricia Tree)は正式に下記に示されている。 https://github.com/ethereum/wiki/wiki/Patricia-Tree - -MPTの上の仕様は下記の決定事項を含む: -1. **2つのクラスのノードを持つ**、KV(キーバリュー)のノードとそこから派生したノード(更なる詳細についてのMPTの仕様を見て欲しい)KVノードがあることでより効率的になる、何故ならばツリーが特定のエリアにまばらに存在することで、KVのノードがショートカットとしての役割を持つため、64層の深さのツリーを保つ必要が無くなるからだ。 - -2. **バイナリではないヘックスの派生ノード**: -これはルックアップの効率を改善するために為された。 -我々は現在準最適な選択を行ってきた、何故ならヘックスツリーのルックアップの効率は -まとまったノードを保存することによるバイナリーでの構想においてもシミュレーション出来からだ。 -しかしながら、ツリーの構造を誤った形で構成することはとても簡単であるために、 -最低でもルートの状態が合わなくなってしまうことには殆どならない。 -我々は1.1のバージョン迄にそのような再構成を審議することを決定した。 -3. **空のバリューと、メンバーシップが無いことの区別を行わない事**: -シンプルさのために為された。組みになっていないバリューは一般的にゼロかか空のがゼロを表すために使われているという -Ethereumのデフォルトの仕様とよく合っているからだ。 -しかしながら他の一般性と、このように僅かばかり準最適な方法を取っていると強く思っている。 -4. **終了したノードと終了していないノードの区別**: -技術的には、"ノードは終わりかけている"のフラグは必要が無い。 -何故ならEthereumの全てのツリーは固定長のキーを保存するために使われているからだ。 -だが、EthereumのMTPの実装が他の暗号プロトコルにそのまま使われるだろうと思い、一般性を高めるために付け加えた。 - -5. **Sha3(k)を使うことに依って、キーが安全なツリーの中に保存されること(状態とアカウントを保存するツリーの中に使われている) ** -このことは、64層の深さのノードから派生した最大限望ましくないチェインを設定して、 -何度もSLOADとSSTOREを呼び出すことによって、DDoS攻撃をツリーに対して行うことを一層難しくしている。 -より一層ツリーを列挙することを難しくために、もし列挙出来る限界をクライアントに設けたいと思うのであれば、 -そのための最もシンプルな方法はデータベースマッピングをsha3(k)->k.RLPに対して行うことだ。 - -## RLP -RLP(Recursive Length Prefix: 再帰的な長さの接頭辞)エンコーディングは、 -Ethereumで使われている主要なシリアライゼーションの形式だ。 -そして、Block,Transaction,アカウントの状態のデータ、そして配線プロトコルのメッセージといっった全ての場所で使われている。 -RLPは正式に下記にて述べられている。https://github.com/ethereum/wiki/wiki/RLP - -RLPは高度に最小主義なシリアライゼーションのフォーマットとして作られた。 -ネストされたバイトアレイを保存する目的のためのみにある。 -Protobufや、BSONや既存の他の解決策と違って、RLPはbooleanやfloatやdoubleや、integerさえも定義しようとしない。 -代わりに只シンプルに、ネストされたアレイの形で構造を保存するために存在し、 -アレイの意味を決定することはプロトコルに任せて、保存状態を残している。 -Key Valueのマップは明示的にサポートされてはいないが、準公式なKeyValueのマッピングのサポートのための提案は、 -k1, k2がある場所において、 [[k1, v1], [k2, v2], ...] をストリングに対する通常の順番を使ってソートすることだ。 - -RLPの代替手段として、ProtobufやBSONのような現在のアルゴリズムに使われていたかもしれないが、 -しかしながら(1)実装のシンプルさ、(2)バイトが完全に一貫していることを保証するために我々はRLPを使うことが良いと考えている。 -多くの言語におけるキーバリューのマップは明らかなオーダーを持たない、そしてフロートのポイントのフォーマットについて多くの特別な場合を持ち、潜在的に同じデータが違うコーディングとなることに繋がっている。そしてそのようにして違うハッシュ値となる。 -プロトコルを内製することによって、我々はこれらのゴールを念頭に置いた仕様を保証することが出来る。(これは例えばVMのようなコードの一部にも当てはまる一般的な原理である。) -BitTorrent にて使われているbencodeは、RLPに代わって通用する代替手段を持つかもしれない、 -だがバイナリーのRLPに比べると長さを表すための小数のエンコーディングはやや準最適である。 - -## 圧縮のアルゴリズム -ワイヤプロトコルと、データベースがどちらもカスタムの圧縮アルゴリズムを、データ保存のために用いている。 -そのアルゴリズムは、ゼロをランレングス符号かし、他の値はそのまま残すものとして、最も分かりやすく表現出来る。 - ->>> compress('horse') -'horse' ->>> compress('donkey dragon 1231231243') -'donkey dragon 1231231243' ->>> compress('\xf8\xaf\xf8\xab\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbe{b\xd5\xcd\x8d\x87\x97') -'\xf8\xaf\xf8\xab\xa0\xfe\x9e\xbe{b\xd5\xcd\x8d\x87\x97' ->>> compress("\xc5\xd2F\x01\x86\xf7#<\x92~}\xb2\xdc\xc7\x03\xc0\xe5\x00\xb6S\xca\x82';{\xfa\xd8\x04]\x85\xa4p") -'\xfe\x01' - -この圧縮のアルゴリズムが存在する前には、多くのEthereum protocol 上の部分では数多くの特別な場合があった。 -例えばsha3が良くsha3('') = ''としてオーバーライドされ, -アカウント内にコードやストレージを保存する必要が無かったことから64バイトを保存しただろう。 -しかしながらスペシャルキャラクターを最近取り除いたことに寄って、 -Ethereumのデータ構造はデフォルトで一層束となった形になった。 -ユーザーのデータベースにワイヤプロトコルを断続無しに導入することによって、 -ブロックチェーンの外のレイヤーに機能的にデータを保存する代わりに、 -データを機能的にブロックチェーンのプロトコルの外側に加える代わりにwire protocolに加える事に依って、 -断続無くEthereumのデータをユーザーのデータベースに挿入することが出来る実装 -このことはコンセンサスのレイヤーにおいて、モジュラリティを追加し、単純化する。 -そして比較的簡単にデプロイを行うための圧縮アルゴリズムに対しての継続的な更新を行うことを可能にしている。 -(例えばネットワークのプロトコルのバージョン更新) - -## ツリーの使い方 - -警告:このセクションではどのようにしてブルームフィルターが働くかの知識を前提としている。 -導入として下記を参照 http://en.wikipedia.org/wiki/Bloom_filter - -全てのEthereumのブロックチェーン上のブロックのヘッダーは、3つの樹に対してのポインターを含んでいる。 -ブロックにアクセスした後の全体のツリー状態を示す、状態のツリー -インデックスに依ってキーとされたブロック上の全てのトランザクションを示している、トランザクションのツリー -(例えば key0: 実行される最初のトランザクション、key1 :2番目のトランザクション、等 ) -そしてあらゆるトランザクションの"お釣り"に対応している、お釣りのツリーだ。 -トランザクションのお釣りはRLPエンコードされた下記のデータの構造となっている。 -構造: -[medstate, gas_used, logbloom, logs] - -詳細: -* medstateは、トランザクションが執行された後のステートツリーのルートである。 -* gas_usedは、トランザクションのプロセスのために使われたgas の量である。 -* logsは、[address, [topic1, topic2... ],data]の形式のデーターのリストを表しており、 -トランザクションの執行の間のLOG0 ... LOG4のopcodeによって作られている。(主要コールとサブのコールを含めて) -addressは、そのログを生成したコントラクト上のアドレスを示している。topicは4 32バイトの値にまでなり、データは任意のサイズのバイトのアレイだ。 -*logbloom は、トランザクション内の全てのログが基づくアドレスとトピックから構成されるbloom filterである。 - -bloom はブロックのヘッダー内、それはブロック内のトランザクションに対するの全てのbloomのORであるブロックヘッダーの中にある。 -この構造の目的は、ライトクライアントにとってEthereumのプロトコルを様々な方法で出来るだけ使いやすい形にするためである。 - -Ethereumにおいてライトクライアントは、デフォルトでブロックのヘッダーをダウンロードし、 -DHTをローカルのハードドライブ上のツリーのノードのデータベースとして使うことに依って、わずかな断片だけを承認していくと考えている。 -幾つかの下記の使い方を含む: -* ライトクライアントはアカウントの状態を特定の時間において知ることを望んでいる -(nonce, balance, code, 又はstorage のインデックス) -* ライトクライアントは単純に再帰的に状態のルートからツリーのノードをダウンロード出来る、任意の値に達する迄。 -* ライトクライアントは、トランザクションが承認されたかを確認したい。 -* ライトクライアントは単純にトランザクションのインデックスとブロックの番号についてネットワークに問い合わせることが出来る。 -そして再帰的にトランザクションのツリーをダウンロードして利用可能かどうかを確かめることが出来る。 -ライトクライアントは合計でデータの有効性を確かめたい。 -それぞれのライトクライアントが、c[i]は1つのトランザクションのindex iをトランザクション T[i](R[i]のお釣りに対応する。) -そして下記のように作動する。 -* R[i-1].medstate、 R[i-1].gas_used(if i = 0 use the parent endstate and 0 gas_used)を生成 -* T[i]のトランザクションの実行 -* 結果として生じるState Root が R[i].medstateであり、その gas_used がR[i].gas_usedであることを確認 -ログと、出来上がったbloomの組みが R[i].logsとR[i].logbloomと合うことを確認 -* bloomがブロックヘッダーレベルのbloomのサブ集合(これはブロックヘッダーレベルのBloomが間違っている事を検出する)であることを確認。そして幾つかのランダムのブロックヘッダーレベルのインデックスを取得し、 -ブルームが1つか他のトランザクションレベルのブルームを持ち、 -もしレスポンスが与えられていなかった場合には、ブロックを拒絶する。 -* ライトクライアントは記録されるイベントを"watch"したいと思う。 -その場合のプロトコルは下記に従う。 -* ライトクライアントは全てのブロックのヘッダーを取得し、ライトクライアントが求めるアドレスかトピックのリストの1つと適合するbloom filterを、ブロックヘッダーが含んでいるかを確認する。 -* 潜在的に適合しているブロックヘッダーを見つけた場合、ライトクライアントは -ブルームフィルターに適合する全てのトランザクションのレシートと、トランザクションに対する証明を取得する。 -* 潜在的に適合しているトランザクションを見つけた場合、ライトクライアントは実際のLOGのRLPを確かめ、それが実際に適合するかどうかを確認する。 - -最初の3つのライトクライアントのプロトコルでは対数量のデータ・アクセスとコンピュテーションが必要となる。 -最初の4つ目では~0(Nの平方根)ブルームフィルターから只2階層だけ、だがこのことは0(log(N))に対して改善が為される。 -もしライトクライアントが様々なプロバイダーに依拠しようとするのであれば、"興味を持っている”トランザクションのインデックスを指し示し、もし間違ったトランザクションを所持していることが公開されれば、プロバイダーへの依存を解除うsる。 -その最初のプロトコルは単純に状態を確認するために有用であr,2爪のプロトコルは、消費者と承認のようなシナリオにおいて、トランザクションが認証されたどうかを確認するために有用である。 -3つ目のプロトコルは、Ethereuのライトクライアントがブロックをとても少ない量のトラストによって承認出来るようにしている。 -ビットコインでは、例えばマイナーはマイナーに対して多大な料のトランザクションの費用を払うブロックを生成することが出来る。 -そして軽量ノードにとってこのことを知る術はない、また、正直な全てのノードが検知することが出来た場合にも -その不当性を証明しなければならない -Ethereumでは、もしブロックが不当な場合には、不当な状態の遷移をどこかのindexで含んでいなければならない、そして -ライトクライアントは、何か間違っていることは無いかindex が見つけられるように認証することとなる。もしくは、データが使用不可能なためにその証明のステップが終わらないからだ、そしてクライアントは警告を上げることが出来る。 - -4つ目のプロトコルはDAPPが効率的に証明される必要のあるある種のイベントを追跡したい場合に有用である。 -例えば分散形の交換所でトレードのログを取るか、もしくはウォレットがトランザクションのログを取る(ライトクライアントが高いレベルのコインベースとアンクルのチェックがマイナーのアカウントに対して十分に働いた場合) -Bitcoinの言葉でいうと、ログは純粋な"Proof of publication"のopcode として考えられる。 - -## Uncleへのインセンティブ -The 強欲で最も重い監視されているサブツリー"(GHOST)プロトコルは、最初にYonatan Sompolinsky とAvivZoharによって2013年12月に導入されたイノベーションだ。[first introduced](http://eprint.iacr.org/2013/881.pdf) -そしてもっと早いブロックの時間を防ぐための問題解決策としての最初の重大な試みでもある。 -GHOSTが開発された動機は、承認時間の早いブロックチェーンが、古くなっていまう可能性が高いためにが -現在セキュリティリスクを抱えていることだ。 -何故ならブロックはネットワークに伝播するまでに一定時間必要であり、 -もしマイナーAがを採掘してマイナーBが他のブロックをマイナーAのブロックが伝播するまでにほった場合には、 -マイナーBのブロックは結局無駄("stale")してしまい、その仕事はネットワークのセキュリティの改善に寄与しないためだ。 -更に言えば、そこには中央集権の問題がある。:もしマイナ-Aがマイニングプール上で30%のハッシュパワーを持ち、Bは10%のハッシュパワーを持っているならば、Aは70%の時間無駄になるブロックを生み出すリスクをもっており、(Aが最後のブロックを生成した他の30%の時間から、そしてマイニングのデータをすぐに手に入れることになるだろう。)一方でBは90%の時間において無駄になるブロックを生成するリスクを取っている。 -このようにして、ブロックのインターバルがブロックが無駄になる確立が十分に高くなるほどに短かったとしても -Aはそのサイズのお陰で大変効率的でシンプルに採掘を行うことが出来る。 - -これらの2つ効果を組み合わせると、ブロックチェーンはブロックを早く生成し、 -1 -早くブロックを作り出していくブロックチェーンが存在することで、 -1つのマイニングプールが、マイニングのプロセスに対してネットワーク全体のハッシュパワーの十分に大きな割合を持つことで -デファクトのコントロールを持つことに繋がって行きやすくなるだろう。 - -Sompolinsky とZoharによって述べられたように、GHOSTはネットワークのセキュリティロスの最初の問題を、 -どのブロックが"最長"のブロックかを計算する中で、無駄となってしまったブロックを含める事によって改善した。 -即ち、ブロックの親と先祖を含めるだけでなく、無駄になった先祖のブロック(Ethereumの隠語で、"uncles")も含めることで、 -どのブロックが合計で最も長いproof of workのための計算に加えられることだ。 - -2つ目の中央集権による偏りの問題を解決するために我々は異なる戦略を採用する: -我々は無駄になったブロックに対しての報酬を無駄となったブロックに付与すること: -無駄となったブロックが7/8(87.5 %)のベースのリワードを受け取る事が出来、 -そして無駄となったブロックを含む甥が、ベースのリワードの1/32(3.125 %)をブロックを含めた報酬として受け取る事が出来る。 -しかしながら、トランザクションの費用は甥にもおじにも与えられることはない。 - -Ethereumでは、無駄となったブロックはおじによってのみ含まれる事ができ、7代目迄のその直接の兄弟の子孫が含まれ、 -そして一層の関係のブロックは含まれない。これはいくつかの理由によって為されている。 -初めに、無限のGHOSTはどのおじが与えられたブロックが有効かという計算を行うに当たって大変複雑となるからだ。 -2つ目には、無限のおじに対してのインセンティブがEthereuで使われることで、 -チェーンへの公衆の攻撃者ではなく、 -メインチェーンのマイナーにとって採掘するインセンティブを失わせることに繋がるからだ。 -最後に、多くのネガティブな影響無しに、7段階目迄に制限していることが大半の望ましい影響を及ぼしていることについての計算を示す。 -* 中央集権のリスクを測ったシミュレーターはこちらで利用可能だ。 -https://github.com/ethereum/economic-modeling/blob/master/ghost.py -* 高度なレベルの議論はこちらで行われている。 -https://blog.ethereum.org/2014/07/11/toward-a-12-second-block-time/ - -ブロックの承認時間のアルゴリズムについての仕様は下記を含む -* **12秒のブロック承認時間**: 出来るだけ早い時間として12秒が選ばれた。 -だが同時に、ネットワークの遅れよりもかなり長い時間である。 -2013年のDecker とWattenhoferによる論文では、Bitcoinのネットワークの遅れが計算されており、 -それは12.6秒が新しいブロックが残りの95%のノードに伝播する迄に必要なためだ。 -しかしながらその文書で指摘されていた伝播に掛かる全体の時間はブロックのサイズに比例するとも指摘されている。 -そのようにして、速い通貨において、伝播のための時間は、劇的に減少することが期待される。 -伝播に掛かる待機時間は凡そ2秒だが、安全のために我々の分析では12秒が伝播のために掛かると考えている。 -* **7ブロックの子孫の制限**: これは幾つかのブロックの後、ブロックの履歴をすぐに"忘れやすい"ものへとするための仕様だ、 -そして7ブロックが最も良い影響を与えることが証明された。 -* **1ブロックの子孫のリミット** (例: c(c(p(p(p(head))))), where c = chile and p = parent, is invalid): -このパートではシンプルさを仕様目標とし、上記のシミュレーターでは大きな中央集権型のリスクを持たないことを示す。 -* **Uncleブロックの正当性の要求**: Uncle(おじ)は認証されたブロックではなく、認証されたブロックヘッダーでなければならない。 -これはシンプルさを達成するためであり、ブロックチェーンのモデルを維持するために線形のデータ構造を取る(block-DAGではなく、SompolinskyとZoharの新しいモデル)。おじが正当なブロックであることを求めるのは同様に正当なアプローチである。 -* **報酬の分散**: 7/8のベースマイニングの報酬はおじにいき、残りの1/32は甥にいき、0%のトランザクション費用が双方に渡る。 -もし費用が独占されているならば、中央集権的な考え方からみるとおじに対してのインセンティブが有効でなくなるだろう。 -しかしながらこれはEthereumで、出来るだけProof of Work を使い、どうしてEtherを発行し続けようとしているのかという一つの理由である。 - -## 困難さをアップデートするアルゴリズム -Ethereumにおいての困難さの更新は下記のルールに従って行われる: -diff(genesis) = 2^32 -diff(block) - diff.block.parent + floor(diff.block.parent/1024)* - -The difficulty in Ethereum is currently updated according to the following rule: - -diff(genesis) = 2^32 -1 if block.timestamp - block.parent.timestamp < 9 else --1 if block.timestamp - block.parent.timestamp >= 9 - -diff(block) = diff.block.parent + floor(diff.block.parent / 1024) * - 1 if block.timestamp - block.parent.timestamp < 9 else - -1 if block.timestamp - block.parent.timestamp >= 9 -The design goals behind the difficulty update rule are: - -このdifficulty のアップデートの仕様は下記である。 -* **速いアップデート**: ブロック同士の間での読込が早ければ速いほど与えられたハッシュパワーの増大と現象にフィットする物となる。 -* **低いボラティリティ**: Difficulty はハッシュパワーがもし定数であるならば大きく変動するべきではない。 -* **シンプルさ**: アルゴリズムは比較的シンプルに実装できるべきである。 -* **メモリーを食わない**: アルゴリズムは幾つかのブロックの履歴に依拠するべきでなない、 -それは幾つかのメモリーの変数を出来る限り含むべきである。 -最後の10ブロックを考えると、最後の10ブロックのブロックのヘッダーに全てのメモリーの変数が置かれる。 -それはアルゴリズムが作用するために利用可能な全てのデータである。 -セキュリティーホールをなくす: アルゴリズムはマイナーに対して -彼らのレベニューを最大化させようという意図で、 -タイムスタンプや、マイニングプールでのハッシュパワーの増減の繰り返しをさせることを過度に奨励すべきではない。 -我々の現在のアルゴリズムは、高い副次的適合性を低いボラティリティと、セキュリティホールの防止策に対して準最適な方法として -既に決定している。そしてタイムスタンプを親や、祖父母のブロックとタイムスタンプを比べるように変更し -もしマイナーが2つの列になったブロックのマイニングを行っているならば、 -マイナーがタイムスタンプの書き換えに対してのみインセンティブを持つようにしようとは全く考えていない。 -もう一つのシミュレーションを伴う強力な定式はこちらにある。 -https://github.com/ethereum/economic-modeling/blob/master/diffadjust/blkdiff.py (シミュレーターはビットコインのマイニングパワーを用いているが、日ごとの平均を全体に対して使っている。1つのポイントでのシミュレーションは95%1日の内にクラッシュする。) - -## GasとFee - -全てのビットコイン内のトランザクションが殆ど同じであるとしても、ネットワークに対するコストは一つのユニットの中で形作られているために、Ethereumのトランザクションはより複雑である。そして、トランザクションのFeeのシステムは、ストレージのコストと、コンピュテーションのコストを含めて様々な要素を考慮に入れて設計されている。 -とりわけ重要な事は Ethereumのプログラミング言語はチューリング完全であることだ。 -そしてトランザクションはbandwidthを使っているかもしれず、ストレージは任意の量のコンピュテーションw行っているかもしれない。 -そして後半では先行して確かにわかったかもしれないが -先行して知ることは決して出来ないコンピューターの停止問題があるが故に、 -無限ループによるサービス妨害攻撃を防ぐために鍵となる目的である。 - -トランザクションの費用の背後にある基本となる作用は下記のとおりだ。 -* 全てのトランザクションは必ず"gas"の量を定義しなければならない。"gas"は(startgasと呼ばれる)使われようとし、 -そのフィーはgasの大きさに応じて支払われる(gasprice)。そして、プログラム開始時に、startgas* gasprice 分のetherが送り手のアカウントのトランザクションから取り除かれる。 -* トランザクションが実行されている際に、全てのオペレーション、databaseの読み書き、メッセージ、全てのコンピューテーションは、 -仮想マシーンによって 一定量のgas を消費することによって行われる。 -もしトランザクションの実行プロセスが完全に、一定量の限界よりも少ない量のガスを消費するのであれば、gas_rem(gasの残り)とともに行われる。そしてトランザクションが通常どおり執行されて、トランザクションの最後には、トランザクションの送り手はga_rem* gasprice分の返金を受け取る。そしてブロックのマイナーは(startgas-gas_rem)*gasprice分の報酬を受け取る。 -* もしトランザクションが"ガス切れ"に実行の最中でなった場合には、全ての実行プロセスは元の状態に戻り、 -トランザクション自体は正しいトランザクションであったにもかかわらず、トランザクションの影響は、 -ただ合計のstartgas*gasprice がマイナーに行き渡るだけとなる。 -* あるコントラクトがメッセージを他のコントラクトに送るときには、それはメッセージから現れたsub実行に対してのgaslimitを設定するオプションを持っている。もしsubの実行プロセスがgas切れになった際には、subの実行プロセスは以前の状態に戻され、 -そうであったにも拘らず、gasは消費される。 - -これらのコンポーネント必須要素である・例えば: - -* もしトランザクションがgasの上限を定めなくて良い場合には、悪意あるユーザーは何10億というループを作り出すトランザクションを送り、そのようなプロセスがブロックの同士の間隔よりも長くなってしまうことで、誰もプロセスを行うことが出来なくなる。 -だが、マイナーが事前にわからないんのであれば、サービス妨害攻撃に対する脆弱性へと繋がる。 - -* gas-countingを規制する他の選択肢は、時間制限である。 -何故ならばあまりにも他の(有るマシーンが他のマシーンよりも早い場合には同一するマシーンのクローズコールが常に存在する。) -Startgas * gaspriceの全体の価値は最初の時点でデポジットとして取り除かれるべきである、それによって -有るアカウントが自身の動作の実行によって、gasのコストが払えなくなって"破産する"こともなくなるような -シチュエーションが起こることを防ぐ事が出来る。 -もし実行がgas が足りないためにやり直す事ができない場合には、コントラクトはより強固で難しいセキュリティの手段を -* 只十分なガスが途中までしか足りていないトランザクションやメッセージによって -それによってコントラクトの実行における幾つかの変更に繋がるが他にはつながらない。 -* もしサブのリミットが存在しない場合には、敵対的なアカウントが、 -他のアカウントに対して合意を導入することによって、最初のコンピュテーションにおいて無限ループを導入し、 -被害者のコントラクトによるどんな攻撃社のコントラクトや、コントラクトに対してメッセージを送ることが全てのトランザクションの実行を枯れさせてしまうかもしれない。 -* トランザクションの送り手がコントラクトの代わりに、gas を送ることを要求することは、開発者の使い勝手をかなり大きく改善した。 -まさにEthereumが始まったばかりのころ、gasに対して費用を払うコントラクトがあったが、 -全てのコントラクトが"guard"するためのコード、即ち全ての受信するメッセージが、消費されるgasに対して支払うための十分なetherがあるかどうかををするためのコードを持たなければならないという、かなり汚い実装となってしまう問題に遭遇した。 - -下記がgasのコストについての仕様である。 -* 21000gas が全てのトランザクションに対して”base fee"としてチャージされる。 -これは楕円曲線のオペレーションを、送り手の署名からアドレスを再現し、 -同様に、トランザクションを保存しておくディスクと一定時間に処理できる情報量の空間を確保しておくための費用である。 -* トランザクションは無限の量のデータを含んでいる、そして仮想マシーンの中にはopcodeが存在している。 -仮想マシーンはコントラクトがデータにアクセスするためのトランザクションを受け取ることを可能としている。 -データに対してのgasの費用はゼロバイトに対して1gas、ノンゼロバイトに対して5 gasである。 -ユーザーによって書かれたコントラクト中の大半のトランザクションにおいて、 -32バイトの引数の列に構成されるとわかったため、この計算式とした。 -大半のコントラクトはゼロバイトになり、そのようなコンストラクションは不十分のように見えるが、 -実際には圧縮アルゴリズムのおかげによって、効率的なものである。 -我々はより複雑な期待されるバイト数に基づいて引数を厳しくパック仕様とするメカニズムのかわりとなる使い方を奨励したいと思っていて、 -まさにかなりの複雑さをコンパイラのレベルで増大させることへと繋がった。 -これは、Sandwich Complexity modelの例外であるが、コストに対するベネフィットが大きいために行われるべきと考えられたことである。 -* SSTOREのopcodeのコストは、アカウントのストレージのバリュ0、どちらかである -(i)20000gasがゼロバリューからノンゼロのバリューに変わる時に掛かる。 -(ii)5000gas がゼロバリューからノンゼロのバリューに変わるときに掛かる。 -(iii)5000gas がノンゼロのバリューからゼロバリューに代わる時に掛かる、加えて20000gasのりファンドが成功したトランザクションの最後尾に与えられる。(例えば 実行gas切れの例外にならないような実行) -Refundsはトランザクションによって消費される全体のガスの50%の部分に制限され、 -このことはストレージを消去するために少ないながらのインセンティブを提供する。 -インセンティブの仕組みが欠けているために、多くのコントラクトがstorageを使わない状態で残すだろうと我々は気づいた。 -我々がそのようなインセンティブのシステムが欠けていることに築き、ストレージが使われないままで残っていると、 -早くブロックチェーンの肥大へと繋がるだろう、そして大半のベネフィットを"利子を徴収する"。 -そして遅れたrefund のメカニズムは、アタッカーによって僅かな量のgasと共にトランザクションが送られ、何度も大きな量のストレージのスロットがクリアーされる類の攻撃に対して - サービスの否定攻撃を防ぐために必要である、 -長いループの一端となる、そしてgas切れとなることで、大量の承認者のコンピューターパワーを実際にはストレージをクリアすることもgas を消費することも無く行わせてしまう。 -この50%のcapは、マイナーに対して定量のガスト共に与えられたトランザクションを、 -マイナーが、トランザクションを実行するためのコンピューターパワーに対して課された上限を図るために必要である。 - -* コントラクトによって与えられたメッセージの中のデータに掛かるgasのコストは無い。 -これはメッセージコールの最中に、呼ばれたデータをコピーする必要は無いからだ、 -何故なら呼ばれたデータは、子の実行が進行中であった最中でも変わることのない -親のコントラクトのメモリーへのポインタとしてシンプルに考えることが出来るためである。 -* メモリーは無限に拡張可能なアレイだ。しかしながら32バイトのメモリーごとのメモリーの拡大に対してgasが掛かる。(切り上げ) -* 幾つかのopcodeではコンピュテーションの時間は大きく引数に依存する、様々なgasのコストを持ちうる。 -例えば、gasのコストとなるEXPが10+10バイトの指数であるとして(例, x^0 = 1 gas, x^1 ....x^255=2gas, x^256 ... x^65535 = 3gas, etc) -Copuするためのopcodesに掛かる(CALLDATACOPY, CODECOPY, EXTCODECOPY)gasのコストは 32バイトのコピー毎に対して、1 + 1掛かる。(切り上げ)(LOGも同様のに似ているルール). -メモリーの拡大に対してのgas残すとは、カバーするために十分ではない、quadraticな攻撃に対して開いている状態であるからである。 -(50000 回の 50000gasを消費するCALLDATACOPYを行い 50000^2のコンピューティングの費用だが、50000以内のgasしかgasのコストの変数が導入される前に提供されていないからだ。) -* CALLのopcode(そしてCALLCODEも同様に)そのバリューがノンゼロの場合には追加の9000gasを消費する。 -その理由はあらゆる価値の以降は、書庫となっているノードのための履歴のストレージに対して大変大きな肥大を招くためだ。 -実際のフィーは6700しかかかっていないが、我々は2300の人工的なgasを追加している、これは自動的に受信者に与えられるものだ。 -これはトランザクションを受け取るウォレットがトランザクションのログを作るために十分がgasを持っていることを保証するためだ。 - -gasのメカニズムについての他に重要な点は、gasの値段自体が経済となっていることだ。 -デフォルトの方法では、bitcoinで使われているように、純粋にボランティアの費用を落ち、 -マイナーがゲートキーパーとして働くことに依拠しており、ダイナミックな最低限の費用を設定することだ。 -Ethereumにおける同様の手段は、トランザクションの送り手が、自由にgasのコストを設定することを許すことだ。 -この方法では、Bitcoinのコミュニティに対して大きく賛同された、とりわけそれが"市場に基づいていて”、 -供給と需要が存在し、マイナー同士とトランザクションの送り手同士で値段を決定することを可能としているからだ。 - -この原理の問題は、しかしながらトランザクションのプロセスは市場には無いことだ、 -マイナーがセンダーに提供するサービスとしてトランザクションのプロセスに対して構文解析を行うことは直感的に魅力的だが、 -実際には全てのマイナーが含むトランザクションはネットワーク全体によって行われる必要がある。それ故にトランザクションに掛かるコストの殆ど大半は第三者に対して生じるものであり、トランザクションがブロックチェーンに含まれるかどうかを決定するマイナーに対してではない。それ故に、こうした一般的な問題はとても良く起こるのだ。 - -現在、現実にはどのようにしてマイナーが作業しているのかについての情報が欠如しているために、私達は大変シンプルなアプローチを行おうとしている。それは投票システムである。 -マイナーは最後のブロックの1/1024のgas limitとなるように、 -gas のlimitを現在のブロックに対して設定する権利を持っており、 -そして結果もたらされるgasのリミットは、マイナー達の設定の中央値となるべきである。 -将来我々がソフトフォークを可能にしてより正確なアルゴリズムとするだろう。 - -### 仮想マシーン -Ethereumの仮想マシーンは、トランザクションのコードを実行させるエンジンである。 -それはEthereumと他のシステムの根本的な違いだ。 -仮想マシーンがコントラクトとメッセージのモデルを分割したものとして考えるべきであることに注意して欲しい。 -例えば、SIGNEXTENDのopcodeはVMの機能の機能だが、実 -際にはコントラクトは他のコントラクトを呼び出し、サブコールに対してのgasの限界を定める事ができ、 -コントラクトとメッセージのモデルの一部におけるsub-callを行う事が出来る。 - -EVM内の設計原理は下記である。 -* **シンプルさ**: 少なく、そしてローレベルのopcodeで出来るだけ行う。なるべく少ないデータ型でなるべく少ない仮想マシーンレベルの設計を行う。 -* **統合的な決定性**: 絶対的なVMの仕様のどの部分においても曖昧な部分は許されない、そしてその結果として -完全に決定的なものとなる。加えて、gasの消費量を計算するために正確なコンピュテーションの段階のコンセプトがあるべきである。 -* **容量の節約**: EVMのアセンブルは出来るだけコンパクトでなければならない。(例; 4000バイトの基本サイズを持つCプログラムは受け入れられない) -* **期待されるアプリケーションに対しての特化性**: 20バイトのアドレスと、32バイトの値を持つカスタムの暗号を取扱うための能力、 -カスタムの暗号化を行うための数学的なモジュール、ブロックとトランザクションのデータを読み込むこと、状態とやりとりする能力 -* **シンプルなセキュリティ**: VMをセキュリティホールが無いものにするためのgasコストを利用するモデルを思いつくことは簡単だろう。 -* **最適化に対して使い勝手が良いこと**:最適化を導入するために簡単であること。JITでコンパイルされたものや、その他の方法で速度が改善されたバージョンのVMが構築出来るようにするためだ。 - -これ迄幾つかの特定の使用に対する決定がなされてきた。 -* **一時的/永続的なストレージの区別** -仮想マシーンのインスタンスの中に存在し、VMの実行が終わると同時に消滅する一時的なストレージと、 -アカウント毎にブロックチェーンに刻まれる状態のレベルで存在する永続的なストレージの2つには明確な区別が存在する。 -例えば、下記のようなツリー型の実行が行われることを考えてみよう。 -(Sは永続的なストレージに対して、そしてMは一時的なストレージに対してである。): -(i) AはBを呼び出す。 -(ii)Bは B.S[0] = 5, B.M[0] = 9 -(iii) B はCを呼び出す -(iv)CはBを呼び出す、ここでBがB.S[0]を呼びだそうとすれば、Bには以前から保存されていた値を受け取る。 -(v)だがmBがBを呼びだそうとし、この点において、もしBがB.M[0]を呼び出せば0を受け取る、なぜならば仮想マシーンの新しいインスタンスは新しい一時的なストレージを持つからだ。 -もし、BがB.M[0] = 13 とB.S[0] = 17 を内部のコールの中で行うと、この内部のコールもCのコールも終了し、 -Bの外部コールへと実行が戻される。 -この区別の目的は、 -(1)互いの実行うインスタンスが再帰的な呼び出しにより破壊されることのない自身のメモリーを与えるため。セキュアとし、プログラミングを簡単にするため。 -(2)とても早くメモリーを操作できる形式を提供すること、何故ならストレージの更新はツリーを変更する必要があるため、遅い必要があるからだ。 -* **スタック/メモリーモデル** -この決定が早くから為されたのは3つのタイプのコンピューターの状態を持つためだ。 -(プログラムのカウンターが次のインストラクションを指していることを脇においてだ。) -その3つの状態はスタック(通常の32バイト値のLIFOスタック)、 -そしてメモリー(無限に拡張可能な一時的なバイトアレイ)と -ストレージ(永続的なストレージ)だ。 -一時的なストレージ上では、スタックとメモリーの構成の代替は、メモリーだけの構成、もしくは -いくつかのレジスタとメモリーのハイブリッドの構成。(レジスタとメモリはあまり違わない、通常はレジスタは一種のメモリのため) -そのような状況において、あらゆるインストラクションは3つの引数を取っている、例えばADD R1 R2 R3: M[R1] = M[R2] + M[R3]. -スタックの考え方に従えば明らかな理由のために選ばれ、4倍以上コードを小さくする事が出来る。 -* **32バイトの文字のサイズ** 4か8バイトの単語の代替として、大半の他の構造で使われているように、もしくは無数にビットコインで使われているように。 -4 or 8 バイトの単語ではあまりにも制限が厳しくアドレスや、暗号の計算のための値を保存することが出来なかったり、 -制限が無い場合にはが安全なgasのモデルを作るためにあまりに厳しい場合がある。 -只十分に多くの暗号の実装で共通している32バイトの値は、十分に大きいからである、、それはアドレスについてもあてはまる(アドレスをパックして、単独のストレージの値へと挿入する最適化の方法として)、だが究極的に非効率というほど大きくはない。 - -* **我々独自のVMを持つこと**:代替案としてJavaを使うことや、幾つかのLispや、Luaのプログラミング言語を使うことが考えられるが、 -我々は特別なVMを持つことが適していると決定した。 -何故ならば -(i)我々のVMの仕様は他の多くのVMよりも大変シンプルだからである。 -何故なら他の仮想マシーンでは複雑さのために大変安いコストを払わなければならない、 -一方で、我々の場合、複雑なユニットを作り出すことは、開発が中央に集中している状況を作り出す高いバリアへと繋がり、 -コンセンサスが出来なくなるような、セキュリティホールの潜在的な可能性となるからだ。 -(ii)より一層VMを特殊に作る上げる事が出来る。例えば32バイトのサイズの宣言を持つことだ。 -(iii)インストール自体が難しくなってしまうというような、複雑な外部依存を持たないでいられる -(iv)我々の特定のセキュリティのニーズにEthereumに対しての全てのセキュリティのレビューを行うために外部のVMのセキュリティのレビューを行うことを余儀なくされてしまうだろう、そしてその努力で得られるものはあまり大きくない。 -* **様々な拡張可能なメモリーのサイズを使うこと。** もしサイズが小さく、もしサイズが大きければ不必要にコストが高くなるのであれば、我々は固定長のメモリーの長さの制約が必要無いと考えた。 -そしてもしメモリーアクセスのための宣言が必要無いのであれば、外部へのアクセスをチェックするどのような場合においても、固定長の長さは実行をより効率的にするだろう。 -* **スタックサイズの制限を持たないこと** 特定の理由が無い。多くの場合gasのコストと、ブロックレベルのgasの制限を組み合わせることに依って、制限は必ずしも必要ないことを心に留めて欲しい、 -これら2つの組み合わせによって、全てのリソースの消費に対して常に天井を設ける働きを実行できる。 -* **コールの深さを1024に制限すること** 多くのプログラミング言語では、スタックが深い点において、 -多くのメモリーの使用かコンピューター負荷によってプログラムが壊れるよりも一層早く、 -そのためにブロック内ののgasの制限による暗黙的なリミットだけでは十分ではない。 - -* **型を持たない*こと* シンプルさのために行った。代わりに、署名されたか署名されていないDIV, SDIV,MOD,SMODを示すopcodeを使った、(それはADDとMULとのためにあり、署名されたものと署名されていないopcoceは同様のものだ。 -そして固定長の場所に対しての算数(深い、固定された場所、数学的に他のベネフィットのある32バイトの文字)は皆シンプルである。 -例えば32ビットの深さでは、a * b -> (a * b )/ 2^32 , a / b -> a * 2^32 / b and +, - and * are unchanged from integer -仮想マシーンにおいて、関数と幾つかのopcodeの目的は明らかである、しかしながら他のopcodeはあまり自明ではない。 -例えば特定の理由は下記のように上げられる。 - -* **ADDMOD**, **MULMOD**: 大半の場合において、addmod(a, b, c) = a * b % cであるがしかしながら、 -楕円曲線暗号の多くのクラスは特定の場合ではそしてそのためにa * b % cを直接行うことで、それ故に実際に行っている。 -そして完全に異なる結果を生み出すこととなる。 -ある形式において、a * b % c を32バイトの値と共に32バイトのスペースにて行うことはかなり重く厚い処理となってしまう。 -* **SIGNEXTEND**: SIGNEXTENDの目的はtypecastingを大きな署名して大きな符号付き整数から、小さな符号付き整数へと型変換するためだ。 -小さな符号付き整数は有用である、何故ならばJITに依ってコンパイルされた仮想マシーンの環境では、 -32バイトの整数を第一義に扱って長く走っているコードの塊を検出し、かなりの速度向上が見込むことが出来るかもしれないからだ。 - -* **SHA3**: Ethereumでは、SHA3はとても応用性が高く、セキュアで無限の大きさのハッシュのマップが出来る。 -ストレージを扱うハッシュのマップは悪意ある衝突を防ぐために、 -セキュアなハッシュのファンクションを使う必要が出てくるだろう、同様にマークルツリーを認証するためにもそしてEthereumのようなデータの構造を認証するためにも使われるだろう。 -鍵となる点は、SHA3はSHA256や、ECRECOVERやRIPEMD160の対であることであり、opcodeではなく、仮のコントラクトして含まれている。 - -その目的は分割されたカテゴリーに暗号化の手段を分けることによって、 -もし、いつか正しい”ネイティブの拡張"によるシステムを考案した時に -より多くのそんなコントラクトを、opcodeの空間を埋めること無く加える事が出来るようにするためだ。 - -* **ORIGIN**: トランザクションの送り手を与えるORIGINのopcodeを使う第一の目的は、コントラクトがgasのためにリファンドの支払いが出来るようにするためだ。 - -* **COINBASE**: COINBASEの第一義的な使い方は、 -(i) 補助貨幣がネットワークのセキュリティの向上に役立つようにするため。 -(ii) Schelling coinのような副次的な分散形のアプリケーションのための、分散形の経済のセットとして -マイナーが使えるようにするようにするためだ。 -* **PREVHASH**: 程々にセキュアなランダムさを生み出すソースとして利用される。 -コントラクトが、マークルツリーの以前のブロック内のproof of stateを、 -とても複雑で再帰的な"Ethereum内、Ethereumライトクライアント"の構造を必要とすること無く -確かめる事が出来るようにするためにある。 - -* **EXTCODESIZE** , **EXTCODECOPY**: 第一義的な使い方はコントラクトが、他のコントラクトとやり取りを開始する前に、 -他のコントラクトのコードがテンプレートの定義に反していないかをチェックするか、 -模倣していないかさえもチェックする事が出来るようにするためにある。 -下記に使い方がある。http://lesswrong.com/lw/aq9/decision_theories_a_less_wrong_primer/  (アプリケーション用) - -* **JUMPDEST**: jumpの行き先が制限されており、幾つかのインデックスに制限されていたときに、 -JITでコンパイルされた仮想マシーンがより一層簡単に実装でき、 -様々な行き先でのコンピュテーションの複雑さがおおまかにO(log(正しいjumpの行き先の数))、だが -固定的なjumpは常に定数時間を要する。) -それ故に、我々は -(i)正当に認証された変数のjumpの行き先に対しての制約 -(ii)動的なjumpに対して静的なjumpを使うことのインセンティブ -2つのゴールを満たすためには、我々は(i)直ぐにプッシュによって先行されるjumpは他のjumpにのみjumpすることが出来る。 -(ii)他のjumpはJUMPDESTにのみjumpを行う事が出来る。 -jumpに対してのjumpを制限することは、jumpは動的なのか静的なのかという質問がただコード内の以前のオペレーションを見るだけで判別することが出来るようになる。 -プッシュデータに対してのjumpを禁じることはJITの仮想マシーンのコンパイルと実行を早める事にも繋がる。 -LOG: LOGはイベントをログするためにある、上記のtrieの使い方のセクションを参照 -* **CALLCODE**: -目的はコントラクトが他のコントラクトに保存されているコード形式となっているfunctionsを呼び出すことが出来るようにし、 -スタックとメモリーが分割されているが、コントラクトを自分のストレージ内で使うこと。 -これはスケール出来るような形で"標準的ライブラリー"のコードをブロックチェーン上に実装することをかなり容易にしている。 -* **SUICIDE**: もしもう必要無いのであればmこのopcodeはコントラクトがすぐに自分自身を消去する。 -最後に実行されるトランザクションにてSUICIDEは実行されるが、すぐに実行されるわけではない、 -なぜならば、既に実行されたsuicide(自殺)を差し戻すことが出来るようにするということは -キャッシュの複雑さを著しく増大させ、仮想マシーンの効率的な実装において大変な困難が強いられるという事実があるためだ。 -* **PC**: 全てのPCのopcodeのインスタンスは、そのインデックスにある実際のプログラムカウンターにpushとして挿入されているため、 -理論的には必ずしも必要ではないが、コード中でPCを使うことに依って、位置に依存しないコードを作る事が出来る。 -(例えば、コピー/ペーストされて他のコントラクトに入ってしまい、コンパイルされた関数が、 -異なるインデックスになってしまっても、プログラムを破壊しない) \ No newline at end of file diff --git a/pages/other-languages/[japanese]-patricia-tree.md b/pages/other-languages/[japanese]-patricia-tree.md deleted file mode 100644 index d9a9e3450..000000000 --- a/pages/other-languages/[japanese]-patricia-tree.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -name: Patricia Tree -category: ---- - -### Merkle Patricia Tree の仕様 - -Merkle Patricia treeは、(キー、値)のすべての結合を保存することのできる、暗号学的な認証データ構造を与えるが, この資料の視点として、キーと値は文字列に制限する(この制限を解除するには、他のデータ種に対し直列化方式を用いるだけでよい)。 これらは、完全に決定的で、つまり、 同じ(キー、値)の結合は全く同じバイト末に至ることを保証し、故に同じroot hashを持ち、挿入、検索、削除にO(log(n))の効率の聖杯を与え, red-block treeのような、もっと複雑な比較ベースの代替よりずっと簡単に理解できる。 - -### 序文: 基本的なRadix Trees - -基本的なradix tree(基数木)では、すべてのノードは、次のようである: - - [ value, i0, i1 ... in] - -i0 ... は、アルファベットの(しばしばバイナリか16進での)シンボルを表現する。 valueは、ノードの終端の値で, i0 ... の値はNULLか、他のノードへのポインタ(我々のケースでは、ハッシュ値)である。 この形式は、基本的な(キー、値)の保存である; 例えば、もしtree中で現在dogにマッピングされている値に興味があるなら、まずdogをアルファベット(もし16進を使うなら646f67となる)に変換し、そのパスを、終わりになるまでずっと降りて行き、値を読む。すなわち、根のノードを得るために、まずキー/値の記録の根のハッシュを調べる, そして1レベル下のノードを得るために、根のノード6を調べる, そして、そのノード4を調べる, そして、そのノード6を調べる, などなど,根 -> 6 -> 4 -> 6 -> f -> 6 -> 7のパスを一度たどるまで行い, 得たノードの値を調べ、その値を返す。 - -radix treeの更新と削除は、簡単で、大まかには次のように定義される: - - def update(node,key,value): - if key == '': - curnode = db.get(node) if node else [ NULL ] * 17 - newnode = curnode.copy() - newnode['value'] = value - else: - curnode = db.get(node) if node else [ NULL ] * 17 - newnode = curnode.copy() - newindex = update(curnode[key[0]],key[1:],value) - newnode[key[0]] = newindex - db.put(hash(newnode),newnode) - return hash(newnode) - - def delete(node,key): - if key == '' or node is NULL: - return NULL - else: - curnode = db.get(node) - newnode = curnode.copy() - newindex = delete(curnode[key[0]],key[1:]) - newnode[key[0]] = newindex - if len(filter(x -> x is not NULL, newnode)) == 0: - return NULL - else: - db.put(hash(newnode),newnode) - return hash(newnode) - -radix treeの"Merkle"部分は、C(訳注:C言語)で、伝統的にtreeの実装で起こるであろう、32ビットや64ビットのメモリの場所ではなく、ノードの決定的な暗号学的ハッシュがノードのポインタとして使われることに起因している 。このことで、データ構造への暗号学的な認証の方法が得られる; もし、与えられたtrieの根のハッシュが公に知られれば、(訳注:(キー・値)ノードから、根までの?)道の各ステップを上がっていくノードを提供することによりtrieが特定のキーに、与えられた値をもつことを、証明することがだれでも可能である。根のハッシュは、その下のすべてのハッシュに究極的には基づいており、故に、どのような変更でも、根のハッシュが変わるので、攻撃者が存在しない(キー、値)の対の証明を与えることは不可能である。 - -しかし、radix treesには、重要な制限がある: 効率性である。 もし、キーが数百文字の長さのたった1つの(キー、値)の結合を保存する場合, 1文字1レベルを保存するのに別の1キロバイト以上のスペースが必要となる, そして、それぞれの検索と削除は、数百ステップとなる。Patricia treeはこの問題を解決するために導入された。 - -### 仕様: 終端オプションありの16進Compact encoding - -16進文字列の伝統的なエンコード方法は、バイナリに変換することである - つまり、0f1248のような文字列は、[15, 18, 72] の3バイトである。しかし、この方法は1つの小さな問題がある: 16進文字列の長さが奇数だったら? このケースでは、0f1248とf1248を区別する方法がない。 加え、 Merkle Patricia treeの我々の適用では、16進文字列が終わりに特別な "終端記号"('T'と表示される)をもつ16進文字列という、追加の特徴が必要である。 終端記号は、1度のみ、唯一最後に発生しうる。このことを考える上での代替の手段は、終端器号があることを考えず、その代わり、 終端器号の存在を示すビットを、与えられたノードが最終のノード、ここでの値は、他のノードのハッシュではなく、本当の値である、をエンコードしたことを示すビットとして扱うことである, - -これら問題を解決するため、 最後のバイトストリームの最初のニブル(4ビット)に対し、長さ('T'記号は無視)が奇数かどうかを示すものと、 終端の状態の、2つのフラグをエンコードする; それらは、それぞれ、最初のニブルの2つの最下位ビットに置かれる。 偶数の長さの16進文字列であれば, 16進文字列の長さが偶数であり、それ故バイトの全数が表現可能であることを保証するため、2番めのニブル(値はゼロ)を導入しなければならない。故に、次のエンコーディングを構築する: - - def compact_encode(hexarray): - term = 1 if hexarray[-1] == 16 else 0 - if term: hexarray = hexarray[:-1] - oddlen = len(hexarray) % 2 - flags = 2 * term + oddlen - if oddlen: - hexarray = [flags] + hexarray - else: - hexarray = [flags] + [0] + hexarray - // hexarrayは最初のニブルがフラグとなった偶数の長さとなっている。 - o = '' - for i in range(0,len(hexarray),2): - o += chr(16 * hexarray[i] + hexarray[i+1]) - return o - -例: - - > [ 1, 2, 3, 4, 5 ] - '\x11\x23\x45' - > [ 0, 1, 2, 3, 4, 5 ] - '\x00\x01\x23\x45' - > [ 0, 15, 1, 12, 11, 8, T ] - '\x20\x0f\x1c\xb8' - > [ 15, 1, 12, 11, 8, T ] - '\x3f\x1c\xb8' - -### メイン仕様: Merkle Patricia Tree - -Merkle Patricia tree は、データ構造にいくつかの特別な複雑さを加えることにより、非効率な問題を解決する。Merkle Patricia treeのノードは、次のうちの1つである: - -1. NULL (空文字を表現する) -2. 2項目の配列 [ キー,値 ] -3. 17項目の配列 [ v0 ... v15, vt ] - -このアイデアは、ただ1つの要素をもつ長いノードのパスが発生した場合、[キー、値]ノードを作ることで下降をショートカットすることである、ここで、キーは上で述べたcompact encodingされた、下降する16進のパスを与え、値は、標準のradix treeのようにただのノードのハッシュである。また、もうひとつ概念の変更を加える: 内部ノードは、もう値をもてない、ただ子を持たない葉のみが、値をもつことができる; しかし、完全に一般的に、キー/値の保存を'dog' と 'doge' を同時に保存できるようにしたいので、単純に終端器号(16)をアルファベットに追加する、そうすることで決してある値が別の値に"立ち寄る"ことがない。 ノードがノード内で参照される場合、もしlen(x) >= 32なら、H(rlp.encode(x)) ここで、H(x) = sha3(x) 、さもなければ xが含まれる 、そしてrlp.encode は [RLP](https://github.com/ethereum/wiki/wiki/%5BJapanese%5D-RLP) エンコード関数である。trieを更新する際,長さ>=32のノードを作成する際、永続的なルックアップテーブルにキー/値のペア (sha3(x), x) を保存せねばならない、しかし、もしノードがそれより短ければ、関数f(x) = xが可逆であるという明らかな理由により、何も保存する必要はない。 - -ここで、2項目配列 `[ key, v ]`, `v` は、値またはサブノードでありうる、を考える。 -* もし `v` が値なら、キーは終端を**含む**ニブルのリストの compact encodingの結果でなければならない。 -* もし `v` がサブノードなら、キーは終端を**含まない**ニブルのリストの compact encodingの結果でなければならない。 - -17項目配列` [ v0 ... v15, vt ]`では, `v0...v15`のそれぞれのアイテムは常にサブノードまたはブランクであり, vtは、常に値かブランクである。故に、`v0...v15`の1アイテムに値を記録する代わりに、(キー、値)のサブノードを保存する、ここでキーは、終端を**含んだ**空のニブルのリストをcompact encodingした結果である。 - -これが、 Merkle Patricia tree中のノードを取得するための、拡張したコードである: - - def get_helper(node,key): - if key == []: return node - if node = '': return '' - curnode = rlp.decode(node if len(node) < 32 else db.get(node)) - if len(curnode) == 2: - (k2, v2) = curnode - k2 = compact_decode(k2) - if k2 == key[:len(k2)]: - return get(v2, key[len(k2):]) - else: - return '' - elif len(curnode) == 17: - return get_helper(curnode[key[0]],key[1:]) - - def get(node,key): - key2 = [] - for i in range(len(key)): - key2.push(int(ord(key) / 16)) - key2.push(ord(key) % 16) - key2.push(16) - return get_helper(node,key2) - -例: ペア('dog', 'puppy'), ('horse', 'stallion'), ('do', 'verb'), ('doge', 'coin')を含むtreeを持つことを想定する。まず、キーを16進形式へ変換する: - - [ 6, 4, 6, 15, 16 ] : 'verb' - [ 6, 4, 6, 15, 6, 7, 16 ] : 'puppy' - [ 6, 4, 6, 15, 6, 7, 6, 5, 16 ] : 'coin' - [ 6, 8, 6, 15, 7, 2, 7, 3, 6, 5, 16 ] : 'stallion' - -そして、treeを構築する: - - ROOT: [ '\x16', A ] - A: [ '', '', '', '', B, '', '', '', C, '', '', '', '', '', '', '', '' ] - B: [ '\x00\x6f', D ] - D: [ '', '', '', '', '', '', E, '', '', '', '', '', '', '', '', '', 'verb' ] - E: [ '\x17', F ] - F: [ '', '', '', '', '', '', G, '', '', '', '', '', '', '', '', '', 'puppy' ] - G: [ '\x35', 'coin' ] - C: [ '\x20\x6f\x72\x73\x65', 'stallion' ] diff --git a/pages/other-languages/[japanese]-rlp.md b/pages/other-languages/[japanese]-rlp.md deleted file mode 100644 index c5bc9f400..000000000 --- a/pages/other-languages/[japanese]-rlp.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -name: RLP -category: ---- - -RLPの目的は任意のネストされたバイナリデータをエンコードすることです。RLPはEthereumにおいてシリアライズされたオブジェクトをエンコードするメインの方法です。RLPの目的は構造をエンコードすることです:特殊なアトミックなデータ型(例えば文字列型、整数型、浮動小数点型)のエンコードはもっと上位のプロトコルに任せます;Ethereumでは整数型は先頭のゼロが無いビッグエンディアンのバイナリで表されます(よって、整数型のゼロは空のバイトアレイとなります)。 - -もし辞書をエンコードするのにRLPを使いたいと思うならば、二つの正規のフォームが使えます。`[[k1,v1],[k2,v2]...]`のような辞書順にならんだキーを使用する方法と、Ethereumで使用されている上位の[Patricia Tree](https://github.com/ethereum/wiki/wiki/Patricia-Tree)を用いたエンコードを使用する方法です。 - - -### 定義 - -RLPエンコード関数はアイテムを受け入れます。アイテムは以下のように定義されます: - -* 文字列型(すなわちバイトアレイ)はアイテムである -* アイテムのリストはアイテムである - -例えば、空の文字列はアイテムです。同様に "cat"という単語による文字列もアイテムです。任意の個数の文字列型のリストもアイテムです。そして、`["cat",["puppy","cow"],"horse",[[]],"pig",[""],"sheep"]`のようなもっと複雑なデータ構造もアイテムです。この論説の残りの部分の文脈において、"文字列型"は"あるバイト数のバイナリデータ"と同義語であることに注意しましょう; 特殊なエンコードは用いられておらず、文字列型の内容が何を意味しているかの知識は必要ではありません。 - -RLPエンコーディングは以下のように定義されます: - -* `[0x00, 0x7f]`の間にある1バイトの値は、そのバイトがそのまま自分自身のRLPエンコーディングとなります。 -* もし、文字列が0-55バイトの長さの場合は、RLPエンコーディングは**0x80**と文字列の長さを足した1バイトと、その後に続く文字列で構成されます。よって、最初の1バイトは`[0x80, 0xb7]`の範囲となります。 -* もし文字列が55バイトより長い場合、RLPエンコーディングは以下の3つで構成されます。文字列の長さをバイナリで表した時に必要となるバイト数を**0xb7**に足した値の1バイト。続けて、文字列の長さ、それに続く文字列です。例えば1024の長さを持つ文字列の場合、`\xb9\x04\x00`と、その後に続く文字列にエンコードされます。よって、最初の1バイトは`[0xb8, 0xbf]`の範囲となります。 -* もし、リストの全ペイロード(すなわち、全てのアイテムを合わせた長さ)が0-55バイトの長さである場合、RLPエンコーディングは、**0xc0**にリストの長さを足した1倍との値と、それに続くアイテムをRLPエンコーディングして続けたもので構成されます。よって、最初の1バイトの範囲は`[0xc0, 0xf7]`となります。 -* もし、リストの全ペイロードの長さが55バイト以上の場合、RLPエンコーディングは以下の構成になります。最初に **0xf7** にペイロードの長さをバイナリで表した時に必要となるバイト数を足した1バイト。続けて、ペイロードの長さ。最後にアイテムをRLPエンコーディングした物を続けたものとなります。よって、最初の1バイトの範囲は`[0xf8, 0xff]`となります。 - - -コードで表すと以下のようになります: - -```python -def rlp_encode(input): - if isinstance(input,str): - if len(input) == 1 and chr(input) < 128: return input - else: return encode_length(len(input),128) + input - elif isinstance(input,list): - output = '' - for item in input: output += rlp_encode(item) - return encode_length(len(output),192) + output - -def encode_length(L,offset): - if L < 56: - return chr(L + offset) - elif L < 256**8: - BL = to_binary(L) - return chr(len(BL) + offset + 55) + BL - else: - raise Exception("input too long") - -def to_binary(x): - return '' if x == 0 else to_binary(int(x / 256)) + chr(x % 256) -``` - -### 例 - -文字列 "dog" = [ 0x83, 'd', 'o', 'g' ] - -リスト [ "cat", "dog" ] = `[ 0xc8, 0x83, 'c', 'a', 't', 0x83, 'd', 'o', 'g' ]` - -空文字列 ('null') = `[ 0x80 ]` - -空リスト = `[ 0xc0 ]` - -整数 15 ('\x0f') のエンコード = `[ 0x0f ]` - -整数 1024 ('\x04\x00') のエンコード = `[ 0x82, 0x04, 0x00 ]` - -[ 集合論的表現 ](http://en.wikipedia.org/wiki/Set-theoretic_definition_of_natural_numbers) `[ [], [[]], [ [], [[]] ] ] = [ 0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc1, 0xc0 ]` - -文字列 "Lorem ipsum dolor sit amet, consectetur adipisicing elit" = `[ 0xb8, 0x38, 'L', 'o', 'r', 'e', 'm', ' ', ... , 'e', 'l', 'i', 't' ]` \ No newline at end of file diff --git a/pages/other-languages/[japanese]-white-paper.md b/pages/other-languages/[japanese]-white-paper.md deleted file mode 100644 index 82945709d..000000000 --- a/pages/other-languages/[japanese]-white-paper.md +++ /dev/null @@ -1,1315 +0,0 @@ ---- -name: White Paper -category: ---- - -# Ethereum 白書 - -### 次世代 Smart contract と 分散型アプリケーション基盤 - -ナカモトサトシの論文により、2009年に開発された Bitcoin は通貨・貨幣における革新的な発明だと -謳われ、金兌換のような後ろ盾がなく、中央通貨管理局をもたないはじめての デジタル財産 の例です。( [intrinsic value](http://bitcoinmagazine.com/8640/an-exploration-of-intrinsic-value-what-it-is-why-bitcoin-doesnt-have-it-and-why-bitcoin-does-have-it/) ) しかし、その壮大な Bitcoin の実験における、より特筆すべき重要部は別の所にあります。 -それは分散型大衆決定のツールとして、まさにその基礎をなす Blockchain の技術であり、急速に人々の注目を集めつつあります。 - -一般的に、 -blockchain テクノロジーを引用している Bitcoin の代替アプリで、 -blockchain 上の電子財産を実装したものとして: - -* 一定取引量のある通貨や金融商品をあらわすもの([ colored coins ](https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit)) -* 基礎となる物理デバイスの所有権 ([ smart property ](https://en.bitcoin.it/wiki/Smart_Property)) -* ドメインのような投資対象外の財産 ([ Namecoin ](http://namecoin.org)) - -があり、より複雑なアプリケーションとしては以下のものが挙げられます: - -* ( 役人や銀行員に取って代わり、)コーディングであらゆるルールを実装し、個々の電子資産を管理するもの([ smart contracts ](http://szabo.best.vwh.net/smart_contracts_idea.html)) -* 上記のスマートコントラクトを blockchain 上で実装したもの ([ DAO ](http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/)) - -Ethereum が提供しようとしているものは、チューリング完全なプログラミング言語の完成品を - blockchain に埋め込み提供することにあります。 -この言語は、"contract" を生成するために使用され、 -"contract" とはあらゆる 関数 をプログラムしたものです。 -これにより、ユーザーは上記の全てのシステムを実装することが可能で、 -われわれがまだ想像すらしていない多くの可能性が、 -論理を秘めし数行のコードを書き上げるだけで実現できるようになります。 - - -### 目次 - -* [歴史](#歴史) - * [状態遷移システム としての Bitcoin](#状態遷移システム-としての-bitcoin) - * [採掘](#採掘) - * [マークル木](#マークル木) - * [Blockchain を用いた代替アプリケーション](#blockchain-を用いた代替アプリケーション) - * [スクリプト言語による記述](#スクリプト言語による記述) -* [Ethereum](#ethereum) - * [Ethereum アカウント](#ethereum-アカウント) - * [メッセージ と トランザクション](#メッセージ-と-トランザクション) - * [Ethereum の 状態遷移関数](#ethereum-の-状態遷移関数) - * [コード実行](#コード実行) - * [Blockchain と 採掘](#blockchain-と-採掘) -* [アプリケーション](#アプリケーション) - * [証明書発行のシステム](#証明書発行のシステム) - * [金融ディリバティブ と 安定価格通貨](#金融ディリバティブ-と-安定価格通貨) - * [Identity と Reputation のシステム](#identity-と-reputation-のシステム) - * [分散型ファイルストレージ](#分散型ファイルストレージ) - * [分散型自律組織](#分散型自律組織) - * [その他のアプリケーション](#その他のアプリケーション) -* [雑録 と 関心事](#雑録-と-関心事) - * [GHOST の修正実装](#ghost-の修正実装) - * [手数料](#手数料) - * [計算 と チューリング完全](#計算-と-チューリング完全) - * [通貨 と 発行](#通貨-と-発行) - * [マイニング集中](#マイニング集中) - * [スケーラビリティ](#スケーラビリティ) -* [結論](#結論) -* [脚注 及び 参考文献](#脚注-及び-参考文献) - -## Bitcoin への導入 と 既存の概念 - -### 歴史 - - -上述した資産登録マシンのような代替アプリや、 -分散型デジタル通貨の概念が現れ始めたのは、ここ数十年です。 -80〜90年代にかけて、David Chaum の「ブラインディング署名 blinding sgnature」をよりどころとした -匿名のデジタル通貨プロトコルがたくさん開発され、高いプライバシーをもつ通貨を提供しましたが、 -これらは中央集約型の媒体に依存していたため、広く注目を浴びるには至りませんでした。 -1998年に発表された、Wei Daiによる [b-money](http://www.weidai.com/bmoney.txt) が、 -現行の分散型のコンセンサスと同様の、計算問題を解くことによって -お金を創造するというアイデアを、はじめて導入した事例となります。 -しかし、このプロポーザルの詳細は不十分であったため、実用的な分散型の大衆意思決定を実装することができませんでした。 -2005年、Hal Finney が、暗号通貨のコンセプトをつくりあげるために、 -ABCD Hashcash パズル[jp-1] と b-money からアイデアをしぼり作られたシステムである "[reusable proofs of work](http://www.finney.org/~hal/rpow/)" というコンセプトを発表しましたが、バックエンドに、信用のある計算機を使用しなければならなかったため、真に分散型とは呼べず、再び失敗しました。 -2009年のナカモトサトシによる実用的な実装がはじめての分散型の通貨となりました。 -これは、昔からあった「公開鍵暗号(所有権を管理) 」と -大衆意思決定アルゴリズムである「 "proof of work" (誰がコインを所有しているのか追跡)」 -を結びあわせたものとなります。 - - -proof of work の背景にある技術は宇宙史に名を刻むほどの飛躍的進歩でありました。 -なぜなら proof of work は、同時に二つの難題を解決したのです。 - -* ひとつめは、単純明快で適切な影響力をもつ大衆意思決定のアルゴリズムの提供で、 -ネットワーク上のノードはBitcoinの帳簿の「一般規則に従う状態更新」ができるようになりました。 -* ふたつめは、大衆意思決定のプロセスへの自由参加を可能にするメカニズムの提供で、 -誰が、コンセンサスに影響をもたらすのかということを決める政治的問題を解決したのです。 - -これは次のようにして、参加基準を定式化したということです。 - -1. ノードに対し、特定リストにおける唯一性の証明書の提出を要求し、 -2. さらに「大衆意思決定のプロセスにおける単位ノードの重みは、ノードのもつ計算能力に応じて分配する」 -という エコノミックバリア[jp-2] を採用する - - - -### 状態遷移システム としての Bitcoin - -![statetransition.png](http://vitalik.ca/files/statetransition.png?2) - -技術的観点から見て、Bitcoin をはじめとした暗号通貨の帳簿は、全 bitcoin の所有状況をあらわす「状態」と、状態と取引(トランザクション、状態遷移関数のこと)から新たな状態を出力する「状態遷移関数」をもった、「状態遷移」のシステムと見てとれます。 -一般的銀行のシステムでは、たとえば「状態」はバランスシートにあたり、 -「トランザクション」はAからBにXドル移動してくれ、というリクエストにあたり、 -この状態遷移関数は、XドルだけAの口座の残高を減らし、Bの残高を増やします。 -もし、Aの口座の残高がXドルに満たなかった場合には、 -状態遷移関数はエラーを返します。 -このようして、定式化をすると - - APPLY(S,TX) -> S' or ERROR - -この銀行システムは以上で定義され、以下は適用例です。 - - APPLY({ Alice: $50, Bob: $50 },"send $20 from Alice to Bob") = { Alice: $30, Bob: $70 } - - APPLY({ Alice: $50, Bob: $50 },"send $70 from Alice to Bob") = ERROR - - -Bitcoin における「状態 state」とは、全コインの集合 であり、 -技術的に説明いたしますと、 -発行されているコインのうちで「UTXO(未使用の取引出力値)」の全集合 となり、各 UTXO には、それぞれ「残高」と「所有者」が記録されています。 -「所有者」は、基本的に、暗号理論における公開鍵[1]である20バイト(160bit)のアドレスとなります。 -「トランザクション」は、状態遷移関数であり、一以上の入力値 と 一以上の出力値 をとります。 -各入力値は、「既存の UTXO への参照」と「所有者のアドレスと関連付けられた秘密鍵による暗号署名」 から構成され、 -各出力値は、「新しく生成された UTXO」を保持しています。 - -状態遷移関数 `APPLY(S,TX) -> S'` を定義するプログラムの概略は以下となります。: - -1. For each input in `TX`: - * If the referenced UTXO is not in `S`, return an error. - * If the provided signature does not match the owner of the UTXO, return an error. -2. If the sum of the denominations of all input UTXO is less than the sum of the denominations of all output UTXO, return an error. -3. Return `S` with all input UTXO removed and all output UTXO added. - -ひとつめのステップにおける -前半部により、トランザクションの送信者が、存在しないコインを不正に送ることを防止し、 -後半部により、トランザクションの送信者が、他人のコインを勝手に送ることを防止します。 -ふたつめのステップによって、トータルバリューの保存(入力値の総計 が 出力値の総計 と等しい)が執行されます。 -これを実用的な支払いに適用するための、プロトコルは以下のようになります。 - -アリスがボブに 11.7BTC を送信したいとします。 -まずはじめに、アリスは、利用可能な UTXO を自分の持っているものの中からかき集め、 -少なくとも総計11.7BTCになるようにします。アリスの UTXO を集めてちょうど11.7BTCをつくることはできず、6+4+2=12 BTC がアリスの得る最小の値です。 -そして彼女は、3つの入力値と2つの出力値をもつトランザクションをつくります。 -ひとつめの出力値は11.7BTCでボブのアドレスが所有者として記録され、 -ふたつめの出力値は0.3BTCの"お釣り"がアリス自身を所有者として記録されます。 - - - -### 採掘 - -![block_picture.jpg](http://vitalik.ca/files/block_picture.png) - -もし、アクセス対象として信用取引可能な 中央集約型 のサービスを使っているのであれば、 -このシステムの実装は至極簡単なものであったでしょう。 -単に上記のプログラムコードを記すのに、中央サーバーのハードディスクを使用し、「状態」を記録・維持すれば済む話であったでしょう。 -しかし、わたしたちが Bitcoin を用いてやろうとしているのは、分散型通貨システムの構築です。 -なので、トランザクションの順番をみんなが合意できることを確約するために、 -状態遷移システム と 大衆意思決定のシステム をくっつけてやらなくてはなりません。 -Bitcoin の分散型大衆決定プロセスでは、「ブロック」と呼ばれる「トランザクションを梱包したもの」を作り続けようとする、 -ネットワーク上のノードが必要です。 -ネットワークは、だいたい10分毎にひとつの ブロック を生成するように設計されており、 -各々のブロックは、 - -* 「タイムスタンプ」 -* 「ノンス」 -* 「直前のブロックへの参照値」 -* 「(直前のブロック生成後から現在までに遂行された)トランザクションのリスト」 - -を保持します。( ※ ノンス:ブロック生成時にインクリメントされ続ける個体識別ハッシュ値で、マイナーがブロックを掘り当てることを目標にして独自にインクリメントする。) -このブロックが時間発展することによって、 -Bitcoin の帳簿を最新状態に更新し続ける、 -永続的かつ恒久的成長をなす " blockchain " (ブロックの鎖)を生成します。 - - -現パラダイム下において、ブロックが有効かどうかをチェックするアルゴリズムは以下となります: - -1. Check if the previous block referenced by the block exists and is valid. -2. Check that the timestamp of the block is greater than that of the previous block[2] and less than 2 hours into the future -3. Check that the proof of work on the block is valid. -4. Let `S[0]` be the state at the end of the previous block. -5. Suppose `TX` is the block's transaction list with `n` transactions. For all `i` in `0...n-1`, set `S[i+1] = APPLY(S[i],TX[i])` If any application returns an error, exit and return false. -6. Return true, and register `S[n]` as the state at the end of this block. - -基本的に -ブロック内の各トランザクションは、 -トランザクション執行前の 過去の状態 をもとにして、有効な状態遷移を提供しなければなりません。 -「状態」はいかなる点においても、ブロック内に記述されないことに注意してください。(ブロックは状態遷移関数をつなげ合わせた関数そのものであり、入力値 である「状態」については何も書かれていません); -(このアルゴリズムは、「検証ノード」を説明する簡単な抽象例であり、 -どのブロックの検証においても、開始状態から、全ブロックの全トランザクションを順番に適用することによって、目的となるブロックの示す状態を計算すれば十分となります。) -さらに「採掘者 miner」がトランザクションをブロックに取り込む順番がとても重要だということに注意してください。 -(もし、A、Bという二つのトランザクションがあって、BはAの生成した UTXO(未使用出力値) を使う場合において、 -AのあとにBがきているブロックは有効ですが、そうでない場合は無効となってしまいます。) - - -他のシステムでは見受けられない仕様として、 -上述のトランザクションリストにおいて「一有効性条件」(有効なものを一つ選ぶための条件)が - "proof of work" には必要となります。 -厳密な定義は、 -全てのブロックの double-SHA256 hash値(256bit の数値)が -動的に変化するように設計された「目的値 target」より小さくなること、であり、 -目的値は、これを執筆している当時では、約2187でした。 -これは、ブロック生成を計算科学上 "難しく" する為であり、 -その結果、Sybil Attack(ひとりでノードを多数生成し多数決的に攻撃する手法)による攻撃者が自身の好きなように 全 blockchain を改竄してしまうことを防止いたします。 -SHA256(エスエイチエーにごろ)は、完全に予測不可能な擬似乱数関数として設計されており、 -有効なブロックをつくる唯一の方法は、単に ノンス をインクリメントしてはその新しい hash値 が適合するかを確かめるという、試行錯誤を繰り返すしかありません。 - - - -現在における~2187の「目的値」では、 -ネットワークは~269 回の試行錯誤をしてやっとブロックを見つけることができます。 -ふつう、目的値 は、ネットワーク上で2016ブロック生成される毎に再設定され、 -ネットワーク上にあるノードによるブロックの発掘が平均して10分毎に生じるよう調整されます。 -採掘者に競わせてこの計算をさせるための設定として、 -ブロックを採掘したものは、どこからともなく湧いた自分への25BTCの報酬を、 -トランザクションとして最後に付け加えます。 -さらに、 -全入力値が全出力値よりも大きいような全てのトランザクションにおける、 -その差額は「取引手数料 transaction fee」として、採掘者のもとへ行く仕組みです。 -ところで、これはBitcoinが発行される唯一のメカニズムとなります。 -つまり、初期状態においては、Bitcoin は皆無であったわけです。 - - - -マイニングの目的をより深く理解するために、 -悪意ある攻撃者のおこす事件によって何がおこるのかを見ていきましょう。 -Bitcoin の基礎となる暗号理論はセキュリティの高いものと知られているので、 -攻撃者の狙い目としては、直接、暗号理論で守られていない部分 : トランザクションの順序 となるでしょう。 - -攻撃者の戦略は簡単なものです: - -1. ある商売人に 100 BTC をある商品の購入代金として送る (瞬間的な発送ができるデジタル商品が好まれます) -2. 商品の到着を待つ -3. 自分自身に 100 BTC を送る別のトランザクションを生成する -4. ネットワークが、後に作った方のトランザクションの順番が最初にくるようなブロックを、承認するように試みる - -一度、ステップ 1 が履行されると -数分後に採掘者がトランザクションをブロックに含めます。 -ブロック番号は 270000 とします。 -一時間後、5個以上のブロックが、そのブロックの後ろに追加され、 -この5つのブロックが、間接的にそのトランザクションを参照しているため、 -トランザクションは「承認 confirming」されたということになります。 -この時点で、 -商売人は、支払いが確定したものとみなし、商品を発送します。 -ここではデジタル商品を考え、商品がすぐに届くこととします。 -さていま、攻撃者が、別のトランザクションを作成し、自分宛に 100BTC を送るものとします。 -攻撃者が、もし単にそれを野に放っただけならば、 -そのトランザクションは受理されないでしょう。 -法の番人である採掘者は、`APPLY(S,TX)` を実行するとき、`TX` が、使用済みUTXO を使用しようとしていることに気づくでしょう。 -なので代わりに、 -攻撃者はブロックチェーンを分岐させ、 -親として同じ 269999 番目のブロックを参照する 270000 番目の新しいバージョンのブロックを生成します。 -ここでは、もとのブロックに含まれていたトランザクションは含まれず、新しいトランザクションが追加されていくこととなります。 -ブロックのデータの中身が違うので、 -攻撃者は proof of work をやり直す必要があります。 -さらに、攻撃者の新しいブロック 270000 では、異なるハッシュ値を生成するので、 -もとのブロックチェーン上のブロック 270001 ~ 270005 は、このブロックを参照しません。 -このように、もとのブロックチェーンと攻撃者のチェーンは完全に分断されるのです。 -このとき適用されるルールは次のようになります。 -ブロックチェーンの分岐時は、 -一番長いブロックチェーンが "信用" あるものとして選択されます。 -なので、攻撃者が新しい 270000 のブロックチェーン上で採掘し続ける傍で、 -このシステムの法の番人である採掘者達はもとの 270005 のブロックチェーンを採掘し続けることになります。 -攻撃者が、自分のブロックチェーンを最長にするためには、 -ネットワーク上の残りのすべてのノードの総和より、高い計算能力を誇る必要があり、 -これを「51%攻撃」と呼びます。 - - - - - - - - -### マークル木 - -![SPV in bitcoin](https://raw.githubusercontent.com/ethereum/www/master-postsale/src/extras/gh_wiki/spv_bitcoin.png) - - -_革新  :   -分岐の正当性の証明には、少しのノードを与えてやるだけでよい_ - -_伝統  :   -どの部分にいかなる変化を付与しても、鎖の上方で必ず不一致を生む_ - - - - - -Bitcoin の重要なスケーラビリティ特性は「ブロックは多層データ構造で保管される」ということです。 -ブロックの「ハッシュ値」とは実は、ブロックヘッダ(先頭部)のハッシュ値 に過ぎず、これは約 200 byte のデータであり、 - -* タイムスタンプ -* ノンス -* 直前のブロックの ハッシュ値 -* マークル木(ブロック内の全トランザクションを保持するデータ構造)の ルート(根の元となる部分)の ハッシュ値 - -を保持します。マークル木は、バイナリ木のひとつで、以下の三つから構成されます。 - -* 基礎データを保持する木構造の最下層の「葉(リーフノード)」の集合 -* 二つの 子ノード のハッシュ値である「枝(中間ノード)」の集合 -* 唯一の「根(ルートノード)」(二つの子ノードのハッシュ値で "頂上" にくるもの) - -マークル木は、ブロック中のデータをバラバラに運搬するためにつくられました。 -ノードは、ひとつのソース(ネットワーク上の自身とは別のノード)からブロックヘッダだけを、 -別のソースから、必要なトランザクションに関連する小さな部分木を、ダウンロードすることができ、それでもなお全データの整合性を保証できるのです。 -これがうまく動作する所以は、ハッシュ値が上に伝播していくところ です。: -もし悪意のあるユーザーが偽物のトランザクションをマークル木の底のノードと取り替えようとすると、この変化はその親のノードを変化させ、繰り返し伝播することで最終的にルートの値を変化させます。 -つまり、ブロックのハッシュ値が変化し、マークル木のプロトコルにより、結果として、全く別のブロックとして記録され、このブロックは十中八九 proof of work が無効となります。 - - -マークル木のプロトコルは、言うまでもなく長期にわたるアプリケーションの維持のために必要です。 -Bitcoin ネットワークにおける「完全ノード、フルノード」とは、「全ブロックの全トランザクションを保管・処理するノード」のことで、 -2014年4月の時点で 15GB の容量をとり、ひと月あたり1GB以上の速さで増え続けています。 -現在、これはデスクトップコンピュータ上で目視できますが、携帯電話では確認できません。 -容量的な観点から、後々の未来、完全ノード に参加できるのは、ビジネスや趣味の範疇に限られてくるでしょう。 -「SPV (簡素な支払検証)」として知られるプロトコルにより、「完全ノード」とは別タイプのノードが開発されました。 -「軽量ノード、ライトノード」と呼ばれ、このノードは、ブロックヘッダをダウンロードし、ブロックヘッダで proof of work を検証し、そして自身に関係のある トランザクションの「枝、ブランチ」だけをダウンロードします。 -軽量ノードは、セキュリティを強く保ったまま、トランザクション履歴や残高を、状態遷移関数により決定することができるというのに、 -全ブロックチェーンの小さな部分木をダウンロードすればよい、というものなのです。 - - - -### Blockchain を用いた代替アプリケーション - -基礎技術である blockchain の他コンセプトへの応用は、これもまた、長い歴史があります。 -2005 年 Nick Szabo が "[secure property titles with owner authority(自己の権威によるセキュアな財産の獲得)](http://szabo.best.vwh.net/securetitle.html)" というコンセプトを発表しました。この論文は、複製データベースの技術の進歩により、いかにして -blockchain 基調のシステムが、土地所有の登記 の保管を可能にするのかを記述し、 -「開拓 homesteading」「不法占有 adverse possesion」「ジョージの土地課税 Georgian land tax」といったコンセプトを含む枠組みを、苦労して築き上げました。 -しかし、残念ながら、当時利用できる、効果的な複製データシステムがなかったため、プロトコルが実際に実装されることはありませでした。 -とは言うものの、2009 年に Bitcoin の分散型コンセンサス が一度開発されてからは、急速に代替アプリが出現し始めました。 - - -* **Namecoin** - 2010年に作られた [Namecoin](https://namecoin.org/) は「分散型名前登録データベース」と表現されます。 -Tor や Bitcoin , BitMessage のような分散型プロトコルでは、個体識別に アカウント が必要で、そのため他人による干渉が可能ですが、 -どのようにしても利用可能な識別子は、`1LW79wp5ZBqaHW1jL5TCiBCrhQYtHagUWy`のような擬似乱数となります。 -できれば "ジョージ" のような名前をつけることができたらいいな、と考えるでしょう。 -しかしながら、問題なのは "ジョージ" という名前を誰でも、同じプロセスをたどることで登録でき、"ジョージ"として振舞えるのです。 -唯一の解決策は 「fist-to-file パラダイム」を用いることです。 -これは、最初(first)の登録者は登録(file)に成功し、二番目以降では失敗するというものです。 -この問題は Bitcoin の大衆意思決定のプロトコルに完全に合致し、 Namecoin は一早くにこの考えを使って名前登録のシステムを実装し、見事に成功しました。 - -* **Colored coins** - [colored coins](https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit) の目的は、Bitcoin の blockchain 上に「自身で作ったデジタル通貨」や、 -通貨の重要な性質である少額使用の例としてユニットを採用した「デジタルトークン」を、構築できるプロトコルを提供することです。 -colored coins のプロトコルでは、 -特定の Bitcoin UTXO に「色」を設定することで、 -新しい通貨を "発行" します。 -プロトコルは、colered coins を生成するトランザクションの入力値に「色」が付いていれば、他の UTXO も同じ「色」であるものと再帰的に定義します。 -(様々な「色」の入力が混じった場合は、特別なルールが適用されます。) -このことで、ユーザーは特別な色の UTXO だけを保持する財布を維持し、 -ほとんど Bitcoin と同じように周囲に対し送金することが可能で、 -受け取った UTXO の色を特定するには blockchain を遡ります。 - -* **Metacoins** - -metacoins の背景となる思想は「 Bitcoin を土台として、その上で動作するプロトコルをもつ」であり、 -metacoins のトランザクションの保管に、Bitcoin のトランザクションを使用しますが、Bitcoin とは別の 状態遷移関数 `APPLY'` を保持します。 -metacoins のプロトコルは、無効な metacoins トランザクションが Bitcoin blockchain 上にでてくることを防止するために、 -規則「 if `APPLY'(S,TX)` returns an error, -the protocol defaults to `APPLY'(S,TX) = S -」を加えます。 -metacoins は、任意の独自暗号通貨をつくるための 簡単なメカニズム を提供しており、 -Bitcoin 自体のシステム内部においては表面化することのない 先進的な独自機能 を持たせることができます。 -採掘とネットワークのシステムといった複雑な部分がすでに Bitcoin プロトコルによって処理されているので、 -開発コストはとても低く済みます。 -metacoins はいくつかの金融契約や名前登録や分散型両替所を実装するのに使われています。 - - -一般的に言って、大衆意思決定プロトコルを構築する方法は二種類あります。 -「独自のネットワークをつくる方法」と「Bitcoin を土台とする方法」です。 -前者の方法は、namecoin では適度な成功を収めたものの、実装するのが大変です。 -と言いますのは、独自の実装はそれぞれにおいて、独自のブロックチェーンをつくる必要があり、 -同様に、それに必要な状態遷移とネットワークを構成するコードのあらゆるビルド・アンド・テストが必要となります。 -さらに、そうしてできた分散型大衆決定のアプリケーションの数々の集合は、 -採掘(power)と検証(law)の分散を招き、仮にアプリケーションの中では多数派であったとしても、 -規模が小さすぎて自分のブロックチェーンを公正なものとすることができない、といった事態を招きます。 -そして次のことを認識するに至りました。 -大きな種類の分散型アプリがあったとして、とりわけ分散型自動組織では、 -それらはお互いに手を取り合わなければなりません。 - -一方で、「Bitcoin を土台とする方法」では、Bitcoin の SPV 特性 を継承しないという欠陥があります。 -SPV は Bitcoin では動作しますが、それは blockchain におけるブロックの「深さ」が その正当性 を代弁するためです。 -一度、トランザクションの祖先が深いところへ行ってしまえば、 -そのトランザクションは、現在の「状態」を構成する正当な状態遷移関数であると、安心して言うことができます。 -一方、meta プロトコル では、そのコンテクスト内でトランザクションが無効であっても、 -Bitcoin の blockchain において、それが組み込まれることを阻止する方法はありません。 -(Bitcoin のコンテクスト と Meta プロトコル のコンテクストは異なります。) -このように、もし、完全にセキュアな SPV meta プロトコルの実装 が存在したならば、 -あるトランザクションが有効かどうかを判定するために、 -Bitcoin の blockchain の一番最初まで全過程を遡ってスキャンする必要があるでしょう。現在、meta プロトコル の軽量実装は、データを提供する信用機関としてのサーバーに依存しており、 -言うまでもなく、とりわけ暗号通貨の当初の目的の一つが「信用機関の必要性の消去」であるような状況下では、最良の結果であるとは到底言えません。 - - -### スクリプリト言語による記述 - -たとえまったく拡張をせずとも、実は、Bitcoin プロトコルは「 smart contracts 」コンセプトの 機能的に弱いバージョン を簡単に実装したものなのです。 -Bitcoin の UTXO は、「公開鍵」に保持されるだけでなく、 -簡素なスタック・ベース・プログラミング言語で表現される少し複雑な「スクリプト」が、保持することもできます。 -このパラダイムの下で、 -トランザクションが、 -スクリプト保持の UTXO を 入力値 とすれば、 -スクリプトの記述内容を満たすデータが 出力値 となるように、 -トランザクションの記述がされなければなりません。 -さらには、 -基本的な 公開鍵保有メカニズム(その公開鍵を使用したトランザクションがブロック内にあるかどうかを検証するメカニズム) -でさえ、スクリプトを通して実装されています。 -そのスクリプトは、 -ブロック生成の証である 楕円曲線署名 を入力値として受け取り、 -トランザクションとその UTXO を所有するアドレス(公開鍵)に対してその署名を検証し、 -検証が成功すれば 1 を返し、そうでなければ 0 を返します。 -他にも、より複雑なスクリプトが様々な使用場面のために存在します。 -例えば、 -トランザクション検証の際、与えられた三つの鍵の組のうち二つの署名を必要とする スクリプト(マルチシグ multisig)や、 -企業アカウントや、セキュリティの高い口座アカウント、商売におけるエスクローが必要な状況に役立つ 初期設定 を構築することができます。 -スクリプトは、計算問題の答えに対する懸賞金の支払いにおいても使用され、 -「もしあなたがこの額の Dogecoin のトランザクションを送信したという SPV proof を提供できるならば、この Bitcoin はあなたのものだ」といったようなことを記述したスクリプトでさえ構築可能です。 -そして基本的には、分散型のクロス暗号通貨の取引が可能です。 - -しかしながら、Bitcoin に実装されたようなスクリプト言語にはいくつかの重要な制限があります。: - -* **チューリング完全性の欠如** - -つまるところ、Bitcoin スクリプト言語 は計算理論の大部分をサポートしていますが、ほぼ全てという訳ではありません。 -サポートしていない代表的なものとして ループ が挙げられます。 -これは、トランザクションの検証中に無限ループに陥る事を避けるために除外されました。 -理論的には、プログラマにとってはこれは簡単に克服できる障害で、if文と一緒に基本コードを繰り返せば、あらゆるループを模倣できますが、 -スクリプトを記録する(ブロックチェーン上の)スペースを極めて非効率に使用することになります。 -たとえば、楕円曲線署名の代替アルゴリズムをスクリプト上に実装したならば、 -全く同じである掛け算の命令セットが256回個別に記述されてしまいます。 - -* **値が定まらない問題** - -UTXO を保持する スクリプトが、取引量をきめ細やかに管理する方法はありません。 -たとえば、 -もしも、神のみぞ知るような内容の契約の大きな取引だっとしたら、それは価格操作等の生じうるヘッジング契約となってしまうでしょう。 -それは次のような状況です。 -AとBがそれぞれ $1000 相当のBTC をスクリプトに提出し、スクリプトが30日後に$1000相当のBTCをAに残りをBに送るものとします。 -30日後の 1 BTC の USドル価格 を決定するのには神託が必要となり、しかし、これは、現在利用可能な完全な中央集約型の方法でさえ、信用とインフラの観点で大きな改良がひつようとなります。 -しかしながら、 UTXO は使うか使わないかの2択なので、 -神託が提示しうるすべての価格を UTXO で表すには、2進数計算しかなく、そのため極めて非効率な UTXO の"ハッキング"が必要で、様々な残高の UTXO を用意する必要があります。 -たとえば、2k の値をもつ UTXO を k = 0 ,..., 30 まで 31個 つくれば良いでしょう。 - -* **状態の欠如** - UTXO は使うか、使われないかのどちらかを必ず決定してやらなければなりません。 -このため、内部に「状態」を保持する多層形式の契約やスクリプトを記述することができません。 -このことにより、多分岐選択可能な契約や、分散型取引のオファー、2段階の暗号理論による決定プロトコル(セキュリティの高い計算問題の賞金を与える場合に必要です)をつくるのはとても困難となってしまいます。 -さらに、 -UTXO は単純な一度きりの契約をつくることにしか使用できず、分散型組織のような、より複雑な「状態」を保持する契約を記述できず、 -meta プロトコルの実装を困難なものとします。 -また、値の定まらない2進数状態では、「引き出し制限」が不可能となります。これは重要なアプリケーションであり、大きな弊害であると言えるでしょう。 - -* **Blockchain が見えない問題** - -UTXO は、ノンス、タイムスタンプ、直前のブロックのハッシュといった blockchain のデータに対して盲目です。 -このことにより、スクリプト言語が、ランダム性の観点で潜在的価値のあるソースを参照するのを防いでしまい、 -ギャンブル・アプリケーションや他のカテゴリのいくつかを、厳しく制限してしまうことになります。 - -このように、 -暗号通貨の上に進化型のアプリケーションを構築する方法を3つ見てきました。 -ひとつめは、新しい blockchain を Bitcoin を土台とした上につくり、スクリプト言語を使用し、meta プロトコルを実装する方法です。 -ふたつめは、新しい blockchain をつくる方法で、その性質を決定するのに無限の自由が得られますが、 -開発時間に関するコスト問題、スタートアップに関する問題とセキュリティー面の問題も同様に得られます。 -みっつめは、Bitcoin のスクリプト言語を使用する方法で、開発や一般化は簡単ですが、 -可能性が限られてくること、meta プロトコルの実装は簡単ですが、スケーラビリティの欠点に悩むことになります。 - -Ethereum では、 -われわれは、代替となる骨格を築き上げ、 -簡単な開発であっても、大きな成果物が得られ、 -スマフォのようなライト・クライアントのもつ財産に対しても強固なものを提供し、 -同時に、アプリケーションが 経済環境 と blockchain セキュリティ とを共有できるものを提供することを意図しています。 - - -## Ethereum - -Ethereum の目的は、分散型アプリケーションのための代替プロトコルを創造し、 -大規模な分散型アプリケーションにとって、われわれが非常に役立つだろうと信じるところの、数々の修正を加え提供することであります。 -ここにおいて、アプリの高速開発にかかる時間、小規模かつ滅多に使われないアプリに対するセキュリティ、他アプリ間の効率のよい相互作用を可能とすること、が重要視されます。 -Ethereum は、基本的に究極の抽象基盤層となるものの構築により、以上の目的を果たします。 -究極の抽象基盤層とは、埋め込み型チューリング完全なプログラム言語を伴う blockchain であり、 -これにより、所有・トランザクションの形式・状態遷移関数に関する、任意の独自規則を創造することのできる機能を備えた - smart contracts と 分散型アプリ をだれでも記述することができます。 -Namecoin の骨格だけを抜き出した実装は、二行のコードで記述できます。 -通貨や評判を管理するシステムは20行以下で構築可能です。 -「 Smart contracts 」と呼ばれる暗号理論で実装された「箱」は、値を保持し、ある条件が整った時にだけ、解錠できます。 -この smart contracts は Ethereum プラットフォーム上に構築可能であり、 -チューリング完全性、値が定まる仕様、状態の保持および blockchain への参照が可能となるところから、 -Bitcoin スクリプトにはない、広大かつより強力なプラットフォームとなります。 - - -### Ethereum アカウント - -Ethereum では、「状態」は、「アカウント」と呼ばれるオブジェクトから作り上げられ、各「アカウント」は、20 byte の アドレス と、アカウント間における値や情報の直接的やりとりである 状態遷移 を保持します。Ethereum アカウントは4つのフィールドを含みます。 - - -* **nonce** 、各トランザクションの処理が一度きりであることを確約するためのカウンター -* アカウントの現在の **ether balance** -* アカウントの **contract code** (もし存在すれば) -* アカウントの **storage** (デフォルトは空) - -Ether は、Ethereum における主要な内部暗号燃料であり、トランザクション手数料を支払うために使用されます。 -一般的に、アカウントには二つの種類があります。 -秘密鍵により管理される **EOA (externally owned accounts)** と自身のコントラクトコードにより管理される **contract (contract account)** です。 -EOA はコードを持たず、EOA からトランザクションを生成し署名することによって メッセージ を送ることができます。contract では、メッセージを受信した時はいつも保持コードをアクティベートし、内部ストレージを読み書き可能にし、メッセージを送信するもしくは新しいコントラクトを作る、といった内容のことが順番に実行されます。 - -Ethereum における contract は履行されるべきあるいは一緒にコンパイルされるべきものというよりかはむしろ、 -Ethereum 実行環境を職場とする「自動金融エージェント」といったものに似ており、メッセージやトランザクションによって起動されたときには、いつもある特定のコードを実行し、自身の ether 残高と、なんども使う変数を把握するのに必要な key/value ストレージ を直接管理する権限を持っている、ということに注意してください。 - - -### メッセージ と トランザクション - -Ethereum において、「トランザクション」は、 -EOA から送られたメッセージを貯蔵する 署名付データパッケージ を参照するために使用されます。 -トランザクションは、以下を含みます。 - -* メッセージの受領人 -* 送信者を特定する署名 -* 送信者から受領人へ送られる ether の量 -* オプショナルデータフィールド(署名付きデータパッケージ) -* `STARTGAS` 値:トランザクションの実行にかかる 計算のステップ数 の最大値 -* `GASPRICE` 値:送信者が支払う、1計算ステップあたりの手数料 - -最初の3つは、どんな暗号通貨にもある標準的な、トランザクションの「フィールド」です。 -4つ目のデータフィールドは、デフォルトでは関数を持ちません。 -しかし、Ethereum 仮想マシンは、contract が使用する opcode を保持する必要があり、その際このデータフィールドが使用されます。 -opcodeとは、「 contract がデータにアクセスするのに使用する opcode(オペレーションコード)」です。 -もし、contract が blockchain 上のドメイン登録サービスとして機能しているならば、 -contract は投げられたデータをふたつの「フィールド」を保持するものとして解釈したがることでありましょう。 -ひとつめのフィールドは、登録するドメインで、ふたつめのフィールドはIPアドレスです。 -コントラクトは、 opcode によって、メッセージに含まれるこれらの値を読み込むことで、適切にストレージの中に配置することが可能となるわけです。 - -`STARTGAS` と `GASPRICE` のフィールドは Ethereum サービス に対するモデル拒否運動を封じ込める狙いがあります。 -偶発的あるいは故意による無限ループや他の計算理論的に無駄なコードの消費を避けるために、 -各トランザクションにはそれらが実行するコードの計算ステップ数の上限を設ける必要があります。 -計算の基本ユニットは「 gas 」と呼びます。 -たいてい、1計算ステップは 1 gas を消費します。 -しかし、幾つかの命令では、計算量的に見てより高価であるため、 -少しおおきな gas の量が必要とされます。 -また、状態の一部として保持しなければならないデータ量が増えたりします。 -トランザクションにデータを埋め込む際には、1 byte 毎に 5 gas の「手数料」もかかります。 -「手数料」システムの意図するところは、攻撃者に対し、計算資源や帯域、ストレージを含めた、 -彼らが消費する全リソースの量に比例した支払いを強要するためです。 -このようにして、ネットワークが消費するどんなリソースにも、それが大量消費とつながるような状況を生み出す、 -すべてのトランザクションに対して、消費量の増加に比例した gas の支払いを強要することとなります。 - - - -### Messages - -contract は他の contract に対して「メッセージ」を送信することが可能です。 -「メッセージ」はネットワークに対して配信されることがなく、 -Ethereum 実行環境内でのみ存在します。メッセージは以下を含みます。 - -* メッセージの送信者 (implicit) -* メッセージの受信者 -* メッセージと一緒に送信されるetherの量 -* オプショナルデータフィールド -* `STARTGAS` 値 - -基本的には「メッセージ」はトランザクションのようなものですが、 -contract により生成され、外部での動作はしない、という点で異なります。 -メッセージは contract が `CALL` opcode を実行している時に生成され、 -この opcode は「メッセージ」を生成し、実行します。 -トランザクションのように、 -メッセージは、そこに記述されたコードを実行する 受信者のアカウント へと導かれます。 -このようにして、contract はEOAのやり方と全く同じ方法で、他の contract と関係性をもつことができます。 - -ただし、以下のことに注意してください。 -トランザクションやコントラクトによって署名された gas の許容値は、そのトランザクションとトランザクション配下の実行ステップにおいて消費される gas の総量に適用されます。 -たとえば、もし、外部管理者である A が B に対し、1000 gas と一緒にトランザクションを送信し、B は、C にメッセージを送信する前に 600 gas を消費し、C の内部実行として戻り値を返すまでに 300 gas が消費されたとすると、 B は、「ガス欠」とならないためには、もう 100 gas を使用することが可能です。( ガス欠 となってしまうとエラーを返し、トランザクションは実行されません。) - -### Ethereum の 状態遷移関数 - -![ethertransition.png](http://vitalik.ca/files/ethertransition.png?1) - -Ethereum の 状態遷移関数, `APPLY(S,TX) -> S'` は次のように定義できます: - - -1. トランンザクションが 「 well-formed 」であるか(例えば、値が正しい数値であるか)チェックし、 -署名が有効であれば、ノンスが送信者のアカウントのものと合致するかチェックします。もし、そうでなければ、エラーを返します。 -2. トランザクションの手数料を `STARTGAS * GASPRICE` として計算し、署名から送信アドレスを決定します。 -送信者のアカウントの残高から手数料を差し引き、送信者のノンスを次の値へとインクリメントします。 -もし、残高不足であれば、エラーを返します。 -3. `GAS = STARTGAS` として、`GAS` 値を初期化し、トランザクションにおける byteデータ量 のぶんだけ byte あたり一定量の gas を支払います。 -4. 送信者のアカウントから受信者のアカウントにトランザクションの値を転送します。もし、受信者のアカウントが存在しないものであったならば、あたらしくつくります。もし、受信者のアカウントが contract であれば、すべての実行が完了するか、あるいは ガス欠 になるまで contract のコードを実行します。 -5. もし、送信者が十分なお金を持っていなかったり、 ガス欠 のために、値の転送が失敗した場合には、手数料の支払いを除いて、全状態を元に戻し、手数料はマイナーのアカウントに加えます。 -6. そうでなければ、余った全ての gas を全て送信者に返し、消費した gas は採掘者に支払われる手数料として送信します。 - - -たとえば、contract コード が以下であるような場合を考えましょう。 - - if !self.storage[calldataload(0)]: - self.storage[calldataload(0)] = calldataload(32) - -実際は、contract コードは低級EVM言語(アセンブラ)であることに注意してください。 -このコードは Ethereum における高級言語であるひとつである Serpent 言語で書かれており、コードを確約したものにするために、 -低級EVMコードへコンパイルすることが可能です。 -さらに次に記す状況を想定しましょう。 -この contract のストレージは空の状態から始まり、 -* 10 ether の値と、 -* 0.001 ether / gas の gasprice で 2000 gas 、そして -* 64バイトのデータ(0-31バイトが数字`2`を表し、32~63バイト番地が`CHARLIE`という string を表しているものとします。) - -の3つが、トランザクションとともに送信されるものとします。 -この場合、状態遷移関数のプロセスは以下のようになります。 - -1. トランザクションが有効かつ well-formed であるか確認する。 -2. トランザクション送信者が、最低限 2000 * 0.001 = 2 ether を所持しているか確認する。 -もし、所持していれば、2 ether を送信者のアカウントから差し引く。 -3. gas の量を gas = 2000; として初期化します。トランザクションのバイト長が 170 byte であるとすると、byte あたりの手数料が 5 であったことから、850 を差し引くことなり、1150 gas が残ります。 -4. 送信者のアカウントから 10 ether を差し引き、それを送信先である contract アカウントに加えます。 -5. コードを走らせます。今回はとてもシンプルです。 -まず contract は自身のストレージにおける `2` 番目の項目が使われているか確認し、 -未使用であることを確認し、ストレージの `2` 番地に `CHARLIE` という値をセットします。 - -この操作で、187 gas を消費するとしましょう、すると残りの gas は 1150 - 187 = 963 となります。 - -6. 963 * 0.001 = 0.963 ether を送信者のアカウントに返金し、結果として出てきた「状態」を返します。 - -もしも、トランザクションの受信側に contract がなかったら、当該トランザクションにおける全手数料は、たんに、トランザクションのバイト長に 与えられた `GASPRICE` の値をかけたものとなり、トランザクションと一緒に送られたデータは全く関係のないものとなってしまうでしょう。 - - -Note that messages work equivalently to transactions in terms of reverts: -もしメッセージが gas を使い果たしてしまったらば、そのメッセージあるいはそのメッセージが引き金となるすべての実行処理がもとにもどされてしまいますが、その「親」の実行に関しては、やり直しになる必要がありません。 -これは、contract が他の contract を呼ぶことに関して「安全」であることを意味し、これは、A が G gasもって B を呼び出すと、A による実行はたかだか G gas 分であることが保証されている、と捉えることができます。 - -最後に、contract を生成する opcode である `CREATE` があることに注意してください。 -その実行メカニズムは一般的に言って `CALL` に似ていますが、実行結果があたらしく作られたコントラクトのコードを返すという点を除いて同じになります。 - -補足:contract が実際に信用あるものとして、機能するかどうかについてですが、 -例として2人間の賭博をあげますと、二人のお金を預けることになるコントラクトはきちんと仕事をするという保証が必要です。 -片一方が作成し、騙し取るということが可能に思われます。しかし、これは簡単に解決できます。片方により作成されたコントラクトの公開鍵はわかっているので、そのコードが実行する内容は明るみにでており、エミュレーターを使って、きちんと動作することを確認することで、簡単にコントラクトの安全性を逐一確認することができます。 - - -### コード実行 - -Ethereum の contract コードは低級スタック・ベース・バイトコード言語で書かれており、「 Ethereum 仮想マシンコード 」や「 EVM code 」などと呼ばれております。 -そのコードは一連のbyte列から構成されており、各 byte はひとつの命令を表しております。 -一般的に、コード実行とは、プログラムカウンターが現在示すところの命令を実行してはプログラムカウンターを1つインクリメントする繰り返しにより構成される、無限ループであり、エラーや `STOP` あるいは `RETURN` といった命令が検出されるまで終わることがありません。 - -EVM における 命令 はデータを貯蔵するために必要な 三種類の スペース にアクセスします。 - -* **stack**, 後入れ先出しのコンテナで、push と pop という二つの命令により値を出し入れします。 -* **Memory**, 無限拡張および無限展開可能なバイト配列 -* **storage**, contract が保持する長期保存用ストレージで 、Key/value の貯蔵庫。スタックやメモリでは計算実行後毎にリセットされるのに対し、storage では長期間、値が保持される。 - -コードも、受信したメッセージにおける 値・送信者・データ にアクセス可能です。また ブロックヘッダ のデータにも同様にアクセスできます。コードは出力として byte 配列のデータ を戻り値として返すことも出来ます。 - -EVM コード における、形だけの実装が施された実行モデルは、驚くほどシンプルです。Ethereum 仮想マシン が動作しているとき、 -ネットワーク全体における、全仮想マシン計算状態 は次のタプルにより決定されます。`(block_state, transaction, message, code, memory, stack, pc, gas)` -ここで、 - `block_state` は、全アカウントを保持し、残高やストレージといったデータをひきこんだ「 global な状態 」を表します。 -実行の開始時毎に、「 命令 」は、変数`pc`番目の byte コードを取ってきます。`pc >= len(code)`の条件下では 0 となります。 -各命令はタプルに対して、どのように影響するのかという点に関して、独自の定義があります。 -例えば、 -`ADD` はスタックから、二つアイテムを引き出し(pop)、その合計をまたスタックへ押し込めます(push)。 -`SSTORE`は上部からふたつのアイテムを pop の上、二つ目のアイテムを contract のストレージにおける、一つ目のアイテムが示す番地に格納します。 -即時コンパイルによる EVM マシン実行最適化の方法はたくさんありにもかかわらず、Ethereum は基本的に、実装すると数百行ほどの byte コードスペースを費やします。 - -### Blockchain と 採掘 - -![apply_block_diagram.png](http://vitalik.ca/files/apply_block_diagram.png) - -Ethereum の blockchain は多くの点で Bitcoin のそれと似ていますが、いくつか違う点があります。 -bockchain のアーキテクチャに関する Ethereum と Bitcoin の違いは、次のようになります。 -Bitcoin とは違い Ethereum のブロックはトランザクションのリストとブロック生成時点の 状態 のコピーを内部に保持しています。 -脇道にそれますが、ブロック番号 と difficulty という、べつの二つの値もブロックに貯蔵されます。 -Ethereum における基本的な、ブロック有効化 アルゴリズム は以下となります。 - -1. ブロックの参照する 直前のブロック が存在し、それが有効であるかをチェックします。 -2. タイムスタンプが 、直前のにおけるそれよりも値が大きく、15分さきの未来まで後出のものより値が小さいことを確認します。 -3. ブロック番号、難易度、トランザクションのルート、Uncle のルート および ガスの上限(様々な、低級Ethereumの仕様概念)が有効であるか確認します。 -4. ブロックの有効証である proof of work が有効であるか確認します。 -5. 直前のブロックの最後の状態を `S[0]` とする。 -6. `TX` をトランザクション・リストとし、`n` 個のトランザクションを含むものとする。 -`0...n-1` までの全ての数に対し、`S[i+1] = APPLY(S[i], TX[i])` とする。 -もし、アプリケーション群のどれか一つでもエラーを返したり、ブロックで消費される全 gas 量がこの段階で `GASLIMIT` を超過していたりすると、エラーを返します。 -7. `S[N]` を `S_FINAL` としますが、採掘者へのブロック採掘に対する報酬も加えます。 -8. 状態 `S_FINAL` の マークル木 の ルート がブロックヘッダにおいて与えられる 最終状態のルート と一致するか確かめます。 -もしそうであれば、ブロックは有効で、そうでなければ、ブロックは無効です。 - -さっと目を通しただけでは、このアプローチはとても非効率に思うかもしれません。 -なぜならば、このやり方では、各ブロックで 全ネットワークの状態 を保存する必要があるからです。 -しかし、現実的には、Etherum の効率は、Bitcoin のそれと比べなければなりません。 -というのは、ここで 保存される状態 は、そのデータ木構造に貯蔵され、ブロック毎に、その小さな部分木が変更される必要があります。 -このようにすると、一般的に、隣り合う二つのブロック間では、木の大部分は同じとなるはずであり、 -そうであるがゆえ、データは、一度貯蔵され、ポインタ(つまり部分木のハッシュ値)を使用して二度 引用符 が付加される、という形式をとります。 -この「状態」の保存方法を達成するために「 パトリシア木 」と呼ばれる 特別なデータ木 が使われ、 -パトリシア木は、マークル木のコンセプトに対して修正がなされており、ノードの挿入・削除が可能であり、 -ただ変わるだけでなく、効率が良くなります。 -さらに、全状態の情報が、最新のブロックに含まれますので、ブロックチェインの全履歴を保存する必要がありません。 -これは、Bitcoin に適用されたら、5 - 20倍のスペース節約になる 技術戦略 です。 - -ひろく尋ねられるのが、「どこで contract が実行されるのか」という質問で、物理デバイス上でどこか?ということです。 -この質問に対しては、シンプルな回答があります。 -「 contract の実行プロセスは、その状態遷移関数の定義の一部であり、それ故ブロックの有効化アルゴリズムの一部となります。 -なので、もしトランザクションがブロック `B` に付加されたならばそのトランザクションにより生まれるコード実行は全てのノードで実行されます。 -その時点より未来において、ブロック`B`をダウンロードした全てのノードということです。」 - - -## アプリケーション - -一般的に、Ethereum 上には、3 種類のアプリケーションがあります。 -一つ目のカテゴリーは、金融系のアプリケーションで、金銭を使用する契約に対し、導入・管理の強力な手段をユーザへ提供するものです。 -これには、副次通貨、金融ディリバティブ、ヘッジング契約、預金、資産相続文書や、さらに言及しますと、労働契約書まるまる含めたものなどがあります。 -二つ目のカテゴリは、準金融系アプリであり、非金融的事象の結果に対して金銭を絡めてくるようなもので、その良い例として、計算理論における難題に対し懸賞金を自動執行するようなアプリが挙げられます。 -三つ目としては、オンライン選挙 や 分散型統治機構 があります。 - - -### 証明書発行のシステム - -ブロックチェイン上の 証明書発行システム (token system) には、多々のアプリケーションがあり、 -USドルや金を表す副次通貨から、株式、スマートプロパティとして個人発行した証明書、堅牢で偽造不可な商品券、あるいは全くの無から新たに作られた貨幣証書でさえその範囲に含まれ、経済原理となる(人々の行動の動機付けとなる)ポイント(稼ぎ)のシステムとして使われます。 - -Ethereum 上で 証明書発行システム を実装するのは驚くほどに簡単です。 -理解するために重要点は、 -通貨や証明書システムといった基軸となるものはすべて、 -あるひとつの操作をともなうデータベース だということです。 -そのひとつの操作とは : - -``` -A から X 単位を差し引き、それを B にやる -その時の条件として -(1) A は トランザクション以前に 少なくとも X 単位 を保持している -(2) トランザクションが A によって承認される -``` - -トークンシステムの実装するのにかかる手間は、このロジックを contract に実装するだけです。 -トークンシステムの Serpent における実装の基本コードは以下のようになります: - - def send(to, value): - if self.storage[msg.sender] >= value: - self.storage[msg.sender] = self.storage[msg.sender] - value - self.storage[to] = self.storage[to] + value - -これは、基礎的に、このドキュメントの冒頭で説明した"銀行システム" の状態遷移関数の文字通りの実装となります。 -このコードとは別に、初期化ステップとして通貨単位を共有するあるいはその他特例のために、数行必要となり、 -理念としては、ある function は、他の contract に、あるアドレスの残高を探索してもらうために追加されるものですが、 -コードの記述はこれで十分です。 -理論的に、Ethereum 基盤の証明書発行システムで副次通貨としてふるまうものは、 -潜在的に別の重要な特徴を持っています。それは Bitcoin 基盤の meta currency には無いもので、 -副次通貨で直接トランザクションの手数料の支払いが可能だという機能です。 -もしこれを実装すらならば、 -手数料支払いに使用される ether を送信者に 再振込 する方法をとり、 -contract は、その時の ether 残高を維持管理することになるかと思います。 -手数料支払い時、および常駐のオークションにおいて副次通貨を再度売る時、に使用される、この内部保持されている副次通貨単位を集めることで、ether の残高を再度満たすことになるでしょう。 -ユーザはこのため ether でアカウントをアクティベートする必要がありますが、 -一度 ether が確認されると、contract がその度ごとに再度振込をするので、再利用可能となるでしょう。 - - -### 金融ディリバティブ と 安定価格通貨 - -金融ディリバティブ は、最も一般的な、smart contract のアプリケーションであり、コード実装が最も簡単なもののひとつです。 -金融契約の実装における主な試練は、その大部分が価格表示器への外部参照が必要となるということです。 -例えば、とても望ましいアプリケーションの例として、USドルに対するEther のボラティリティ(取引規模に由来する凶暴性)に対して、ヘッジ(囲い込み:高値で売り、安値で買う)をおこなう smart contract がありますが(これは価格安定化に寄与します)、 -これを行うには、ETH/USD の価格がいくらであるかを知るための contract が必要となります。 -いちばんシンプルな実行方法としては、必要に応じて contract を更新する能力をもつように設計された(NASDAQのような) 特定のパーティにより維持管理される「 データフィード contract 」を通す方法があります。これにより、他の contract はそのデータフィード contract にメッセージを送信し、価格情報が与えられた返答を受け取ることができます。 - - -それらの深刻材料が与えられた条件下において, ヘッジング contract は次のようになるでしょう : - -1. パーティ A が 1000 ether 入金するのを待ちます -2. パーティ B が 1000 ether 入金するのを待ちます -3. 1000 ether の USD での価値を記録します。これはデータフィード contract を探索することで計算され、ストレージに対し、「Xドルだ」と告げます(記録します) -4. 30日後、(データフィード contract から得られた新しい価格によって計算された)Xドル相当の ether をAに送信し、 -残りをBに送るのに、A もしくは B が 該当 contract を再アクティベートすることができるようにします。 - - -このような contract には暗号取引における重要な潜在価値があるでしょう。 -暗号通貨を取引等に引用するときに現れる主要な問題として、極めてボラティリティが高いということがあります。 -多くのユーザや商売人が暗号通貨の取引の利便性やセキュリティを望んでいるかもしれないにもかかわらず、 -たった1日で資金の23%を失うという場面には直面したくないでしょう。 -この問題に対して、いままでに提案された、最も一般的な解決策としてあるのは、発行者の後ろ盾のある財産 です。 -この考えは、発行者が発行並びに無効化の権利を有した副次通貨をつくり、 -金やUSDのような特定の基礎財産の一単位をオフラインで提供する全ての人に対し、その副次通貨の一単位を提供するというものです。 -そして発行者は、暗号副次通貨が送り返されたときには、基礎財産を提供することを約束します。 -この仕組みによって、全ての非暗号化財産が、暗号財産へと "上場" されることが可能となりますが、これは発行主体が信用可能であることにより実現します。 - - -しかし実際は、発行主体は常に信用に価するとは限らず、 -中には、その銀行システムはあまりにも脆弱であったり、 -あまりにも顧客対抗的であるようなことが見受けられ、 -これは金融サービスとしてはとてもあるまじきものとなりえます。 -金融ディリバティブ はこれに取って代わり、よりよいサービスを提供します。 -金融ディリバティブにおいては、財産をバックアップするための資金を提供する単一の発行主体の代わりに、 -分散型の投資市場、つまり ETH ような暗号参照財産の価格が上昇するか賭けをする場所、がその役割を担います。 -発行主体とは違って、投資家は自分たちの都合で売り出しをなかったことにすることができません。というのは、「 ヘッジング contract 」がエスクローとして資金を保持しているからです。この方法でも、まだ完全に非中央集約化したわけではないことに注意してください。というのは、価格表示器を提供するのに信用あるデータソースが必要となります。とはいうものの、中央集約型のインフラに対する要求事項を減らし、かつ詐欺の潜在性を減らした点で大きな進歩と言えます。(副次通貨の発行主体となるのとは違って、価格データの発行はライセンスが必要とされず、表現が自由な範疇に分類される可能性が高いのです。(そのため参入への垣根が低い自由競争をもたらします。)) - - -### Identity と Reputation のシステム - -すべての代替暗号通貨のなかでいちばん早くに登場した [Namecoin](http://namecoin.org/) は、 -名前登録サービスに Bitcoin と似た blockchain を用いる試みを行いました。 -そこでは、ユーザは他のデータとともに 名前 を公共的なデータベースに登録することができます。 -Namecoin の最も広く普及した利用方法は、[DNS](http://en.wikipedia.org/wiki/Domain_Name_System) システムとして使う方法で、 -"bitcoin.org" のような名前を、IPアドレスに対応( mapping )づけたものです。 -他の使用方法として、email authentication や、潜在的発展性のある reputation システム などが考えられます。 -以下に、Namecoin に似た名前登録システムの Ethereum 上での、基本 contract を示します。 - - def register(name, value): - if !self.storage[name]: - self.storage[name] = value - -contract はとてもシンプルです。 -システムの全容は、追加のみが可能で削除および修正が不可能な Ethereum ネットワーク内部にあるデータベースです。 -誰でも、幾つかの値とともに名前を登録することが可能で、その登録内容は永遠に保管されます。 -より洗練された名前登録 contract は、他の contract がその内容を探索できるようにするための 関数節( (内部)関数 )をもつでしょう。 -同様に、(例えば、初期登録者のような) 名前の所有者 がデータを変更したり所有権を移行したりするためのメカニズム のようなものも考えられます。 -reputation や web上の信用度 といった機能性さえ、システムの上層に追加可能です。 - - - -### 分散型ファイルストレージ - -過去数年にわたり、オンライン上でのファイルストレージ・サービスのスタートアップが出現し、たくさんの非常に人気あるものが生まれました。 -一番人気のあるのが、Dropbox です。ユーザはハードドライブのバックアップをアップロードし、保管してもらうことが可能で、月額使用料と引き換えにそのデータにアクセスできます。 -しかしながら、使用料金支払いの点でファイルストレージの市場は比較的非効率です。 -この使用料金問題に関する様々な[現存の解決方法](http://online-storage-service-review.toptenreviews.com/)を概観しても、" uncanny valley "と呼ばれる、20-200 GBレベルでは、無料利用や企業割引が全く存在せず、ファイルストレージのアクセスに対する月額料金は、同等容量のハードドライブの調達に要する全コストをたった一ヶ月のうちに上回ってしまいます。 -Ethereum の contract によって、分散型ファイルストレージという新しい経済圏を開発することが可能で、そこでは、個人ユーザが自分のハードドライブを貸し出すことで、小遣い稼ぎが可能となり、さらに未使用領域が使用されれば、ファイルストレージのコストは下がります。 - -そのようなデバイスを裏で繋ぎとめておくための 鍵 として、" 分散型 Dropbox contract " と命名したものがあります。 -この contract は次のように動作します。 - -1. まずはじめに、保存したいデータをブロックに分割し、プライバシーのために各ブロックを暗号化し、 -その暗号化したブロック群から、(データ保管木として)ひとつのマークル木を作り上げます。 -2. N ブロック毎に、contract は マークル木からランダムに参照先を選び、 -(ランダム性を提供するものとしては直前のブロックハッシュを使用し、contract コードでアクセスできるようにします)、 -そのデータ木におけるその特定の参照先におけるそのブロックの所有のSPV証明のようなもの(ブロックを預けた人は当然ながら秘密鍵を持っており、その預け人の出すクイズに対して簡潔に回答した証明書)を載せたトランザクションを一番はじめに提供した個人に対して、X ether を与えます。 - -ユーザがそれらのファイルを再ダウンロードしたいときは、 -[micropayment channel プロトコル](https://bitcoinj.github.io/working-with-micropayments) を使用することができ、 -(例えば 32 KBで 1 szabo 支払うといった具合で、) ファイルを復元することできます。 -micropayment channel を利用した最も支払い効率のよい方法は、 -支払い者がその終わりまでトランザクションを発行せず、 -かわりに、そのトランザクションを32KB毎に同じノンスを使用して -微量ではあるもののより利益を生むトランザクションに置き換え続けるというやり方です。 - -この 分散型 dropbox protocol の重要な性質として、 -預け人はたくさんの乱雑なノードがファイルを忘れてしまうという決定をしないものと信用しているように見えるかもしれませんが、 -秘密共有を通して、ファイルをたくさんの断片へと分割することで、また各断片がどこかのノードに未だに保存されていることを確認するために contract を監視することで、そのリスクは限りなくゼロに近づきます。 -もし、その contract がお金の支払いを続けていたならば、それは、誰かまだファイルを所有している人がいるといった 暗号学的証拠 を提供していることとなります。 - - - -### 分散型自律組織 - -分散型自律組織 Decentralized autonomous organization (DAO) の一般的な概念としては、 -会員あるいは株主が、67%以上の多数派を占めると、contract コードの修正や、資金の消費が可能となる、仮想団体としてのものです。 -会員であれば、まとまることで資金の使い道を決定することができるでしょう。 -資金の使い道としては、懸賞金、給料、あるいは、労働報酬として使用価値のある域内通貨のような、 -異文化地域における仕組みにさえ、適用するこができます。 -これは基礎的に、 -伝統的な会社や非営利組織を合法的にとらえることのできる枠組みでありますが、 -執行に際し使用するのは、暗号理論に則った blockchain テクノロジー だけとなります。 - -DAO の議論をさらに進めると、配当株主や株券をともなう 分散型自律株式会社 DACorp (decentralized autonomous corporation) といった資本主義を推し進めるモデルに行き当たりました。 -代案としてある、分散型自律共同体 DACom (decentralizd autonomous community) では、 -会員の除名あるいは入会を承認するといった決定に関し、全会員が平等に権利を保持し、在籍会員の67%の承認を必要とします。 -というのは、一人一会員のみという要望があれば、グループによってまとまって執行される必要が有るのです。 -(非中央型自動株式会社では、当然大株主が決定権を支配するので、こういった要望は、却下されるでしょう。) - -DAO をコード化する方法の概要は次のようになります。 -一番シンプルな設計を示しますと、それは「もし、2/3の会員が賛同すれば、変更する」といった 自己修正コード です。 -理論的には contract コードは不変なものですが、 -別のところに contract を複数保持し、 -ストレージは修正可能なので、そこに呼び出す contract のアドレスを保持することで、 -事実として、contract の書き換えが可能となります。 -DAO contract のようなものの簡素な実装において、そのトランザクションが提供するデータによって、 -三種類に分けることができます。 - -* `[0,i,K,V]` to register a proposal with index `i` to change the address at storage index `K` to value `V` -* `[0,i]` to register a vote in favor of proposal `i` -* `[2,i]` to finalize proposal `i` if enough votes have been made - -contract はこれら各種類ごとに、複数の条項を持つでしょう。 -contract は、誰が投票したかというリストに従い、全オープンストレージの書き換えを維持管理するでしょう。 -さらに、contract は、全会員のリストも保持するでしょう。 -どんなストレージの変化も、それが投票する会員の2/3に達したとき、ある最終決定トランザクションがその変化を執行できることとなるでしょう。 -より洗練された枠組みとしては、 -トランザクションの送信、会員の除名や入会のような特徴を組み込んだ投票システムを保持するものもあり、 -そして流動的民主主義 [Liquid Democracy](http://en.wikipedia.org/wiki/Delegative_democracy) スタイルの代議員議会の投票でさえ提供可能です。 -(※誰でも代議員選出が可能で、その選出投票は、遷移的であり、結果、もしAがBを、BがCを選出したならば、CはAの投票権を保持することになります。) -この設計であれば、DAO は分散型コミュニティとして、有機的成長を遂げることが可能で、 -民衆は結果的に、会員の選出作業を専門家に委任することが可能となります。 -しかし、これは "現行の政治システム"にみうけられるようなものとは異なり、 -個々のコミュニティメンバが提携先を変えることで、時間軸上において、専門家は簡単に出現と消失(取り替え)することが可能です。 - -代わりとなる分散型株式会社のモデルでは、0以上の株式をもつアカウントがあり、株式の 2/3 が決定に必要とされます。 -完璧な枠組みとしては、財産管理機能や、株式売買の申請機能および受諾機能を備えたものがあるでしょう。( contract 内部に注文一致させる機能があることが望ましいでしょう) -代議員選出による委任は、流動的民主主義を存在させ、" 意思決定機関 " という概念を一般化するものでしょう。 - - -### その他のアプリケーション - -**1. 預金ウォレット**. 次のような場面を考えて下さい。アリスは、自分の資金を安全に管理したいとします。 -しかし彼女は、資産を失うことや秘密鍵がハッキングされることを心配しています。そこで彼女は、銀行となるボブとともに、 -contract をつくり、ether をその中に保管します。それは以下のようになります。 - -* アリスは自分一人で1日あたり最大資金の1%を引き出すことが可能です。 -* ボブは自分一人で1日あたり最大資金の1%を引き出すことが可能です。しかし、アリスは自分の秘密鍵でこのボブの能力を奪い去るトランザクションを作成することができます。 -* アリスとボブは一緒であればどんな額でも引き出し可能です。 - -通常、1日1%というは、アリスにとって十分な額であり、もしそれ以上引き出したいのであれば、ボブに頼めば済む話となります。 -もし、アリスが秘密鍵をハッキングされたならば、アリスは、ボブのところに駆け寄り、ふたりで新しい contract に資金を移します。 -もし、彼女が秘密鍵をなくしてしまえば、結果として、ボブは資金を引き出すことになるでしょう。 -もしも、ボブが悪意をもっているとわかったならば、アリスは、ボブの引き出し能力を消去できます。 - -**2. 農作物保険**. 金融ディリバティブ contract は簡単に作成可能ですが、データフィードとして、価格表示器でなく天候を使用します。 -アイオワ にいる農家が、逆にアイオワ における降水量を基盤として逆に支払いをするディリバティブを購入したとすると、 -もし干ばつがあったならば、農家は自動的にお金を受け取り、もし十分な降水があったなら、作物が同様の働きをしてくれるので、農家は幸運を手に入れることができます。これは一般的に、自然災害の保険にも拡張可能です。 - -**3. 分散型データフィード**. 金融 contract その他において、"[SchellingCoin](http://blog.ethereum.org/2014/03/28/schellingcoin-a-minimal-trust-universal-data-feed/)" と呼ばれるプロトコルを通してデータフィードを分散化することが実際可能です。 -SchellingCoin は基本的に次のように動作します。 -N 個のパーティが全て、ある与えられた一つのデータ(例えば ETH/USD の価格)の値をそれぞれ提供するものとします。 -その価格の値はソートされ、その値の順番が 25% ~ 75% であるものが、報酬を得られるようにします。 -全員が、他の全員が提供するだろう答えを提供するインセンティブを保持し、その大多数のプレイヤが現実的に認める唯一の価格が、明白な基準となり、これは信用のおけるものとなります。 -これによって、理論的にどんな数値をも提供することが可能な、分散型プロトコルが作られます。 -それには、ETH/USD価格、ベルリンの気温、あるいは特定の重い計算の結果、でさえ含まれます。 - -**4. スマート・マルチシグネチャ 認証**. Bitcoin では マルチシグネチャ・トランザクション contact が可能で、例えば、5つの秘密鍵のうち、3つが揃えば資金を使用できるといったものです。 -Ethereum では、より詳細な設計が可能です。たとえば、5つのうち4つで全て使用可能とし、5つのうち3つで1日10%使用可能とし、5つのうち2つで1日0.5%使用可能とすることができます。 -加えて、Ethereum マルチシグネチャは同期します。というのは二つのパーティが、別々の時間に blockchain 上に署名を登録することが可能で、その最後の署名が行われれば、自動的にトランザクションは送信されます。 - - -**5. クラウド・コンピューティング**. EVM テクノロジは、検証可能な計算環境を構築する目的でも使用され、 -ユーザは他人に対して、計算の実行を依頼することができます。またオプションとしてランダムに選択したチェックポイントにおける、計算の整合性を示した証拠の提出を依頼することができます。 -これによって、クラウド・コンピューティングの市場を作ることが可能で、どんなユーザでも、デスクトップ型あるいはノートパソコンあるいは特化型サーバを用いて参加することが可能です。そして、セキュリティ課金を用いたスポットチェックにより、システムが信用に足るかということを確かめます。(結果ノードはチートすることによって、より利益を得ることはできません。) -このようなシステムは、あらゆるタスクに適する、ということはないかもしれません。たとえば、内部プロセスにおける高度な連携が必要なタスクだと複数のノードによる大きなクラウドにおいて、簡単に計算することは不可能です。 -しかしながら、他のタスクは容易に並列化可能で、SETI@home 、folding@home や 遺伝的アルゴリズム のようなプロジェクトは簡単に、プラットフォーム上に構築可能です。 - -**6. P2P 賭博**. P2P賭博プロトコルはいくらでも実装可能で、例えば、 -Frank Stajano と Richard Clayton による [Cyberdice](http://www.cl.cam.ac.uk/~fms27/papers/2008-StajanoCla-cyberdice.pdf) は Ethereum blockchain 上で実装できます。 -簡素な賭博プロトコルは実はただの次のブロックのハッシュ値を当てるだけの contract で、より進化したプロトコルはそこから作り上げることが可能で、チート不可能な手数料が0に近い賭博サービスを作ることができます。 - -**7. 市場予測**. SchellingCoin あるいは Oracle が提供されることで、市場予測もまた実装が容易となります。 -市場予測と SchellingCoin が一緒になることで、非中央組織の統治プロトコルである [futarchy](http://hanson.gmu.edu/futarchy.html) の主流アプリケーションとしては初のものと成る可能性があります。 - -**8. blockchain 上の商取引市場**, Identity と Reputation のシステムを基盤とします。 - - - - - -## 雑録 と 関心事 - -### GHOST の修正実装 - - -Greedy Heavist Observed Subtree (GHOST) は、Yonatan Sompolinsky と Aviv Zoharによって[2013年12月](http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf)に初めて導入されたイノベーションです。 -GHOST開発の動機は、blockchain の検証時間を短縮すると、 -現行のシステムでは、「非同期状態」(最新のブロックと同期していない状態)の割合が増えるため、 -セキュリティを減少させてしまうという問題に苦しんでいます。 -というのは、ブロックはネットワークを通して伝播するのにある程度の時間がかかるため、 -もし、マイナーAがブロックを発掘し、つぎにマイナーBがたまたまAのブロックがBに伝わってくる前にその他のブロックを見つけた場合、 -マイナーBのブロックは最終的に無駄となり、ネットワークセキュリティに貢献しないこととなります。 -さらには中央集約の問題があります。 -それは、もしマイナーAが30%の採掘能力を持つマイニングプールで、Bが10%の採掘能力を持つものとすると、 -Aには、採掘時間の70%は無効なブロックを生成するリスクがあり、 -(採掘時間の30%のあいだ、Aは有効な最終ブロックを生成しているということなので、採掘データをすぐに得る事ができます。) -一方、Bには、採掘時間の10%は無効なブロックを生成するリスクがあります。 -このよう状況で、 -ブロック生成の間隔が「非同期状態」の割合が高くなるぐらいに十分、ブロック間のインターバルが短いと、 -Aは、単に自身のプールのサイズから得られる効能によって、実質上さらに効率的となります。 -これら二つの効果が結びつくことで、 -ブロック生成の速いブロックチェーンは、ネットワーク上の採掘能力のうち大きな割合を占めやすくなり、 -マイニングのプロセス全体をコントロールできるマイニングプールを生み出してしまいます。 - -Somopolinsky と Zohar の説明によると、 -GHOSTは、最長チェインの計算上において、無効ブロックを採り入れることで、 -一つ目のネットワークセキュリティ損失の問題を解決します。 -つまり、親ブロックや先祖ブロックのみでなく、 -proof-of-workの裏付けされネットワーク上で最長チェインを誇る、 -先祖ブロックの無効な子孫ブロック ( ethereum 用語では 「 uncle (叔父) 」) が計算に加えられます。 -二つ目の中央集約のバイアスがかかるという問題を解決するためには、 -Somopolinsky と Zohar によって描かれたプロトコルのさらに先を考える必要があり、 -無効ブロックへの報酬を供給する必要があります。 -無効ブロックは元となる報酬の87.5%を受け取り、 -uncle として無効ブロックを採り入れた nephew (甥)ブロックには残りの12.5%が贈られます。 -しかしながら、トランザクション手数料は uncle には与えられません。 - -Ethereum は、7層だけ遡る簡易版 GHOST を実装しました。 -仕様としては以下の通りです。 - -* A block must specify a parent, and it must specify 0 or more uncles -* An uncle included in block B must have the following properties: - * It must be a direct child of the kth generation ancestor of B, where 2 <= k <= 7. - * It cannot be an ancestor of B - * An uncle must be a valid block header, but does not need to be a previously verified or even valid block - * An uncle must be different from all uncles included in previous blocks and all other uncles included in the same block (non-double-inclusion) -* For every uncle U in block B, the miner of B gets an additional 3.125% added to its coinbase reward and the miner of U gets 93.75% of a standard coinbase reward. - -この制限版の GHOST では、7世代上までの uncle を取り込みますが、これが採択されたのには2つの理由がありました。 -ひとつめとして、無制限の GHOST だと、与えられたブロックに対し、どの uncle が有効なのか確かめる計算が複雑になりすぎます。 -ふたつめとして、無制限の GHOST と Ethereum で使用されている報酬の方法が合わさると、採掘者が、メインチェイン上で採掘する動機を取り去ってしまい、攻撃者のチェインにおいてはそうでないので、攻撃されすくなります。 - - - -### 手数料 - -blockchain 上に発行される全トランザクションは、ネットワークに対し、 -ダウンロードと検証に際し必要なコストの支払いを強いるので、 -乱用を防ぐために、トランザクション手数料に代表される、何らかの規制メカニズムが必要となります。 - - -Bitcoin でとられている初期のアプローチでは、純粋な寄付金としての手数料をとり、 -採掘者に対し、「門番」の役割と動的な最小額を決める役割を依頼しています。 -このアプローチはBitcoinコミュニティには好意的に受け入れられました。 -これには、採掘者とトランザクション送信者間の需給バランスにより価格が決まる、といった市場原理に基づくという理由があります。 -しかしながら、この論理の道筋には問題があって、トランザクションの処理は市場ではないのです。というのは、 -トランザクションを採掘者が送信者にオファするサービスと捉えることには本質的魅力がありますが、 -実際は、採掘者が採り入れた全トランザクションは、ネットワーク内の全てのノードにおいて処理される必要があるため、 -トランザクション実行のための大きなコストはサードパーティによって担われ、 -あるトランザクションを取り入れるかどうかの決定は採掘者に担われている訳ではないのです。 -このような仕組みでは、コモンズの悲劇の問題が発生する確率が非常に高いのです。 - -市場原理に基づくメカニズムにおけるこの欠陥が明るみにでましたが、 -ある特定の厳密でないシンプルな仮定のもとで、その欠陥を手品のようにキャンセルすることができます。 -論拠は以下のようなものです。 - -1. `k`個のオペレーションを含むトランザクションに対して、送信者がそのオペレーションを含める採掘者に対して`kR`の報酬をオファーする。ここで、`R`は送信者によって決定され、`k`と`R`は採掘者に対しておおよその値が事前に分かるようにする。 -2. 一つのオペレーションはどのノードにとっても`C`という実行コストを持つ(すなわち、すべてのノードは同じ効率をもつ) -3. `N`個のマイニングノードが存在するとき、それぞれは全く同じ処理能力を持っている(すなわち `1/N`である) -4. 採掘をしない フルノード は存在しない - -採掘者は、期待できる報酬がコストより大きければ、トランザクションを喜んで処理します。 -そして、採掘者が次のブロックを見つける確率は`1/N`なので、予想される報酬は `kR/N`となり、 -採掘者にとっての処理コストは`kC`だけです。 -このように考えると、採掘者は `kR/N > kC` つまり `R > NC`の時、トランザクションを取り込みます。 -ここで、`R`は送信者がオペレーション処理の前に支払う手数料で、 -送信者がトランザクション送信による利益を享受するのに必要な最低料金となります。 -NCはオペレーションを処理するためのネットワーク全体のコストであり、 -よって、採掘者は、実利のトータルがコストを超えるトランザクションだけを取り入れようとします。 - -しかし、実際の仮定では、いくつか重要な逸脱が生じます。 - -1. 採掘者は実際には他の検証ノードよりもトランザクション処理に高いコストを払う事があります。それは、追加の検証時間がブロックの伝搬を遅らせ、ブロックが無効になる可能性が増加するためです。 -2. 採掘を全くしないフルノードが存在します。 -3. 現実には採掘能力の分散は非常に不平等なものとなります。 -4. 投機家、政敵、ネットワークの存在に対して攻撃を仕掛ける道具をもった狂人が存在しまう。彼らは頭が良く、contract において、自分たちのコストが他の検証ノードが払うコストよりもかなり低いような環境を設定します。 - -(1)は採掘者が少ししかトランザクションを取り込まない傾向を生み出してしまいます。 -(2)は`NC`を増加させます。よって、(1)と(2)は、少なくとも互いに部分的にキャンセルします。 -(3)(4)は重要な問題です。これらの問題を解決する方法としては、単純に上限を設定しました。 -どのブロックも`BLK_LIMIT_FACTOR`回 x `長期指数関数移動平均` 以上のオペレーションを行うことはできません。 -つまり、 - - blk.oplimit = floor((blk.parent.oplimit * (EMAFACTOR - 1) + floor(parent.opcount * BLK_LIMIT_FACTOR)) / EMA_FACTOR) - -`BLK_LIMIT_FACTOR` と `EMA_FACTOR` は、当分は、65536と1.5に設定される定数で、さらに解析が進めば、変更される可能性があります。 - -Bitcoin に見られる大きなブロックを推奨しない別の理由として、 -大きなブロックは伝播するのに、時間がかかります。 -そして、このように、高確率で新鮮でないものとなってしまいます。 -Ethereum においては、ガス消費量の大きいブロックも同様に伝播するのに時間がかかります。 -それには、物理的に大きいトランザクションの状態遷移を検証するのに時間が掛かるという双方の理由があります。 -この遅延に対すす非推奨はBitcoin においては重要な問題ですが、 -Ethereum においては、GHOST プロトコルのおかげでそれほど問題ではありません。 -このように、ブロックを規制することにより、より安定した基盤工程ができあがります。 - - -### 計算 と チューリング完全 - -Ethereum 仮想マシン が チューリング完全 だというのはとても重要なことです。 -これは、EVMコード が無限ループを含む計算もコード化できることを意味します。 -EVMコード は二つの方法でループを可能にします。 -第一に、 -`JUMP` 命令はプログラムにコードの以前のどこか指定した場所へジャンプします。 -`JUMPI`命令は`while x<27; x= x*2`のような条件分岐を可能にします。 -第二に contract は別の contract を呼ぶ事ができ、 -潜在的に再帰によりループが可能となります。 -この方法では当然問題に行き当たります。 -悪意をもったユーザは、無限ループに陥らせる事で採掘者を黙らせ、フルノードをダウンさせることができるのか?という問題で、 -これは、コンピュータサイエンスの「実行停止問題」として知られる問題を浮かび上がらせます。 -実行停止問題とは、一般的に与えられたプログラムがいつまでも停止しないかどうかを知る方法が無いというものです。 - -"状態遷移の章" で説明したように我々の解決方法は、 -トランザクションに対し、許される最大の計算ステップ数を設定し、もし実行が長引けば計算を元に戻し、費用だけを支払うといったもので、 -メッセージも同じ方法をとります。 -我々がこの解法を選んだ動機を理解するために、以下のような例を考えてみましょう。 - -* 攻撃者が、無限ループを引き起こす contract を作り、採掘者に対してそのループを引き起こすトランザクションを送信します。 -採掘者はトランザクションを実行し、無限ループを実行し、そして燃料が切れるのを待ちます。実行は燃料切れになり、途中で止まりますが、トランザクションはまだ有効であり、採掘者は各実行ステップのための手数料を攻撃者に要求し続けています。 -* 攻撃者は非常に長い無限ループを作り、数ブロックが認証されるほどの時間、採掘者を計算させ続け、採掘者がトランザクションを含めて手数料を要求することを不可能にさせます。しかし、攻撃者は計算ステップ数の上限を決める`STARTGAS`の値を提供する必要があるので、採掘者は計算が非常に大きなステップ数であることを前もって知ります。 -* 攻撃者は `send(A,contract.storage[A]); contract.storage[A] = 0` のようなコードを持った contract を見て、最初のステップのみ実行できて二番目のステップは実行できないような量の燃料を持ったトランザクションを送付します。 -(つまり、引き出しはするが差額を減らさせない)。contract の作者はそのような攻撃に対する防御を考える必要はない。なぜならば、実行が途中で終わる時には状態の変化は元に戻ります。 -* ある金融 contract がリスクを減らすために9つの固有のデータフィードの中央値をとるとします。DAO の章で説明したような、呼出アドレスを変数化するメカニズム を通して変更可能な設計をされている一つのデータフィードを攻撃者は乗っ取り、無限ループを引き起こすように変更し、金融 contract から資金を要求するものを燃料切れにしていきます。しかしながら、金融 contract は、メッセージ上で燃料の上限を設定できるので、このような問題は防ぐ事ができます。 - - -チューリング完全 に取って代わるものは、チューリング不完全 です。`JUMP` や `JUMPI` 命令は存在せず、 -コールスタックにはそれぞれの contract の一つだけのコピーが存在できます。 -このシステムではこれまでに述べた手数料システムや我々の解決策の効果についての不確実性は必要なくなります。 -なぜなら contract を実行するコストはそのサイズによって上限が決まるからです。 -さらに、チューリング不完全 はそれほど大きな制約ではありません。 -というのは、我々が内部で想像した全ての contract の例で、一つのみがループを必要とし、 -さらにそのループはコードを26回繰り返す事によって取り除くことができました。 -チューリング完全 のもたらす厳しさや限定された利益を考えた時、 -何故チューリング不完全な言語を使用しないのでしょうか? -しかし実際は、チューリング不完全では、与えられた問題の正しい解決からはほど遠いものです。 -その理由を知るために、以下のcontractを考えましょう。 - - C0: call(C1); call(C1); - C1: call(C2); call(C2); - C2: call(C3); call(C3); - ... - C49: call(C50); call(C50); - C50: (run one step of a program and record the change in storage) - -いまあるトランザクションをAに送ります。 -このように、51個のトランザクションにおいて、250 の計算ステップを持つ contract を保持するものとします。 -採掘者はそれぞれの contract に付随する、 -最大の計算ステップ数や、contract が呼出す contract を前もって見る事によって -そのような論理爆弾を事前に察知することが可能ですが、これには、採掘者が他の contract を作り出す contract を禁止する必要が有ります。 -(なぜなら、上記の 51 個の contract の生成と実行は簡単に一つの contract に書き記すことができるのです。) -他の問題となるポイントはメッセージのアドレスフィールドが変数であり、一般的に contract が呼出す他の contract を事前に理解することが不可能なことです。 -よって、我々は驚くべき結論を得ます。 -チューリング完全 では驚く程容易に管理でき、 -一方、チューリング不完全 では、チューリング完全と同じ機能を持たせようとすると、驚く程管理が難しくなります。 -そのような場合、チューリング完全にしない理由はありません。 - - -### 通貨 と 発行 - -Ethereum のネットワークは ether という、自身の組込型通貨を保持し、 -二つの主要レイヤを保持します。 -種々のデジタル資産の効率的交換と、さらに重要なものとして、 -トランザクション手数料の支払いのメカニズムを提供します。 -簡便性のためと将来の議論を避けるため Bitcoin における mBTC/uBTC/satoshi に関する現在の議論を参照してください。通貨単位は設定済みで以下の通りです。 - -* 1: wei -* 103: lovelace -* 106: babbage -* 109: shannon -* 1012: szabo -* 1015: finney -* 1018: ether - -これはドルとセント、あるいは BTC と satoshi のコンセプトの拡張であり、 -近い将来、ether は通常のトランザクションで使用され、finney はマイクロトランザクションで使用され、szabo と wei は手数料やプロトコル実装の技術討論で用いられると我々は予想しています。残りの単位は後に必要となるかもしれませんが、現在の所、クライアント・サイドの実装には含まれていません。 - -Ether 発行 のモデルは以下の通りとなります。 - -* Etherは1BTCあたり1000-2000 etherの価格で通貨販売でリリースされます。このメカニズムは Etehereum Organization の資金調達の目的と、Mastercoin や NXT のような成功した他の基盤を引き継ぎ開発するための支払い目的を意図しています。 -初期の購入者は大きなディスカウントを得る事ができます。販売で得られたBTCは、全て、開発者の給与や賞金、Etehreum や仮想通貨エコシステムの様々な利益、非利益プロジェクトへの投資に使用されます。 -* 0.099 x プリセール販売額 ( 60102216 ETH ) が、初期の貢献者へ報いるために Ethereum Organization へ与えられます。 -ブロック生成開始前にETH建てで経費は支払われ、残りは長期に保有されます。 -* 0.099 x プリセール販売額 が長期保存用として維持管理されます。 -* 0.26 x プリセール販売額 が一年あたり採掘者に割り当てられる総額で、永遠に提供されます。 - -| Group | At launch | After 1 year | After 5 years -| ------------- | ------------- |-------------| ----------- | -| Currency units | 1.198X | 1.458X | 2.498X | -| Purchasers | 83.5% | 68.6% | 40.0% | -| Reserve spent pre-sale | 8.26% | 6.79% | 3.96% | -| Reserve used post-sale | 8.26% | 6.79% | 3.96% | -| Miners | 0% | 17.8% | 52.0% | - - -**長期における供給成長率** - -![SPV in bitcoin](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/inflation.png) - -_線形的な通貨の発行に関わらず、しかしながら、Bitcoin のように長期的に供給成長率は零となる傾向がある_ - - -上記モデルにおける主要な二つの選択として、 -(1)基金プールの存在とその規模、 -(2)供給上限があるBitcoinと異なった永久に全供給量が増え続ける仕組み -が挙げられます。 -基金プールの存在に対する正当性は次のとおりです。 -もし基金プールが存在せず、 -同じインフレ率を提供するために線形発行量を0.217倍に減少させると、 -etherの全供給量は16.5%減り、一単位の価値は19.8%上昇します。 -この19.8%の不均衡を埋めるために、より多くのetherがセールで購入され、 -結果、1単位が以前と全く同じ価値を持つところで平衡を保ちます。 -組織は1.198倍のBTCを持ちますが、 -それは二つに分ける事ができます。 -オリジナルのBTCと追加の0.198倍のBTCです。 -このように考えると、基金プールを持たない状況は、基金プールがある状況と _厳密に等価_ ですが、 -一つだけ重要な違いがあります。 -組織は純粋にBTCを保持し、ether の価値を維持するインセンティブを持ちません。 - -永遠に線形的に全供給量が増えるモデルでは、Bitcoin で見られた一部に富の超過集中リスクを減らします。 -そして、現在を生きる個人と未来を生きる個人に対して公平な通貨獲得の機会を与えます。 -同時に、供給増加レートがゼロに向かうため、Etherを得て保持しようという強いインセンティブを与えます。 -不注意や死やその他の理由でコインは常に失われて行き、 -コインの損失は一年あたりの総供給量に対する割合でモデリングすることができ、 -全循環通貨供給量はゆっくりと年間発行量を損失率で割った値に近づいて行くということから上記の理論化を行っています。 -(すなわち、損失率が1%の場合、ひとたび供給量が26Xになったら、0.26Xが採掘され、0.26Xが毎年失われるところで均衡します)。 - -将来、Ethereum はセキュリティ向上のため proof of stake モデルに切り替える可能性が高く、発行需要量を0-0.05X/年の間に減らす考えがあります。Ethereum Organization が資金を失ったり他の理由で消失した場合に備えて、オープンな、 -「 social contract 」をあとに残す考えがあります。 -誰もが Ethereum の未来候補版を作成する権利があり、唯一の条件は ether の総額は、 -せいぜい `60102216 * (1.198 + 0.26 * n)` ( `n` : ブロック生成開始からの年数 ) に等しくなることです。 -クリエータは開発費用を捻出するために自由に -クラウドセールを行ったりあるいは、 -POS 上での供給拡大と最大許容供給拡大の間の差の一部あるいは全てを自由に使用することができます。 -socail contract に合致しない候補版のアップグレードが -準拠版として公正にフォークされる可能性もあります。 - - -### マイニング集中 - - -Bitcoin のマイニングアルゴリズムは、基本的に、採掘者にブロックヘッダの少しだけ変更したバージョンについて何百万回も繰り返してSHA256を演算をさせ、最終的に一つのノードがあるターゲット以下(現在は2192)のハッシュ値になることによって成立しています。しかしながら、このマイニングアルゴリズムは二つの中央集権化に対する脆弱性を持っています。一つは、マイニングのエコシステムがASIC(application-specific integrated circuits)に支配されるようになってきています。ASIC はマイニング専門にチップがデザインされているためビットコインマイニングのタスクに対して数千倍の効率を持っています。これはBitcoinのマイニングはもはや分散型ではなく、効率的に参加するためには数百万ドルが必要となり、平等主義を追求していないことを意味しています。第二に殆どのBitcoinマイナーはブロックの認証プロセスを実際には一人では行っていません。その代わりにブロックヘッダを見つけるための中央集権化されたマイニングプールに依存しています。こちらの問題はおそらくもっとひどいものです。この文章を書いている時で、トップ3のマイニングプールは直接的ではないですが、Bitcoinネットワークの約50%をコントロールしています。マイナーはもしマイニングプールや連立が51%アタックをしようとしたときに他のマイニングプールに移動できるのですが、それでも良くないものです。 - -現在 Ethereum が使用しようとしているアルゴリズムは採掘者が「 状態 」から ランダムなデータ を生み出し、 -ブロックチェインの最後のNブロックからランダムに選ばれたトランザクションを計算し、結果のハッシュを返すというものです。これは二つの重要な利点があります。第一に、Etehreum の contract はどのような種類の演算も取り込む事ができます、つまりEtehreum用のASICを開発するとしたら、本質的にどのような演算も早いASIC ー それはすなわち、より良いCPUということになります。第二に、マイニングにおいてブロックチェイン全体にアクセスすることが必要になり、マイナーにブロックチェイン全体を保持することと、少なくとも全てのトランザクションを検証できるということを要求する事になります。これは中央集権化したマイニングプールの必要性を取り除くことになります;マイニングプールは報酬の分配のランダムさを平等にする、正当な役割を果たす事はできますが、この機能はP2Pプールによって中央集権無しに実現できます。 - -このモデルはまだテストされていません。そしてマイニングアルゴリズムとしてcontractの実行をさせる時に、賢く最適化を利用されることを避ける難しさがあると思われます。しかしながら、このアルゴリズムの面白い特徴は非常に大きな数のcontractを、特にあるASICの妨害をするように設計して、ブロックチェインに入れることで誰でも井戸に毒を盛る事ができるということです。ASIC 製造者にはお互いにそのようなトリックを使って攻撃する経済的なインセンティブが存在します。よって、我々が開発中のソリューションは純粋なテクニカルなものというよりも究極の経済的なヒューマンソリューションとなります。 - - - -### スケーラビリティ - - -Ethereum に関する大勢の関心の一つは スケーラビリティ です。 -Bitcoin のように Etehreum はすべてのトランザクションがネットワーク上の全てのノードで実行される必要があるという欠点があります。 -Bitcoin では現在のブロックチェインは約15GBであり、一時間あたり1MB増加しています。 -もし Bitcoin ネットワークが Visa のように一秒当たり 2000 トランザクション を処理する場合、 -3秒当たり1MB(1時間あたり1GB, 一年当たり8TB)もの増加をすることになります。 -Etehreum も同じような成長パターンに苦しむことになります。 -さらに悪い事には、単なる貨幣として使用されているBitcoinと異なり、 -Ethereum のブロックチェインは様々なアプリケーションが実行されることになります。 -しかし、Ethereum のフルノードはブロックチェインの履歴全てではなく、状態だけを保持すれば良いという事実が良い方向に働くでしょう。 - - -このような巨大なブロックチェインのサイズには中央集約化リスクが存在します。 -仮にブロックチェインのサイズが100TBになったとします。 -そのとき、もっともあり得るシナリオは非常に少ない数の巨大なビジネス組織のみがフルノードを動作させており、通常のユーザーは皆ライトSPVノードを使っているというものです。そのような状態では、なんらかの利益のためにお互いが手を組んでずるをして合意するという潜在的な危機が浮かび上がります(例えば、ブロックの報酬を変更して、彼らにBTCを与える)。ライトノードはこれを即座に見つけ出す方法を持っていません。もちろん少なくとも一つの誠実なフルノードが存在しているでしょう、そして、欠陥についての情報が数時間のちにRedditのようなチャンネルを通してじわじわ広まったとして、そのタイミングではもう遅すぎます:与えられたブロック -をブラックリスト化する努力を計画するかは一般ユーザに委ねられ、またうまく出来た51%アタックを抜き出すのと同じ規模の、巨大でおそらく不可能な整合作業となるでしょう。Bitcoin の場合、このことは現在問題になっています。しかし[Peter Todd の提案](http://sourceforge.net/p/bitcoin/mailman/message/31709140/)がこの問題を緩和するでしょう。 - - -近い将来、Ethereum はこの問題に取り組むために二つの戦略を追加する予定です。 -第一に、ブロックチェインベースのマイニングアルゴリズムのために、 -すくなくとも全てのマイナーがフルノードである必要があり、 -フルノードの数の下限を作ります。 -第二に、これはさらに重要なのですが、 -それぞれのトランザクションを処理した後にブロックチェイン内部に中間状態木のルートを含めます。 -もしブロック認証が中央集権化してしまったとしても、一つの正直な認証ノードが存在している限り、 -中央集権問題は認証プロトコルによって避ける事が可能です。 -もし、採掘者が有効でないブロックを提供した場合、 -そのブロックはフォーマットが間違っているか、 -もしくは状態`S[n]`が正しくないかです。 -`S[0]`は正しい事が分かっているので、どこかに`S[i-1]`は正しいが、`S[i]`は正しくないという最初の状態が存在します。検証ノードは `APPLY(S[i-1],TX[i]) -> S[i]` を実行するのに必要なパトリシアツリーのノードの部分木による誤りの検証プロセスによって、index `i`を見つけます。ノードはこれらのノードを演算の一部として実行し、与えられた`S[i]`と異なる`S[i]`を見つけます。 - - -他のより洗練された攻撃として、 -悪意のある採掘者が不完全なブロックを提出することで、 -ブロックが有効かどうかの決定に際し、完全な情報不足状態をつくることができます。 -この攻撃に対する解決策は challenge-response プロトコルです。 -検証ノードは、該当トランザクション索引 の形式で「 challenge 」を発行し、 -ひとつのノードを受け取った 軽量ノードは、 -採掘者あるいは検証者が、有効性の証明としてパトリシアノードの部分木を送るまでブロックを信用できないものとして扱います。 - - -## 結論 - - -Ethereum のプロトコルは元々、暗号通貨のアップグレード版で、ブロックチェイン上のエスクローや、引き出しの上限、金融contract、ギャンブルマーケットのような先進的な特徴を、高度一般化したプログラミング言語を通して提供するものだと考えられてきました。 -Ethereum のプロトコルはどんなアプリケーションも直接にはサポートせず、チューリング完全なプログラミング言語のみが存在します。 -それは、理論的にはどんなトランザクションタイプやアプリケーションのための任意の contract を作る事ができるということです。 -しかし、Ethereum について、さらに興味深い事は、Ethereum のプロトコルは単なる通貨を超えているということです。 -分散型ファイルストレージ、分散型コンピューティング、分散型市場予想や、その他多数の概念のプロトコルは、 -コンピュータ業界の効率の増加とともに本質的な潜在性が開花するものと思われますが、 -最初は経済のレイヤーでP2Pプロトコルを加速しました。 -最終的には、通貨と全く関係のない沢山の本質的なアプリケーションの可能性が広がっています。 - - -Ethereum のプロトコルによって実装されている任意の状態遷移関数のコンセプトはユニークな潜在性をもった基盤です。 -閉じた単一の目的である、データストレージや、賭博、金融アプリケーション用のプロトコルと異なり、 -Ethereum は非常にオープンな設計です。 -我々は数年で、金融や非金融の両方のプロトコルにおいて、 -多数の基礎レイヤーとして使われる事になると信じています。 - -# 脚注 及び 参考文献 - -#### 脚注 - -1. 洗練された読者は Bitcoin のアドレスは公開鍵そのものでは無く、 -楕円曲線公開鍵のハッシュであることに気がつくでしょう。 -しかしながら、じつのところ、暗号用語は公開鍵そのものとして公開鍵ハッシュを扱っても成立します。 -これは Bitcoin の暗号がカスタムなデジタル署名アルゴリズムと考えることが可能で、 -そこでは公開鍵は ECC 公開鍵 のハッシュで構成されており、 -署名はECC公開鍵をECC署名と重ねたもので構成されており、 -認証アルゴリズムは署名の中のECC公開鍵が公開鍵として与えられているECC公開鍵ハッシュに対して正しいかチェックすることを含んでおり、 -よって、ECC 署名 が ECC 公開鍵 に対して正しいかのチェックになっているからです。 -2. 技術的には、11個前までのブロックの中央値です。 -3. 内部的には 2 も "CHARLIE" も両方とも番号です。 -後者は ビッグエンディアンの256ビットベース の表現です。番号は最小で 0 、最大で 2256-1 を取る事ができます。 - - -#### 参考文献 - -1. Intrinsic value: http://bitcoinmagazine.com/8640/an-exploration-of-intrinsic-value-what-it-is-why-bitcoin-doesnt-have-it-and-why-bitcoin-does-have-it/ -2. Smart property: https://en.bitcoin.it/wiki/Smart_Property -3. Smart contracts: https://en.bitcoin.it/wiki/Contracts -4. B-money: http://www.weidai.com/bmoney.txt -5. Reusable proofs of work: http://www.finney.org/~hal/rpow/ -6. Secure property titles with owner authority: http://szabo.best.vwh.net/securetitle.html -7. Bitcoin whitepaper: http://bitcoin.org/bitcoin.pdf -8. Namecoin: https://namecoin.org/ -9. Zooko's triangle: http://en.wikipedia.org/wiki/Zooko's_triangle -10. Colored coins whitepaper: https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit -11. Mastercoin whitepaper: https://github.com/mastercoin-MSC/spec -12. Decentralized autonomous corporations, Bitcoin Magazine: http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/ -13. Simplified payment verification: https://en.bitcoin.it/wiki/Scalability#Simplifiedpaymentverification -14. Merkle trees: http://en.wikipedia.org/wiki/Merkle_tree -15. Patricia trees: http://en.wikipedia.org/wiki/Patricia_tree -16. GHOST: http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf -17. StorJ and Autonomous Agents, Jeff Garzik: http://garzikrants.blogspot.ca/2013/01/storj-and-bitcoin-autonomous-agents.html -18. Mike Hearn on Smart Property at Turing Festival: http://www.youtube.com/watch?v=Pu4PAMFPo5Y -19. Ethereum RLP: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP -20. Ethereum Merkle Patricia trees: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree -21. Peter Todd on Merkle sum trees: http://sourceforge.net/p/bitcoin/mailman/message/31709140/ diff --git a/pages/other-languages/[korean]-white-paper.md b/pages/other-languages/[korean]-white-paper.md deleted file mode 100644 index 791729d08..000000000 --- a/pages/other-languages/[korean]-white-paper.md +++ /dev/null @@ -1,553 +0,0 @@ ---- -name: White Paper -category: ---- - -### 차세대 스마트 컨트랙트와 탈중앙화된 어플리케이션 플랫폼 -(A Next-Generation Smart Contract and Decentralized Application Platform) - -사토시 나카모토가 2009년 개발한 비트코인은 종종 화폐와 통화분야에서 매우 근본적인 혁신으로 묘사되어 왔는데, 이것은 비트코인이 어떤 담보나 내재적인 가치를 가지지 않으며 중앙화된 발행기관이나 통제기관도 없는 디지털 자산의 첫번째 사례였기 때문이다. 하지만 비트코인 실험의 더욱 중요한 측면은 비트코인을 떠받치고 있는 분산합의수단으로서의 블록체인 기술이며, 이에 대한 관심이 급격하게 늘어나고 있다. - -블록체인 기술을 이용한 대안적 어플리케이션들에는 다음과 같은 것들이 자주 거론되고 있다. 사용자 정의 화폐와 금융상품을 블록체인 위에 표현하는 컬러드 코인("colored coins"), 물리적 대상의 소유권을 표현하는 스마트 자산("smart property"), 도메인 이름과 같은 비동질적 자산을 기록하는 네임코인("Namecoin"), 임의적인 계약규칙을 구현한 코드에 의해 다지털 자산을 관리하는 좀 더 복잡한 형태의 스마트 컨트랙트 ("smart contracts"), 더 나아가 블록체인을 기반으로 한 탈중앙화된 자율 조직( "decentralized autonomous organizations" , DAOs) 등이다. - -이더리움이 제공하려는 것은 완벽한 튜링완전(turing-complete) 프로그래밍 언어가 심어진 블록체인이다. 이 프로그래밍 언어는, 코딩된 규칙에 따라 '어떤 상태'를 다르게 변환시키는 기능(arbitrary state transition functions)이 포함된 "계약(contracts)"을 유저들이 작성할 수 있게 함으로써 앞서 설명한 시스템들을 구현 가능하게 할 뿐만 아니라 우리가 아직 상상하지 못한 다른 많은 어플리케이션도 매우 쉽게 만들 수 있도록 도와줄 것이다. - -### 목차 - -* [역사](#%EC%97%AD%EC%82%AChistory) - * [상태변환시스템으로서의 비트코인](#%EC%83%81%ED%83%9C%EB%B3%80%ED%99%98%EC%8B%9C%EC%8A%A4%ED%85%9C%EC%9C%BC%EB%A1%9C%EC%84%9C%EC%9D%98-%EB%B9%84%ED%8A%B8%EC%BD%94%EC%9D%B8bitcoin-as-a-state-transition-system) - * [채굴](#%EC%B1%84%EA%B5%B4) - * [머클트리](##%EB%A8%B8%ED%81%B4%ED%8A%B8%EB%A6%AC) - * [블록체인 사용한 다른 사용사례](#%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8-%EA%B8%B0%EC%88%A0%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EB%8B%A4%EB%A5%B8-%EC%9D%91%EC%9A%A9-%EC%82%AC%EB%A1%80-alternative-blockchain-applications) - * [스크립팅](#%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8C%85) -* [이더리움](#%EC%9D%B4%EB%8D%94%EB%A6%AC%EC%9B%80) - * [이더리움 어카운트](#%EC%96%B4%EB%8D%94%EB%A6%AC%EC%9B%80-%EC%96%B4%EC%B9%B4%EC%9A%B4%ED%8A%B8) - * [메시지와 트랜잭션](#%EB%A9%94%EC%8B%9C%EC%A7%80%EC%99%80-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98) - * [이더리움 상태변환함수](#%EC%9D%B4%EB%8D%94%EB%A6%AC%EC%9B%80-%EC%83%81%ED%83%9C-%EB%B3%80%ED%99%98-%ED%95%A8%EC%88%98ethereum-state-transition-function) - * [코드 실행](#%EC%BD%94%EB%93%9C-%EC%8B%A4%ED%96%89code-execution) - * [블럭체인과 채굴](#%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8%EA%B3%BC-%EC%B1%84%EA%B5%B4blockchain-and-mining) -* [어플리케이션들](#%EC%96%B4%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98applications) - * [토큰 시스템](#%ED%86%A0%ED%81%B0-%EC%8B%9C%EC%8A%A4%ED%85%9Ctoken-systems) - * [금융 파생상품](#%ED%8C%8C%EC%83%9D%EC%83%81%ED%92%88%EA%B3%BC-%EA%B0%80%EC%B9%98%EC%95%88%EC%A0%95%ED%86%B5%ED%99%94) - * [신원조회와 평판시스템](#%EC%8B%A0%EC%9B%90%EC%A1%B0%ED%9A%8C--%ED%8F%89%ED%8C%90-%EC%8B%9C%EC%8A%A4%ED%85%9Cidentity-and-reputation-systems) - * [탈중앙화된 파일 저장공간](#%EB%B6%84%EC%82%B0%ED%98%95-%ED%8C%8C%EC%9D%BC-%EC%A0%80%EC%9E%A5%EC%86%8Cdecentralized-file-storage) - * [탈중앙화된 자율 조직](#%ED%83%88%EC%A4%91%EC%95%99%ED%99%94%EB%90%9C-%EC%9E%90%EC%9C%A8%EC%A1%B0%EC%A7%81decentralized-autonomous-organizations) - * [추가적인 어플리케이션들](#%EC%B6%94%EA%B0%80%EC%A0%81%EC%9D%B8-%EC%96%B4%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98%EB%93%A4further-applications) -* [기타 이슈들](#%EA%B7%B8-%EB%B0%96%EC%9D%98-%EC%9D%B4%EC%8A%88%EB%93%A4) - * [수정된 GHOST 도입](#%EC%88%98%EC%A0%95%EB%90%9C-ghost-%EB%8F%84%EC%9E%85modified-ghost-implementation) - * [수수료](#%EC%88%98%EC%88%98%EB%A3%8C) - * [연산과 튜링완전성](#%EC%97%B0%EC%82%B0%EA%B3%BC-%ED%8A%9C%EB%A7%81%EC%99%84%EC%A0%84%EC%84%B1computation-and-turing-completeness) - * [통화와 발행](#%ED%86%B5%ED%99%94-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%EB%B0%9C%ED%96%89currency-and-issuance) - * [채굴 중앙집중화](#%EC%B1%84%EA%B5%B4-%EC%A4%91%EC%95%99%EC%A7%91%EC%A4%91%ED%99%94mining-centralization) - * [확장성](#%ED%99%95%EC%9E%A5%EC%84%B1scalability) -* [결론](#%EA%B2%B0%EB%A1%A0) -* [주석과 추가 자료](#%EC%A3%BC%EC%84%9D%EA%B3%BC-%EC%B6%94%EA%B0%80%EC%9E%90%EB%A3%8C) - -## 비트코인과 기존 개념들에 대한 소개(Introduction to Bitcoin and Existing Concepts) - -### 역사(History) - -분산화된 디지털 통화의 개념은, 재산등록 같은 대안 어플리케이션과 마찬가지로 지난 수십 년간 우리 주변에 있었다. 1980~90년대 익명 e-cash 프로토콜은 주로 ‘Chaumian blinding’으로 알려진 ‘로우레벨 암호 알고리즘(cryptographic primitive)’에 기반하였고 개인정보를 강력하게 보호하는 화폐를 제공하였으나 중앙집권적인 중개인에 의존했기 때문에 별다른 주목을 받지 못했다. 1998년 'Wei Dai'의 [b-money](http://www.weidai.com/bmoney.txt)는 분산 합의와 계산 퍼즐을 풀게 하는 방식을 통해서 화폐를 발행하게 하는 아이디어를 최초로 제안하였지만 분산 합의를 실제로 어떻게 구현할지에 대한 자세한 방법은 제시하지 못했다. 2005년에 'Hall Finney'는 "재사용 가능한 작업증명([reusable proofs of work](http://www.finney.org/~hal/rpow/))" 개념을 소개하였다. 이 시스템은 b-money의 아이디어에 Adam Back의 ‘계산 난이도 해시캐시 퍼즐(computationally difficult Hashcash puzzles)’을 조합한 것이었다. 그러나 외부의 신뢰를 필요로 하는 컴퓨팅(trusted computing)을 그 기반에 둠으로써, 이상을 구현하는데에는 또 다시 실패했다. 2009년 사토시 나카모토에 의해 처음 실제적으로 구현된 탈중앙화된 화폐는 공개키 암호방식을 통한 소유권 관리를 위해 사용되던 기존의 알고리즘을 ‘작업 증명(proof of work)’이라고 알려진 합의 알고리즘과 결합함으로써 가능하게 되었다. - -작업증명의 기반이 되는 작동방식은 매우 혁신적인 것이었는데, 이것은 두가지 문제를 동시에 해결하기 때문이다. 첫째, 이것은 간단하면서도 상당히 효과적인 합의 알고리즘을 제공해주었다. 즉, 네트워크 상에 있는 모든 노드들이 비트코인의 장부상태(state of the Bitcoin ledger)에 일어난 표준 업데이트의 집합(a set of canonical updates)에 공동으로 동의할 수 있도록 해주었다는 것이다. 둘째, 누구나 합의 프로세스에 참여할 수 있도록 허용해줌으로써 합의결정권에 대한 정치적 문제를 해결할 수 있을 뿐만 아니라 동시에 시빌공격(sybil attacks)도 방어해줄 수 있는 메커니즘을 제공했다. 이것은 합의 프로세스에 대한 참여의 조건으로 ‘특정한 리스트에 등록된 주체이어야만 한다’라는 어떤 형식적 장벽대신에, 경제적 장벽 - 각 노드의 결정권의 크기를 그 노드의 계산능력에 직접적으로 비례시키는 방식으로 대체하는 것이었다. - -이후로, 지분증명(proof of stake)이라는 새로운 방식의 합의 알고리즘이 등장했는데, 이는 각 노드가 가진 계산능력이 아니라 화폐의 보유량에 따라 각 노드의 결정권 정도를 계산해야 한다는 것이다. 이 두 방식의 상대적인 장점들에 대한 논의는 이 백서에서는 다루지 않겠지만, 두 방법 모두 암호화화폐의 기반으로서 사용될 수 있다는 점은 지적해두고자 한다. - -### 상태변환시스템으로서의 비트코인(Bitcoin As A State Transition System) - -![statetransition.png](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/statetransition.png) - -기술적인 관점에서 보았을 때, 비트코인과 같은 암호화 화폐의 장부는 하나의 상태변환시스템(state transition system)으로 생각해볼 수 있다. 이 시스템은, 현재 모든 비트코인의 소유권 현황으로 이루어진 하나의 “상태(state)” 와 이 현재 상태와 트랜잭션을 받아서 그 결과로써 새로운 상태를 출력해주는 “상태변환함수(state transition function)”로 구성되어 있다. 표준 은행 시스템에 비유하자면 상태는 모든 계좌잔고표(balance sheet)이고 트랜잭션은 A에서 B로 $X를 송금하라는 요청이며, 상태변환함수에 의해 A의 계좌에서는 $X가 감소하고 B의 계좌에서는 $X가 증가한다. 만약 처음에 A의 계좌에 있는 금액이 $X 이하인 경우에는 상태변환함수가 에러를 리턴한다. -이러한 상태변환를 비트코인 장부에서는 다음과 같이 정의할 수 있다. - - APPLY(S,TX) -> S' or ERROR - -은행 시스템 예시에서는 다음과 같다. - - APPLY({ Alice: $50, Bob: $50 },"send $20 from Alice to Bob") = { Alice: $30, Bob: $70 } - - APPLY({ Alice: $50, Bob: $50 },"send $70 from Alice to Bob") = ERROR - -비트코인에서 "상태(state)"는 생성되었지만 아직 사용되지 않은 모든 코인들의 집합(기술적표현으로는 '소비되지 않은 트랜잭션 출력', UTXO(Unspent Transaction Outputs))이다. 각 UTXO들에는 각자의 코인금액이 표시되어 있고 이 UTXO의 소유자(20byte의 주소로 정의되는 암호화된 공개키(public key)[1])정보가 들어 있다. 트랜잭션은 하나 이상의 입력(inputs) 및 출력을 포함한다. 각 입력에는 보내는 쪽 지갑주소에서 선택된 기존 UTXO에 대한 참조정보와, 해당지갑주소에 대응되는 개인키(private key)가 생성한 암호화된 서명을 담고 있다. 그리고 각 출력들은 상태에 추가될 새로운 UTXO정보를 가지고 있다. - -상태변환함수 `APPLY(S,TX) -> S'` 는 다음과 같이 정의할 수 있다. - -1. TX의 각 입력에 대해 : - * 만약 참조된 UTXO가 `S`에 없다면, 에러를 리턴. - * 만약 서명이 UTXO의 소유자와 매치되지 않으면, 에러를 리턴. -2. 만약 입력에 사용된 UTXO들 금액의 합이 출력 UTXO들 금액의 합보다 작으면, 에러를 리턴. -3. 입력에 사용된 UTXO가 삭제되고 출력 UTXO가 추가된 `S`를 리턴. - -여기서 1번의 첫번째 과정은 존재하지 않는 코인이 트랜잭션에 사용되는 것을 막기 위한 것이고 1번의 두번째 과정은 다른 사람의 코인이 트랜잭션에 사용되는 것을 막기 위한 것이다. 위 절차를 실제 비트코인 지불과정에 적용하면 다음과 같다. Alice가 Bob에게 11.7 BTC를 보내고 싶다고 가정하자. 먼저 Alice 지갑주소로부터 표시된 금액의 합이 적어도 11.7 BTC 이상인 UTXO의 집합을 찾는다. 실제 대부분의 경우에는 11.7 BTC를 정확히 바로 선택할 수 없다. Alice의 지갑주소에서 각각 6, 4, 2 BTC 가 표시된 3개의 UTXO를 참조할 수 있다고 하자. 이 3개의 UTXO가 트랜잭션의 input이 되고 2개의 output이 생성된다. Output 중 하나는 11.7 BTC가 표시된 새로운 UTXO이며 소유자는 Bob의 지갑주소가 된다. 그리고 다른 하나는 12(6+4+2) - 11.7 = 0.3 BTC의 "잔돈(change)"이 표시된 새로운 UTXO이며 소유자는 Alice 자신의 지갑주소가 된다. - -### 채굴 - -![block_picture.jpg](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/block.png) - -만일 우리가 위에서 기술한 내용을 신뢰를 기반으로 하는 중앙집권화된 서비스 방식으로 구현하자면 매우 간단한 일이 될텐데, 왜냐하면 중앙 서버 하드드라이브에 상태변화의 과정을 저장만 하면 되기 때문이다. 그러나 비트코인에서는, 탈중앙화된 통화시스템을 구축하고자 하는 것이며, 이를 위해서는 모든 사람이 수긍할 수 있는 트랜잭션 순서 합의 시스템을 상태변화시스템과 결합해야만 한다. 비트코인의 분산 합의 과정은 네트워크에 "블록(blocks)"이라 불리는 트랜잭션 패키지를 계속적으로 생성하고자 시도하는 노드들을 필요로 한다. 이 네트워크는 약 10분마다 하나의 블록을 생성하도록 계획되어 있고 각 블록은 타임스탬프, 논스(nonce), 이전 블록에 대한 참조(이전 블록의 해시), 그리고 이전 블록 이후에 발생한 모든 트랜잭션의 목록을 포함한다. 이 과정을 통해서 지속적으로 성장하는 블록체인이 생성되게 되는데, 비트코인 장부의 최신상태(state)를 나타내기 위해 지속적인 업데이트가 이루어진다. - -이 체계에서 하나의 블록이 유효한지 아닌지를 확인하기 위한 알고리즘은 다음과 같다. - -1. 이 블록에 의해 참조되는 이전 블록이 존재하는지, 유효한지 확인한다. -2. 타임스탬프 값이 이전 블록의 타임스탬프 값보다 크면서 2시간 이내인지 확인한다. -3. 작업증명(proof of work)이 유효한지 확인한다. -4. `S[0]`를 이전 블록의 마지막 상태(state)가 되도록 설정한다. -5. `TX`를 `n`개의 트랜잭션을 가지는, 블록의 트랜잭션 목록으로 가정한다. 폐구간 `0...n-1`의 모든 i에 대해, `S[i+1] = APPLY(S[i], TX[i])`집합 중 어느 하나라도 에러를 리턴하면 거짓(false)을 리턴하며 종료한다. -6. 참(true)을 리턴하고, `S[n]`를 이 블록의 마지막 상태로 등록한다. - -기본적으로 블록의 각 트랜잭션은 유효한 상태변환을 일으켜야 한다. 여기서 상태가 블록 내에 어떠한 방법으로로 기록되지 않았다는 점에 주목해보자. 상태는 유효성을 검증하는 노드가 매번 계산해서 기억해야 할 완전히 추상적 것(abstraction)인데, 이것은 원시상태(genesis state)부터 해당 블록까지의 모든 트랜잭션을 순차적으로 적용함으로써 계산될 수 있다. 채굴자가 블록에 포함시키는 트랜잭션의 순서에 주목해보자. 만약 어떤 블록에 A와 B라는 두 트랜잭션이 있고 B가 A의 출력 UTXO를 소비한다고 하자. 이때 A가 B이전의 트랜잭션인 경우 그 블록은 유효하지만, 그렇지 않을 경우 유효하지 않다. - -블록 유효성 검증 알고리즘에서 특징적인 부분은 "작업증명(proof of work)"의 조건 즉, 256 비트 숫자로 표현되는 각 블록의 이중-SHA256 해시값이 동적으로 조정되는 목표값(이더리움 영문 백서를 작성하는 시점에서 대략 2187)보다 반드시 작아야 된다는 조건이다. 작업증명의 목적은 블록 생성을 계산적으로 어렵게 만들어서 sybil 공격자들이 마음대로 전체 블록체인을 조작하는 것을 방지하는 것이다. SHA256은 전혀 예측불가능한 유사난수 함수(pseudorandom function)로 설계되었기 때문에 유효 블록을 생성하기 위한 유일한 방법은 블록헤더의 논스(nonce) 값을 계속해서 증가시키면서, 생성되는 새로운 해시값이 위의 조건을 만족하는지 확인하는 과정을 반복하는 것 뿐이다. -현재 목표값인 2187하에서 하나의 유효블록을 발견하기 위해서 평균적으로 264번의 시도를 해야만 한다. 일반적으로 이 목표값은 매 2016개의 블록마다 네트워크에 의해 재조정되어서 네트워크의 현재 노드들이 평균적으로 10분마다 새로운 블록을 생성할 수 있도록 한다. 이러한 연산작업에 대한 보상으로 현 시점의 각 블록의 채굴자들은 25 BTC를 획득할 자격을 가진다. 그리고 출력금액보다 입력금액이 큰 트랜잭션이 있다면 그 차액을 "트랜잭션 수수료(transaction fee)"로 얻는다. 이것이 BTC가 발행되는 유일한 방법이며, 원시상태(genesis state)에는 아무런 코인이 포함되지 않았다. - -채굴 목적을 더 잘 이해하기 위해서, 악의적인 공격자가 있을 때 어떤 일이 발생하는지 알아보자. 비트코인의 뼈대를 이루는 암호기법은 안전한 것으로 알려져 있다. 그러므로 공격자는 비트코인 시스템에서 암호기법에 의해 직접 보호되지 않는 부분인 '트랜잭션 순서'를 공격 목표로 잡을 것이다. 공격자의 전략은 매우 단순하다. - -1. 어떤 상품(가급적이면 바로 전달되는 디지털 상품)을 구매하기 위해 판매자에게 100 BTC를 지불한다. -2. 상품이 전송되기를 기다린다. -3. 판매자에게 지불한 것과 같은 100 BTC를 공격자 자신에게 보내는 트랜잭션을 생성한다.(이중지불 시도) -4. 비트코인 네트워크가, 공격자 자신에게 보내는 트랜잭션이 판매자에게 지불하는 트랜잭션보다 먼저 수행된 것으로 인식하도록 한다. - -1번 과정이 발생하고 몇 분 후에 몇몇 채굴자가 그 트랜잭션을 블록에 포함할 것이다. 이 블록 번호를 270000이라 하자. 대략 1시간 후에는 이 블록 다음의 체인에 5개의 블록들이 추가될 것이다. 이 5개의 블록들은 위 1번 트랜잭션을 간접적으로 가리킴으로써 "컨펌(confirming)"한다. 이 시점에서 판매자는 지불이 완료된 것으로 판단하고 상품을 전송할 것이다. 디지털 상품으로 가정했으므로 전송은 바로 끝난다. 이제 공격자는 판매자에게 보낸 것과 동일한 100 BTC를 공격자 자신에게 보내는 다른 트랜잭션을 생성한다. 만약 공격자가 그냥 단순하게 트랜잭션을 시도한다면, 채굴자들이 `APPLY(S,TX)`를 실행하고 이 `TX`는 상태에 더 이상 존재하지 않는 UTXO를 소비하려 한다는 것을 알아차리므로 이 트랜잭션은 진행되지 않는다. 그러므로 대신에, 같은 부모 블록 269999을 가리키지만 판매자에게 보낸 것을 대체하는 새로운 트랜잭션이 포함된 다른 버전의 블록 270000을 채굴함으로서 블록체인 "분기점(fork)"을 생성한다. 이 블록 정보는 원래 것과 다르므로 작업증명(proof of work)이 다시 수행되어야 한다. 그리고 공격자의 새버전 블록 270000은 기존 270000과 다른 해시를 가지므로 원래 블록 270001부터 270005는 공격자의 블록을 가리키지 않는다. 그러므로 원래 체인과 공격자의 새로운 체인은 완전히 분리된다. 이러한 분기점에서 비트코인 네트워크의 규칙은 가장 긴 블록체인을 참으로 인식하는 것이다. 공격자가 자신의 체인에서 혼자 작업을 하는 동안 정당한 채굴자들은 원래의 270005체인에서 작업할 것이기 때문에 공격자 자신의 체인을 가장 길게 만들기 위해서는 네트워크의 다른 노드들의 계산능력 조합보다 더 큰 계산능력을 가져야 한다.(이를 51% attack이라 한다.) - -### 머클트리 - -![SPV in bitcoin](https://raw.githubusercontent.com/ethereum/www/master-postsale/src/extras/gh_wiki/spv_bitcoin.png) - -_왼쪽: Merkle tree(머클트리)의 몇몇 노드만 보아도 곁가지(branch)의 유효성을 입증하기에 충분하다._ - -_오른쪽: Merkle tree의 어떤 부분을 바꾸려는 시도는 결국 상위 해시값 어딘가에 불일치를 만든다._ - -비트코인의 중요한 확장 기능은 블록이 여러 계층 구조(multi-layer data structure)에 저장된다는 것이다. 어떤 블록의 "해시(hash)"란 사실 블록헤더의 해시만을 의미한다. 이 블록헤더에는 타임스탬프, 논스(nonce), 이전 블록 해시, 그리고 블록에 포함된 모든 트랜잭션 정보에 의해 생성되는 머클트리(Merkle tree)의 루트 해시가 들어있는 200 바이트 정도의 데이터이다. 머클트리(Merkle tree)는 이진트리(binary tree)의 일종으로서 트리의 최하위에 위치하고 기저 데이터가 들어있는 수 많은 잎노드, 자기 자신 바로 하위에 있는 두 자식 노드의 해시로 구성된 중간 노드, 자기 자신 바로 하위에 있는 두 자식 중간노드의 해시로 구성된 트리의 "최상위(top)"에 있는 하나의 루트 노드의 집합이다. 머클트리(Merkle tree)의 목적은 어떤 블록의 데이터가 분리돼서 전달될 수 있도록 하는 것이다. 만약에 비트코인의 어떤 노드가 한 소스로부터 블록헤더만을 다운로드 받고, 이 블록헤더와 관계된 트랜잭션 정보는 다른 소스로부터 다운받아도 이 데이터들이 여전히 정확하다는 것이 보장된다. 이것이 가능한 이유는 Merkle tree에서 하위 노드들의 해시값이 상위 노드에 영향을 주기 때문에 어떤 악의적인 유저가 머클트리 최하위에 있는 트랜잭션 정보를 가짜로 바꿔치기 하면 상위 부모들의 해시값들이 변해서 결국 트리의 루트값이 바뀌므로, 결과적으로 이 블록의 해시가 달라지기 때문이다. 이렇게 되면 이 블록은 완전히 다른 블록으로 인식되게 되며, 이것은 유효하지 않은 작업증명을 가지고 있게 될 것이 분명하다. - -머클트리 프로토콜은 비트코인 네트워크를 장기간 지속가능하게 만드는 기초가 된다. 비트코인 네트워크에서 각 블록의 모든 정보를 저장하고 처리하는 "완전노드(full node)"는 2014년 4월 기준으로 거의 15 GB의 디스크 공간을 필요로 하며 매달 1 GB 넘게 증가하고 있다. 현재 데스크탑 컴퓨터 정도에서는 수용할 수 있지만 스마트폰에서는 불가능하다. 그리고 나중에는 소수의 사업체들이나 풀 노드를 유지할 수 있을 것이다. 반면 "단순화된 지불검증(simplified payment verification, SPV)"으로 알려진 프로토콜은 "가벼운 노드(light node)"라고 불리는 또 다른 형태의 노드를 가능하게 해준다. 가벼운 노드는 블록헤더를 다운로드하고 그 블록헤더에서 작업증명을 검증한다. 그리고 관련 트랜잭션들에 대한 "곁가지들(branches)"만을 다운로드 한다. 이렇게 전체 블록체인의 매우 작은 비율만을 다운로드 함에도 불구하고 강한 안전성을 보장하면서도, 임의의 트랜잭션의 상태 및 잔고 상태를 알아낼 수 있게 한다. - -### 블록체인 기술을 이용한 다른 응용 사례 (Alternative Blockchain Applications) - -블록체인의 근본 아이디어를 확장해 다른 개념으로 응용하려는 아이디어 역시 오랜 역사를 가지고 있다. 2005년 'Nick Szabo'는 "소유주 권한을 통한 재산권 보장"이라는 글을 발표했다. 그는 정주(homesteading), 불법점유, 지공주의(Georgism) 등의 개념을 포함한 정교한 틀을 설계해 누가 어떤 땅을 가지고 있느냐라는 등기 문제를 블록체인 기반 시스템으로 처리할 수 있음을 보였다. 그는 이것이 "데이터베이스 복제 기술의 새로운 발전"덕분에 가능해졌다고 말했다. 하지만, 불행히도 그 당시에는 쓸만한 효과적인 파일 복제 시스템이 없었기때문에 Nick Szabo의 프로토콜은 실현되지 못했다. 하지만 2009년 이후 비트코인 분권 합의 시스템이 발전하면서 수 많은 대안 응용 사례가 빠르게 부각되기 시작했다. - -* **네임코인** - 2010년에 만들어진 [네임코인](https://namecoin.org/)은 '탈중앙화된 명칭 등록 데이터베이스'라고 부르는 것이 가장 좋을 것이다. 토르, 비트코인, 비트메시지와 같은 탈중앙화된 자율조직 프로토콜을 이용할 때, 사용자는 타인과 서로 교류하기 위해 각자의 계정을 구분해내야 한다. 하지만 현존하는 가능한 구별 방법은 1LW79wp5ZBqaHW1jL5TCiBCrhQYtHagUWy와 같은 식의 의사난수 해쉬를 이용하는 방식이었다. 이상적으로는, 사용자가 "george"같은 일상적인 이름을 계정 이름으로 갖는 것이 좋겠지만 문제는 어떤 사용자가 "george" 라는 이름을 계정으로 만들 수 있다면, 다른 누구도 똑같이 "george"라는 계정을 등록해 흉내낼 수 있다는 점이다. 유일한 해답은 선출원주의로, 먼저 등록한 사람이 성공하고 두 번째 등록한 사람은 실패하도록 하는 것이다. 이는 이미 비트코인 합의 규약에 완벽히 적용된 문제이기도 하다. 네임코인은 이런 아이디어를 응용한 가장 오래되고 가장 성공적인 명칭 등록 시스템이다 - -* **컬러드 코인** - [컬러드 코인](https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit)의 목적은 누구나 비트코인 블록체인 위에서 자신만의 고유한 디지털 화폐를 발행할 수 있는 프로토콜 역할을 하는 것이다. 또는 (그 디지털 화폐의 발행량이 한 단위 밖에 없는 단순한 경우로 환원할 수 있는) 자기 자신만의 디지털 토큰을 발행하는 프로토콜 역할을 하는 것이다. 컬러드 코인 프로토콜에서, 사용자는 특정 비트코인 UTXO에 공개적으로 색깔을 부여함으로써 새 화폐를 "발행"할 수 있다. 다른 UTXO의 색깔은 이미 소비된(혼합 색깔 입력의 경우에는 몇몇 특별한 규칙이 적용된다) 것으로 간주하는 거래의 입력과 같은 색깔이 되도록 재귀적으로 정의한다. 이 프로토콜은 블록체인을 처음부터 끝까지 역추적해 그들이받은 UTXO의 색깔을 정함으로써, 사용자가 특정 색깔을 가진 UTXO만 지갑에 간직하고 그 코인을 보통 비트코인처럼 여기저기 보낼 수 있게 한다. - -* **메타코인** - 메타코인이 품고 있는 아이디어는, 비트코인 거래를 메타코인 거래 저장에 이용하되, 상태 이동 함수 APPLY' 를 다르게 가짐으로써, 비트코인 시스템 위에서 운영되는 프로토콜을 갖는 것이다. 메타코인 프로토콜만으로는 비트코인 블록체인 속에 무효 메타코인 거래가 나타나는 현상을 예방 수 없기 때문에, 규칙이 하나 더해진다. 즉 만약 APPLY'(S, TX)가 에러를 리턴하면, 프로토콜은 APPLY'(S,TX)=S로 정해진다. 비트코인 스스로는 내부 실행이 불가능한, 잠재적으로 더 발전된 성질을 가진 무작위 암호화폐 프로토콜을 만드는 쉬운 메커니즘이라고 할 수 있다. 반면 이 프로토콜의 개발비용은 적은데 왜냐하면 채굴과 네트워킹의 복잡성 문제가 이미 비트코인 프로토콜에 의해 처리되고 있기 때문이다. - -일반적으로 합의 프로토콜을 건설하는 데 두 가지 접근방법이 있다. 하나는 독립적인 네트워크를 세우는 것이고 다른 하나는 비트코인 시스템과 연동되는 프로토콜을 세우는 것이다. 전자의 접근 방법은 네임코인 같은 응용 사례에서는 상당히 성공적이었지만, 실제 실행하는 데 어려움이 있다; 각 개별 실행주체가 모든 필요한 상태변환과 네트워킹 코드를 건설하고 점검해야 할 뿐만 아니라 독립적인 블록체인을 구동시켜야 한다. 나아가, 분권 합의 기술에 관한 어플리케이션의 집합이 멱함수분포를 따를 것으로 예상된다. 즉, 대다수 어플리케이션은 자기 자신의 블록체인을 보장하기에는 너무 작을 것이다. 그리고 또 거대한 클래스의 분권화된 어플리케이션, 즉 서로 교류를 하기 위한 분권화된 자율 기구(DAO)가 생겨날 것이라고 예상한다. - -후자의 접근 방법, 즉, 비트코인에 기반한 접근 방법은 비트코인의 단순 지불 검증(SPV)특징을 물려받지 못한다는 단점이 있다. 단순지불검증은 비트코인에서는 작동한다. 왜냐하면 비트코인은 블록체인 깊이(depth)를 검증 대리 수단으로 이용할 수 있기 때문이다. 한 거래의 근원을 찾아 충분히 뒤로 돌아가보면, 그 상태의 정합성을 증명하는 부분이 있었다고 말해도 무방하다. 반면, 블록체인에 기반한 메타-프로토콜은 무효거래가 블록체인에 포함되지 않도록 막을 방법이 자기 자신의 프로토콜 자체에는 없다. 그렇기 때문에 완전히 안전보장이 된 단순지불검증 메타-프로토콜이라면, 어떤 거래가 유효한지 아닌지를 결정하기위해, 항상 비트코인 블록체인의 원점까지 돌아가 훑어보는 작업이 필요하다. 현재까지 비트코인에 기반한 메타-프로토콜의 모든 "간단한"(light) 클라이언트 구현은 자료를 제공하는 믿을 만한 서버에 의지하고 있는 형편이다. 우리가 암호화폐를 만든 가장 중요한 목적이 제3의 신용기구의 필요성을 없애는 것이었다는 걸 특히 되새겨본다면, 이것은 아주 분명하게도, 차선의 결과가 될 뿐이다. - -### 스크립팅 - -별도의 확장없이도 비트코인 프로토콜은 낮은 수준의 "스마트 계약"의 개념을 가능하게 할 수 있다. 비트코인의 UTXO는 공개키만으로 획득할 수 있을 뿐만 아니라, 단순 스택-기반 프로그래밍 언어로 표현되는 더 복잡한 스크립트로도 획득할 수 있다. 이런 경우에, UTXO를 지출하는 거래는 그 스크립트를 만족하는 데이터를 제공해야만 한다. 사실, 기초적인 공개키 소유권 메커니즘도 스크립트를 통해 실행된다: 그 스크립트는 타원곡선서명을 '입력'으로 받아 그 거래와 UTXO를 가진 주소에 대해 검증을 하고 만약 검증이 성공하면 1을, 실패하면 0을 '출력'한다. 여러 다른 다양한 사용 사례에 대해 좀 더 복잡한 여러 스크립트들이 있을 수 있다. - -예를 들어, 주어진 세 개의 개인 키 가운데 두 개로부터 서명을 받아야만 승인이 되도록 스크립트를 짤 수 있다. 이런 스크립트는 회사 계정, 보안 저축 계정, 상업 공탁 상황 등에 유용하게 쓰일 수 있다. 스크립트는 또한 어떤 계산 문제의 답에 대한 포상금을 지불하는데도 쓰일 수 있다. "만약 당신이 이 액면가의 도기코인 거래를 나에게 보냈다는 SPV 증명을 제공한다면, 이 비트코인 UTXO는 당신 것이다"라는 식으로 말하는 스크립트를 짤 수도 있다. 즉 근본적으로 탈중앙화된 상호-암호화폐 교환을 가능하게 한다. - -하지만 비트코인에 구현된 스크립트 언어는 몇가지 중요한 한계가 있다. - -* **튜링불완전성**: 비트코인 스크립트 언어로 할 수 있는 작업이 많긴 하지만, 모든 경우의 프로그래밍을 다 지원하지는 않는다. 특히 while이나 for와 같은 순환(loop) 명령 카테고리가 빠져 있다. 순환 명령어를 없앤 이유는 거래 증명을 할 때 무한 순환에 빠지는 것을 막기 위해서였다. 이론적으로는 튜링불완전성은 스크립트 프로그래머가 극복할 수 있는 장애물이기는 하다. 왜냐하면 어떤 순환 명령이든 단순히 하위 코드를 여러 차례 if 구문과 함께 반복함으로써 구현이 가능하기 때문이다. 하지만 이것은 아주 공간 비효율적인 프로그램이 된다. 예를 들어 대안 타원곡선서명 알고리즘을 실행하려면 코드 안에 있는 곱셈을 모두 개별적으로 256번 반복하는 것이 필요하다. - -* **가치무지하다**: UTXO 스크립트만으로는 인출 액수를 세밀하게 통제할 방법이 없다. 예를 들어 신탁 계약의 강력한 실용 사례라 할 수 있는 헷지 계약을 살펴보자. A와 B가 $1000어치의 BTC를 공동계좌에 입금했다고 하자. 시간이 지나면 비트코인의 가격이 오를 수가 있다. 두 사람은 30일 후 자동으로 A 가 $1000어치 BTC를 받고 B는 공동계좌의 나머지 잔액을 받는 그런 계약을 맺고 싶다. 하지만 이 계약은 1BTC가 미국 달러로 얼마인지 정해줄 제3자를 필요로 한다. 만약 이런 계약이 실현가능하다면 지금 현존하는 완전 중앙집권적인 금융 시스템 아래에서도 고도로 발전된 계약 형태라고 볼 수 있을 것이다. 하지만 UTXO는 인출액 전부가 송금되거나 말거나 밖에 선택할 수가 없다. 즉 세부 작은 단위로 나눠질 가능성을 포함할 수 없는 것이다. 위에 예를 든 계약 거래를 실행할 유일한 방법은 변하는 UTXO의 액면가 단위를 아주 다양하게 양산하고(예를 들어 1부터 30까지의 모든 자연수 k에 대해 2의 k승의 1 UTXO를 만듦) A가 B에게 이중에서 필요한 금액에 맞는 것을 선택해서 보내게 하는 방식과 같이 매우 비효율적인 편법을 사용하는 길 뿐이다. - -* **다양한 상태를 표현할 수 없다(Lack of State)**: UTXO가 표현할 수 있는 상태는 사용되었거나 안 되거나 둘 뿐이다. 그렇기 때문에 이 두가지 상태 이외에 다른 어떤 내부적 상태를 가지는 다중 단계 계약이나 스크립트를 만들 수가 없다. 이 점이 분산 환전 거래나 이중 암호 실행 프로토콜(계산 보상금을 보장하기 위해 필요하다)과 같은 다중 조건 계약을 어렵게 한다. 즉 UTXO은 단순하고 1회적인 계약에만 이용될 수 있을 뿐, 분산조직과 같은 더 복잡한 "상태적(stateful)" 계약에는 이용될 수 없고 메타프로토콜을 적용하기 어렵게 만든다. - -* **블록체인을 해독할 방법이 없다(Blockchain-blindness)**: UTXO는 논스(Nonce), 타임스탬프,이전 블록해시같은 블록체인 자료를 해독하지 못한다. 이 단점으로 인해 스크랩트 언어 속에 잠재적으로 가치있을 무작위성이 빠지게 된다. 그래서 도박이나 여러 다른 분야의 어플리케이션을 만드는 데 한계를 보인다. - -정리하자면, 발전된 어플리케이션을 만드는 데 3가지 접근법이 있다. 첫번째는 독립적인 블록체인을 만드는 것이고 두번째는 비트코인에 이미 내재된 스크립트를 이용하는 것이며, 세번째는 비트코인 상에서 작동되는 메타-규약을 건설하는 것이다. 독립적인 블록체을 쓰면 무한히 자유로운 프로그램을 짤 수 있지만 개발 기간, 초기 셋업 작업, 보안 등의 비용을 치뤄야 한다. 비트코인에 내재된 스크립트를 이용하면 실행이 간단하고 표준화된다는 장점이 있지만, 이용범위가 제한적이다. 메타규약을 쓰는 것은 간단하긴 하지만, 확장성의 결함을 감수해야 한다. -이더리움을 통해 우리는 개발하기도 쉽고 더 강력한 라이트 클라이언트 기능을 가지는 동시에 경제적인 개발 환경과 블록체인 보안을 공유하는 어플리케이션을 만들 수 있는, 대안 프레임워크(alternative framework)를 건설하려고 한다. - -## 이더리움 - -이더리움의 목적은 분산 어플리케이션 제작을 위한 대체 프로토콜을 만드는 것이다. 대규모 분산 어플리케이션에 유용할 것이라 생각되는 다른 종류의 제작기법을 제공하며, 빠른 개발 시간, 작고 드물게 사용되는 어플리케이션을 위한 보안, 다른 어플리케이션과의 효율적인 상호작용이 중요한 상황에 특히 주안점을 두고 있다. 이더리움은 튜링 완전 언어를 내장하고 있는 블록체인이라는 필수적이고 근본적인 기반을 제공함으로써 이 목적을 이루고자 한다. 누구든지 이 언어를 사용해 스마트 컨트랙트, 분산 어플리케이션을 작성하고 소유권에 대한 임의의 규칙, 트랜잭션 형식(transaction format), 상태변환 함수(state transition function) 등을 생성 할 수 있다. 네임코인의 기본적인 형태는 두 줄 정도의 코드로 작성할 수 있고, 통화나 평판 시스템 관련 프로토콜은 스무 줄 내외의 코드로 만들 수 있다. 어떤 값을 저장하고, 특정한 조건들을 만족했을 때만 그 값을 얻을 수 있게 하는 일종의 암호 상자인 스마트 컨트랙트 또한 이 플랫폼 위에 만들 수 있다. 이것은 비트코인의 스크립팅(scripting)이 제공하는 것보다 훨씬 강력한 기능들이 제공되기 때문에 가능한 것으로, 튜링-완전(Turing-completeness), 가치 인지능력(value-awareness), 블록체인 인지능력(blockchain-awareness), 상태(state)개념 등이 포함된다. - -### 이더리움 어카운트 - -이더리움에서, 상태(state)는 어카운트(account)라고 하는 오브젝트(object)들로 구성되어 있다. 각각의 어카운트는 20바이트의 주소와 어카운트 간 값과 정보를 직접적으로 전달해 주는 상태변환(state transition)을 가지고 있다. 이더리움 어카운트는 다음 네 개의 필드를 가지고 있다. - -* **논스(nonce)**: 각 트랜잭션이 오직 한번만 처리되게 하는 일종의 카운터 -* 어카운트의 현재 **이더(ether) 잔고** -* 어카운트의 **계약 코드** (존재한다면) -* 어카운트의 **저장 공간** (초기설정(default) 상에서는 비어있음) - -이더는 이더리움의 기본 내부 암호-연료(crypto-fuel) 이고, 트랜잭션 수수료를 지불하는데 사용된다. 보통 두가지 종류의 어카운트가 존재하는데, 프라이빗 키에 의해 통제되는 외부 소유 어카운트(Externally Owned Accounts)와 컨트랙트 코드에 의해 통제되는 컨트랙트 어카운트(Contract Accounts)가 있다. 외부 소유 어카운트는 아무런 코드도 가지고 있지 않으며, 이 어카운트에서 메시지를 보내기 위해서는 새로운 트랜잭션을 하나 만들고, 서명(signing)을 해야 한다. 컨트랙트 어카운트는 메시지를 받을 때마다, 자신의 코드를 활성화시키고, 이에 따라 메시지를 읽거나 내부 저장공간에 기록하고, 다른 메시지들을 보내거나, 컨트랙트들을 차례로 생성하게 된다. -이더리움에서 컨트랙트는, 수행되거나 컴파일 되어져야 할 어떤 것이라기 보다는, 이더리움의 실행 환경안에 살아있는 일종의 자율 에이전트(autonomous agents)로서, 메시지나 트랜잭션이 도착하면 항상 특정한 코드를 실행하고, 자신의 이더 잔고와, 영속적인 변수들을 추적하기 위해 자신의 키/값 저장소를 직접적으로 통제하는 역할을 한다. - -### 메시지와 트랜잭션 - -이더리움에서 사용되는 트랜잭션(transaction)이란 용어는 외부 소유 어카운트가 보낼 메시지를 가지고 있는 서명된 데이터 패키지를 말한다. 이 트랜잭션은 다음을 포함하고 있다. - -* 메시지 수신처 -* 발신처를 확인할 수 있는 서명 -* 발신처가 수신처로 보내는 이더의 양 -* 선택적(optional) 데이터 필드 -* STARTGAS 값, 트랜잭션 실행이 수행되도록 허용된 최대 계산 단계수 -* GASPRICE 값, 매 계산단계마다 발신처가 지불하는 수수료 - -처음 세 항목은 암호 화폐에서는 거의 표준처럼 사용되는 값이다. 데이터 필드는 초기값으로 설정된 기능(function)은 가지고 있지 않지만, 버추얼 머신(virtual machine)은 컨트랙트가 이 데이터에 접근할 때 사용할 수행코드(opcode)를 가지고 있다. 예를 들어, 블록체인 위에 도메인 등록 서비스로 기능하고 있는 컨트랙트가 있을 경우, 이 컨트랙트로 보내지는 데이터는 두개의 필드를 가지고 있는 것으로 해석할 수 있다. 첫번째 필드는 등록하고자 하는 도메인이고, 두번째 필드는 IP 주소이다. 컨트랙트는 메시지 데이터로부터 이 값들을 읽어서 저장소 내 적당한 위치에 저장한다. - -STARTGAS 와 GASPRICE 필드는 이더리움의 앤티-서비스거부(anti-DoS) 모델에 있어서 매우 중요한 역할을 한다. 코드내의 우연적이거나 악의적인 무한루프, 또는 계산 낭비를 방지하기 위해 각각의 트랜잭션은 사용할 수 있는 코드 실행의 계산 단계 수를 제한하도록 설정되어야 한다. 계산의 기본 단위는 gas이고 보통, 계산 단계는 1 gas의 비용이 소요되나, 어떤 연산은 더 비싼 계산 비용을 치루거나, 상태의 일부분으로 저장되어야 하는 데이터의 양이 많을 경우 더 많은 수의 gas 비용이 필요하게 된다. 또한 트랜잭션 데이터에 있는 모든 바이트는 바이트당 5 gas 의 수수료가 든다. 이러한 수수료 시스템의 의도는 어떤 공격자가 계산, 밴드위스, 저장소 등을 포함해 그들이 소비하는 모든 리소스에 비례하여 강제로 수수료를 지불하게 하는데 있다. 따라서, 이런 리소스중 어떤 것이라도 상당량을 소비하는 네트웍과 연관된 트랜잭션은 대략 증가분에 비례한 gas 수수료를 가지고 있어야 한다. - -### 메시지(Messages) -컨트랙트는 다른 컨트랙트에게 “메시지”를 전달할 수 있다. 메시지는 따로 저장될 필요가 없는 이더리움의 실행 환경에서만 존재하는 가상의 오브젝트이다. 메시지는 다음의 것을 포함하고 있다. - -* (암묵적으로) 메시지 발신처 -* 메시지 수신처 -* 메시지와 함께 전달되는 이더 -* 선택적 데이터 필드 -* STARTGAS 값 - -본질적으로, 메시지는 외부 실행자가 아닌 컨트랙트에 의해 생성된다는 것을 제외하면 트랜잭션과 유사하다. 현재 코드 수행을 하고 있는 컨트랙트가 메시지를 생성하고 실행하라는 CALL opcode를 만나게 되면 메시지를 생성한다. 트랜잭션과 마찬가지로, 메시지는 해당 코드를 실행하는 수신자 어카운트에 도달하게 된다. 따라서, 컨트랙트는 외부 실행자가 하는 것과 정확히 같은 방식으로 다른 컨트랙트와 관계를 맺을 수 있다. -트랜잭션이나 컨트랙트에 의해 할당된 gas 허용치는 그 트랜잭션과 모든 하위 실행에 의해 소모된 총 gas 에 적용된다. 예를 들어, 외부 실행자 A가 B에게 1000 gas와 함께 트랜잭션을 보내고, B는 600 gas를 소모한 뒤 C에게 메시지를 보내고, C의 내부 실행에 300 gas를 소모한 후 반환하면, B는 gas가 모두 소모되기 전에 100 gas를 더 사용할 수 있다. - - -### 이더리움 상태 변환 함수(Ethereum State Transition Function) - -![ethertransition.png](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/ethertransition.png) - -이더리움 상태 전이 함수 APPLY(S, TX) -> S’ 는 다음처럼 정의될 수 있다. -트랜잭션이 형식에 제대로 맞는지(즉, 올바른 갯수의 값을 가지고 있는지) 체크하고, 서명이 유효한지, 논스가 발신처 어카운트의 논스와 일치하는지를 체크한다. 그렇지 않다면 오류를 반환한다. -STARTGAS * GASPRICE 로 트랜잭션 수수료를 계산하고, 서명으로부터 발신처 주소를 결정한다. 발신처 어카운트 잔고에서 이 수수료를 빼고 발신자 논스를 증가시킨다. 발신처 잔고가 충분하지 않으면 오류를 반환한다. -GAS = STARTGAS 로 초기화 한후, 트랜잭션에서 사용된 바이트에 대한 값을 지불하기 위해 바이트당 gas의 특정양을 차감한다. -발신처 어카운트에서 수신처 어카운트로 트랜잭션 값을 보낸다. 수신처 어카운트가 존재하지 않으면 새로 생성한다. 수신처 어카운트가 컨트랙트이면, 컨트랙트의 코드를 끝까지, 또는 gas가 모두 소모될 때 까지 수행한다. -발신처가 충분한 ‘돈'을 가지고 있지 못해서 값 전송이 실패하거나, 코드 수행시 gas가 부족하면, 모든 상태 변경를 원상태로 돌려놓는다. 단, 수수료 지불은 제외되고, 이 수수료는 채굴자 어카운트에 더해지게 된다. -그 외에는, 모든 남아있는 모든 gas에 대한 수수료를 발신처에게 돌려주고, 소모된 gas에 지불된 수수료를 채굴자에게 보낸다. - -예를 들어, 다음과 같은 컨트랙트 코드를 가정해 보자. - - if !self.storage[calldataload(0)]: - self.storage[calldataload(0)] = calldataload(32) - -실제로 컨트랙트 코드는 로우-레벨 EVM 코드로 작성되나, 이 예제는 이해하기 쉽게 하기 위해, 이더리움 하이-레벨 언어중 하나인 Serpent 로 작성하였다. 이 코드는 EVM 코드로 컴파일 될 수 있다. 컨트랙트의 스토리지는 비어있다고 가정하고, 트랜잭션이 10 ether, 2000 gas, 0.001ether gasprice, 64 바이트의 데이터(0-31 바이트까지는 숫자 2를 나타내고, 32-63 바이트는 CHARLIE 라는 문자열)를 보낸다고 가정하자. 이 경우 상태 변환 함수의 프로세스는 다음과 같다. - -1. 트랜잭션이 유효하고 형식에 제대로 맞는지 확인한다. -2. 트랜잭션 발송처가 최소 2000 * 0.001=2 ether를 가지고 있는지 확인하고, 그럴 경우, 발송처의 어카운트에서 2 ether를 뺀다. -gas=2000으로 초기화 한 후, 트랜잭션은 170바이트 길이를 가지고, 바이트당 수수료는 5라고 가정하면, 850을 빼야 하고 결국 1150 gas가 남게된다. -3. 송신처 어카운트에서 추가 10 ether를 빼고 이것을 컨트랙트 어카운트에 더한다. -4. 코드를 실행시킨다. 이 경우는 간단한데, 컨트랙트의 index 2에 해당하는 스토리지가 사용되었는지 확인하고 (이 경우, 사용되지 않았다.) index 2에 해당하는 스토리지 값을 CHARLIE 로 설정한다. 이 작업에 187 gas 가 소비됐다고 가정하면, 남아있는 gas 의 양은 1150 - 187 = 963 이 된다. -5. 963*0.001 = 0.963 ether를 송신처의 어카운트로 되돌려주고, 결과 상태를 반환한다. - -트랜잭션의 수신처에 컨트랙트가 없으면, 총 트랜잭션 수수료는 제공된 GASPRICE와 트랜잭션의 바이트 수를 곱한 값과 같아지고, 트랜잭션과 함께 보내진 데이터는 관련이 없어지게 된다. - -메시지는 트랜잭션과 마찬가지 방식으로, 상태를 원래 상태로 되돌린다는 것에 주목하자. 메시지 실행시 gas가 부족하게 되면, 그 메시지 실행과 그 실행에 의해 촉발된 다른 모든 실행들은 원래대로 되돌려지게 되지만, 그 부모 실행은 되돌려질 필요가 없다. 이것은 컨트랙트가 다른 컨트랙트를 호출하는 것은 안전하다는 것을 의미한다. A가 G gas를 가지고 B를 호출하면, A의 실행은 최대 G gas만을 잃는다는 것을 보장받게 된다. 컨트랙트를 생성하는 CREATE라는 opcode를 보면, 실행 방식은 대체로 CALL과 유사하나, 실행 결과는 새로 생성된 컨트랙트의 코드를 결정한다는 차이가 있다. - -### 코드 실행(Code Execution) - -이더리움 컨트랙트를 구성하는 코드는 “이더리움 버추얼 머신 코드” 또는 “EVM 코드”로 불리는 로우-레벨, 스택 기반의 바이트코드 언어로 작성된다. 이 코드는 연속된 바이트로 구성되어 있고, 각각의 바이트는 연산(operation)을 나타낸다. 보통, 코드 실행은 0부터 시작하는 현재 프로그램 카운터를 하나씩 증가시키면서 반복적으로 연산을 수행하도록 구성된 무한 루프이고, 코드의 마지막에 도달하거나 오류, STOP, RETURN 명령을 만나면 실행을 멈추게 된다. 연산을 수행하기 위해서는 데이터를 저장하는 세가지 타입의 공간에 접근할 수 있어야 한다. - -* **스택**: last-in-first-out 컨테이너로 여기에 값들을 밀어 넣거나(push) 하거나 뺄(pop) 수 있다. -* **메모리**: 무한대로 확장 가능한 바이트 배열 -* 컨트랙트의 영속적인(long-term) **저장소(storage)**: 키/값 저장소. 계산이 끝나면 리셋되는 스택이나 메모리와는 달리 저장소는 영속적으로 유지된다. - -코드는 또한 블록 헤더 데이터 뿐만 아니라 특정 값이나, 발송자 및 수신되는 메시지의 데이터에 접근할 수 있고, 결과값으로 데이터의 바이트 배열을 반환할 수도 있다. - -EVM 코드의 공식 실행 모델은 놀랍도록 단순하다. 이더리움 버추얼 머신이 실행되는 동안, 모든 계산 상태는 (block_state, transaction, message, code, memory, stack, pc, gas) 튜플(tuple)로 정의될 수 있고, block_state는 모든 어카운트를 포함하는 전역상태(global state)로서 잔고와 저장소(storage)를 포함한다. 반복되는 매 코드 실행 순간의 시작시, code의 pc(프로그램 카운터)번째 바이트의 현재 명령이 실행되고, ( pc 가 코드의 길이보다 크면(pc >= len(code)) pc 는 0), 각각의 명령은 튜플을 어떻게 변화시킬지 대한 그 자신의 정의를 알고 있다. 예를 들어, ADD는 스택에서 두개의 아이템을 꺼내(pop), 그 합을 구한 후 다시 스택에 넣고(push) gas를 1만큼 감소시키고, pc는 1 증가시킨다. SSTORE 는 스택에서 두개의 아이템을 꺼내 이 아이템의 첫번째 값이 가리키는 컨트랙트 저장소 인덱스에 두번째 아이템을 넣는다. 이더리움 버추얼 머신 환경을 JIT 컴파일을 통해 최적화 하는 많은 방법이 있지만, 기본적인 이더리움은 수백줄의 코드로 구현될 수 있다. - -### 블록체인과 채굴(Blockchain and Mining) - -![apply_block_diagram.png](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/apply_block_diagram.png) - -이더리움 블록체인은 여러면에서 비트코인 블록체인과 유사하나, 어느정도 차이점들이 있다. 이더리움과 비트코인에서의 각 블록체인 구조에 대한 주요 차이점으로는 비트코인과는 달리 이더리움 블록은 트랜잭션 리스트와 가장 최근의 상태(state) 복사본을 가지고 있다는 것이다. 그것 외에도, 두개의 다른 값 - 블록 넘버와 difficulty - 이 또한 블록내에 저장된다. 기본적인 이더리움 블록 검증 알고리즘은 다음과 같다. - -1. 참조하고 있는 이전 블록이 존재하는지 그리고, 유효한지 확인한다. -2. 현재 블록의 타임스탬프가 참조하고 있는 이전 블록의 그것보다 크면서, 동시에 현 시점을 기준으로 15분 후보다 작은 값인지 확인한다. -3. 블록 넘버, difficulty, 트랜잭션 루트, 삼촌 루트, gas 리미트등(기타 다양한 이더리움 로우 레벨 개념)이 유효한지 확인한다. -4. 블록에 포함된 작업 증명이 유효한지 확인한다. -5. S[0] 이 이전 블록의 마지막 상태(state)라고 가정 하자. -6. TX를 현재 블록의 n개의 트랜잭션 리스트라고 하자. 0 부터 n-1에 대해, S[i+1] = APPLY(S[i], TX[i]) 로 설정하자. 어플리케이션이 오류를 반환하거나, 이 시점까지 블록에서 소모된 총 gas가 GASLIMIT를 초과하면 오류를 반환한다. -7. 채굴자에게 지불된 보상 블록을 S[n] 덧붙인 후 이것을 S_FINAL 이라 하자. -8. 상태 S_FINAL의 머클 트리 루트가 블록 헤더가 가지고 있는 최종 상태 루트와 같은지를 검증한다. 이 값이 같으면 그 블록은 유효한 블록이며, 다르면 유효하지 않은 것으로 판단한다. - -이러한 접근은 언뜻, 모든 상태를 각 블록에 저장할 필요성 때문에 매우 비효율적인 것처럼 보이지만, 실제로는 효율성의 측면에서는 비트코인과 비교할만 하다. 그 이유로는 상태가 트리 구조로 저장되고, 모든 블록 후에 단지 트리의 작은 부분만이 변경되기 때문이다. 보통, 인접한 두 개의 블록간에는 트리의 대부분의 내용이 같고, 따라서 한번 데이터가 저장되면 포인터(서브트리의 해쉬)를 사용하여 참조될 수 있다. 패트리시아 트리(Patricia tree)로 알려진 이러한 종류의 특별한 트리는 머클 트리 개념을 수정하여 노드를 단지 수정할 뿐만 아니라, 효율적으로 삽입되거나 삭제하여 이러한 작업을 수행할 수 있도록 해준다. 또한, 모든 상태 정보가 마지막 블록에 포함되어 있기 때문에, 전체 블록체인 히스토리를 모두 저장할 필요가 없어지게 된다. 이 방법을 비트코인에 적용한다면 5~20배의 저장 공간 절약의 효과가 생길 것이다. - -물리적인 하드웨어 관점에서 볼 때, 컨트랙트 코드는 “어디에서" 실행되는가 하는 의문이 쉽게 들 수 있다. 간단한 해답은 다음과 같다. 컨트랙트 코드를 실행하는 프로세스는 상태 전환 함수 정의의 한 부분이고, 이것은 블록 검증 알고리즘의 부분이다. 따라서, 트랜잭션이 블록 B에 포함되면 그 트랜잭션에 의해 발생할 코드의 실행은 현재 또는 향후에 블록 B 를 다운로드 하고 검증하는 모든 노드들에 의해 실행될 것이다. - -## 어플리케이션(Applications) - -기본적으로, 이더리움을 이용하여 총 세 가지 카테고리의 어플리케이션을 제작할 수 있다. 첫번째 카테고리는 돈과 직접적으로 연관된 컨트랙트를 계약참여자로 하여금 보다 강력하게 설정-관리하게끔 하는 금융 어플리케이션이다. 이의 예는 하위화폐(=유로/달러 등의 상위화폐와 환율이 연동된 화폐를 지칭), 파생상품, 헷지컨트랙트, 예금용 전자지갑, 유언장, 그리고 최종적으로는 전면적인 고용계약 수준의 것들까지 포함한다. 두번째 카테고리는 준(準)금융 어플리케이션이다. 금전이 관여되어 있지만, 상당부분 비(非)화폐적인 면이 존재하는 계약을 위한 어플리케이션이 이에 해당된다. 이의 좋은 예로는 어려운 연산 문제를 푸는 자에게 자동적으로 포상금이 지급되는 계약이다. 마지막으로, 온라인 투표와 분권형(分權形) 거버넌스(Governance)와 같이 금융과 관련성이 아예 없는 어플리케이션이 있다. - -### 토큰 시스템(Token Systems) - -블록체인토큰시스템(On-blockchain token system)은 미화/금 등과 연동된 하위화폐, 주식과 “스마트자산* (Smart Property: 비트코인의 블록체인 상에서 소유권이 컨트롤/관리되는 자산),” "위조불가능한(secure unforgeable)" 쿠폰, 그리고 통상적인 가치와 연결되어 있지 않은 기타 토큰시스템 (예, 인센티브 부여를 위한 포인트제도) 등에 이르기까지 다양한 형태의 거래시스템을 네트워크 상에서 구현하게끔 해주는 어플리케이션들을 갖고 있다. 이더리움에서 토큰시스템은 놀랍도록 쉽게 구현할 수 있다. 토큰시스템을 이해하는 데에 핵심은 아래와 같다. - -* 모든 화폐 혹은 토큰시스템은 근본은 결국 한 가지 오퍼레이션만을 수행하는 데이터베이스이다. -* A라는 주체로부터 X 단위의 화폐/토큰을 차감하고, 차감한 X 단위의 화폐/토큰을 B에게 지급한다. 단, -거래 전, A는 최소 X단위를 보유하고 있었음 -* A가 이 거래를 승인함 - -이더리움에서 유저는 바로 위의 로직을 컨트랙트에 반영 시키기만 하면 된다. -Serpent 에서 토큰시스템을 실행하는 기본적은 코드는 아래와 같다: - - def send(to, value): - if self.storage[msg.sender] >= value: - self.storage[msg.sender] = self.storage[msg.sender] - value - self.storage[to] = self.storage[to] + value - -이는 기본적으로 본 백서에서 설명한 “은행시스템”의 "상태변환함수(state transition function)"를 아무런 가공없이 그대로적용시킨 것이다. 통화의 단위를 정의하고 배급하기 위한 최초 작업을 위해서, 또는 더 나아가 여타 컨트랙트들이 계좌의 잔금에 대한 정보요청을 처리하기 위한, 몇 줄의 코드가 추가적으로 더 쓰여져야 할 수도 있다. 하지만, 그 정도가 토큰시스템을 만드는 데 필요한 전부이다. 이론적으로, 이더리움에 기반한 하위화폐 체계로서의 토큰시스템은 비트코인에 기반한 메타화폐 (=비트코인 블록체인 연동된 화폐)가 갖고 있지 않는 중요한 특성을 지니고 있을 수 있다: 거래비용을 거래 시 사용한 화폐로 직접 지불할 수 있다는 점이 그것이다. 다음과 같은 과정을 통하여 이 특성은 발현될 수 있다: 컨트랙트을 집행하기 위해서는 발송인에게 지불해야 하는 비용 만큼의 이더 잔고를 유지해야 한다. 그리고 컨트랙트 집행 시 수수료로 받는 내부화폐(하위화폐)를 (상시 돌아가고 있는 내부화폐-이더 거래소에서) 즉각 환전하여 이더 잔고로 충전할 수 있다. 유저들은 그렇게 이더로 그들의 계좌들을 “활성화”시켜야 하지만 각 컨트랙트를 통해 얻어지는 만큼의 금액을 이더로 매번 환전해 주기에, 한 번 충전된 이더는 재사용이 가능하다고 볼 수 있다. - -### 파생상품과 가치안정통화 - -파생상품은 “스마트 컨트랙트”의 가장 일반적인 어플리케이션이며, 코드로 실행할 수 있는 가장 간단한 형태의 어플리케이션 중 하나다. 금융 컨트랙트를 실행하는 데 가장 주된 어려움은 대부분의 경우 계약에서 규정하는 자산에 대한 시세를 외부에서 참조해야 한다는 것이다. 예를 들어, 금융컨트랙트에 매우 필요한 것은 이더(또는 기타 가상화폐)-USD 변동성에 대해 헷지(hedge)하는 어플리케이션인데, 이 헷지컨트랙트를 실행하기 위해서는 ETH/USD의 환율을 제공할 수 있는 컨트랙트가 필요하다. 환율을 알기 위한 가장 쉬운 방법은 주식시장의 NASDAQ과 같은 특정한 제 3자가 실시간으로 제공하는 “데이터피드” 컨트랙트를 통해서이고, 관여주체는 필요할 때 마다 환율을 업데이트할 수 있어야 하며, 여타 컨트랙트들과 환율에 대한 메시지를 주고받을 수 있는 인터페이스를 제공할 수 있어야 한다. - -상기 핵심 요건들을 가정하고, 위 언급한 헷지컨트랙트는 다음과 같은 구조를 띌 것이다: - -1. A가 1000 이더를 입금할 때까지 기다린다 -2. B가 1000 이더를 입금할 때까지 기다린다 -3. 입금된 이더의 달러가치를 기록하며 (환율은 Data feed 컨트랙트로 쿼리를 보냄으로써 계산한다), 이를 $X라 한다 -4. 30일 이후, 당시의 환율을 적용한 금액을 계산하여 A에게는 $X를 송금하고 당시 총금액에 나머지를 B에게 송금하도록 A 또는 B가 컨트랙트를 다시 활성화 시킬 수 있게끔 한다. - -위와 같은 컨트랙트는 가상통화를 이용한 상거래의 향후 발전 가능성을 제시한다. 가상화폐 상거래 활성화의 장애물 중 하나는 가상화폐의 높은 변동성이다; 다수의 유저들과 상인들은 가상화폐 혹은 블록체인자산이 제공하는 보안성과 편의성에 대한 니즈가 있지만, 단 하루만의 그들의 자산가치가 23% 하락할지도 모른다는 리스크는 피하고 싶어한다. 이 문제에 대한 지금까지의 가장 보편적인 솔루션은 자산 발행자가 자산에 대한 보증을 서는 것이었다: 이는 곧, 빌헹자가 하위화폐를 만들어서 그를 통해서 통화량을 조절할 수 있는 권한을 갖고, 누군가가 일정 단위의 하위화폐를 지불하였을 때 그에 상응하는 특정한 베이스 자산 (예, USD, 금)으로 교환해주는 방식을 뜻한다. 이 방식을 본 사례에 적용한다면, 가상화폐 발행자는 가상화폐를 지불하는 자에게 그에 상응하는 베이스자산을 제공할 것이라고 공개적인 약속을 하는 것이다. 이 메커니즘은 비(非)가상화폐 혹은 비(非)디지털자산을 블록체인 자산화(化)자산화 시키는 결과를 낳는다—물론 가상화폐 발행자를 신뢰할 수 있다면 말이다. - -다만, 현실적으로는 자산 발행인을 언제나 신뢰를 할 수 없으며, 몇몇 사례를 보면, 우리의 금융인프라는 자산보증 서비스가 존재하기에는 너무 취약하거나, 때로는 적대적이기도 하다. 파생상품은 이에 대한 대안을 제공해준다. 여기서 자산을 보증하기 위한 펀드를 제공하는 역활을 하나의 자산 발행자가 하는 것이 아니라 -암호화 담보자산(cryptographic reference asset, 예: 이더)의 가격이 올라갈 것이라는 데에 베팅을 하는 투자자들(speculators)의 탈중앙화된 시장이 그 역할을 담당하게 된다. -파생상품을 통한 보증 또한 완전하게 탈중앙화된 방법론은 아니라는 것을 주의하기 바란다. 비록 자산 발행자을 통한 방법 보다 진입장벽(영업허가증 등이 필요 없음)이 없고 사기/조작 가능성이 줄어들기는 하지만, 신뢰성있는 제 3기관이 USD/ETH 시세 또는 환율을 제공해야 하기 때문이다. - -### 신원조회 / 평판 시스템(Identity and Reputation Systems) - -최초의 알트코인(비트코인 이후에 생겨난 가상화폐)인 네임코인은 비트코인과 유사한 블록체인을 이용하여 사용자가 공공DB에 다른 데이터와 함께 본인의 이름을 등록하는 명의등록 시스템을 만들어냈다. 이의 주된 사용례는 “bitcoin.org”와 (Namecoin의 경우에는 “bitcoin.bit”) 도메인명을 매핑하는 DNS 시스템이다. 다른 사용례에는 이메일 인증, 그리고 보다 진일보된 평판 시스템 등이 있다. 이더리움에서 네임코인과 같은 명의등록 시스템의 기본적인 컨트랙트는 아래와 같은 형태를 띈다. - - def register(name, value): - if !self.storage[name]: - self.storage[name] = value - -이 컨트랙트는 매우 단순하게도, 이더리움 네트워크 안에서 저장되어 있는, 추가할 수는 있지만 수정하거나 지울 수 없는 데이터 베이스일 뿐이다. 누구든지 소량의 이더를 이용하여 본인의 명의를 등록할 수 있으며, 한 번 등록하면 영구적으로 보존된다. 보다 정교한 명의등록 컨트랙트는 다른 컨트랙트가 보내는 쿼리에 반응할 수 있는 함수조건이 걸려 있을 것으며, 명의 소유자 (곧, 최초 등록자)가 데이터를 변경하거나 명의소유권을 이전할 수 있는 메커니즘이 장착되어 있을 것이다. 혹자는 평판이나 인터넷신용도 기능등을 그 위에 추가할 수도 있다. - -### 분산형 파일 저장소(Decentralized File Storage) - -지난 몇년 동안, 드롭박스와 같은 웹 상에 파일을 저장시켜주는 인기있는 스타트업이 다수 생겨났다 (월 정액에 유저들이 하드드라이브를 백업 시켜 놓고 백업파일에 액세스 할 수 있는 비즈니스 모델임). 그러나, 현시점에서 파일저장 시장은 종종 상대적으로 비효율적일 때가 많다. [현재 존재하는 솔루션](http://online-storage-service-review.toptenreviews.com/)들의 월정액 가격을 보면 (특히 무료 할당량도 기업 할인도 없는 20-200기가바이트 수준의 기업이 지불하는 월정액), 한달만 써도 전체 하드드라이브의 비용보다 더 비쌀 정도이다. 이더리움의 컨트랙트는 분산형 파일 저장소 생태계의 발전을 가능케한다. 이 생태계에서 유저 개개인은 본인의 하드드라이브를 대여해주는 대가로 소액의 돈을 받을 수 있으며 남는 하드디스크 공간은 파일저장의 비용을 더욱 낮추는 결과를 낳을 것이다. -분산형 파일 저장소의 핵심 기반은, 소위 “분산형 드롭박스 컨트랙트”가 될 것이다. 이 컨트랙트는 다음과 같이 작동한다: 1) 유저가 업로드하려는 데이터를 블록으로 잘라내고, 2) 프라이버시를 위해 해당 데이터를 암호화 시킨 후, 3) 그 데이터로 머클트리를 만든다. 위 데이터에 대한 컨트랙트는 아래와 같은 룰에 의해서 유지된다. - -* N개의 블록 마다 무작위 방식으로 (컨트랙트 코드로 접근가능한 전 블록의 해쉬에 기반한 무작위 방식) 머클트리의 인덱스를 뽑는다. -* 유저가 올린 파일에 해당하는 트리의 특정 인덱스에 대하여, 해당 데이터를 저장해주겠다는 첫 주체에게 (간소화된 지불증명이자 소유권증명의 의미를 띄는) X 이더를 지불한다. - -파일을 올린 유저가 다시 자신의 파일을 다운로드 하고 싶을 때에는, 소액결제 채널 프로토콜(예, 32킬로바이트에 1 szabo를 지불한다)을 사용해서 파일을 복원할 수 있다; 수수료 측면에서 가장 효율적인 접근방법은 파일을 업로드한 유저가 저장이 끝나는 마지막까지 파일에 대한 트랜스액션을 공표하지 않고, 매 32 킬로바이트 마다 동일한 Nonce를 갖고 있는 보다 수익성이 있는 트랜스액션으로 바꿔주는 방법이 있다. - -비록 이 방식은 파일을 업로드한 유저가 다수의 랜덤한 노드들이 나의 파일을 계속 저장하고 있을 것이라고 믿어야 한다는 것을 전제하는 것 처럼 보이지만, 실제로는 유저는 업로드한 파일을 수많은 암호화된 조각으로 잘라내서 여러 노드들과 공유하고 또 컨트랙트를 통해서 외부 노드들이 내가 올린 파일을 저장하고 있다는 것을 모니터링함으로써 내가 올린 파일에 대한 분실 혹은 제 3자에의한 도용이라는 리스크를 거의 0에 가깝게 줄일 수 있다는 것이 분산형 드롭박스 컨트랙트 중요한 특징이다. 컨트랙트가 계속 돈을 지불하고 있다는 것은 곧 네트워크 상에서 누군가는 파일을 저장하고 있다는 것을 증명한다. - -### 탈중앙화된 자율조직(Decentralized Autonomous Organizations) - -“탈중앙화된 자율조직”의 기본적인 개념은특정한 집합의 구성원 또는 주주들을 갖고 있는 가상 독립체(virtual entity)가 필요한 수만큼의 구성원의 동의하에(예, 67% 다수) 조직자금운용 권한 및 코드 변경 권한을 갖는다는 것이다. 구성원들은 그 조직이 어떻게 운영자금을 배분할지를 공동으로 결정할 것이다. DAO의 자금을 배분하는 방식은 포상, 급여 형식부터 보다 색다른 내부화폐로 보상하는 형식까지 다양하다. 이것은 본질적으로 통상적인 기업이나 비영리재단에서 사용하는 법적인 장치들을 그대로 따르는 것이지만, 그 집행의 강제(enforcement)를 위해 암호화 블록체인 기술을 사용한다는 점이 차별점이다. 지금까지의 DAO에 대한 논의는 주로 "자본주의적(capitalist)" 모델인 "탈중앙화된 자율기업(decentralized autonomous corporation, DAC)"에 관한 것이었는데, 이 DAC는 배당을 받는 주주들과 매매가능한 지분을 가지고 있다. 이것에 대한 대안적인 형태로 "탈중앙화된 자율 커뮤니티( decentralized autonomous community)" 같은 개념도 생각해 볼 수 있는데, 이 안에서 구성원들은 의사결정에 있어서 모두 동일한 지분을 갖고있으며, 기존 구성원의 67%의 표결을 통한 동의가 있을 때 구성원을 충원하거나 탈퇴시킬 수 있을 것이다.그렇다면, 한사람이 오직 하나의 멤버십만을 가져야한다는 요건이 그 그룹에 의해 공동으로 시행될 필요가 있을 것이다. -DAO 코딩에 관한 일반적인 개요는 다음과 같다. 가장 간단한 디자인은 단순하게도 구성원 2/3가 동의/거부하였을 시 저절로 코드가 변경되는 컨셉이다. 비록 이론적으로 한 번 세팅된 코드는 바뀔수 없어도, 별도의 코드들을 각각 다른 컨트랙트들로 분리시켜서, 이것을 변경가능한 저장공간에 각각 넣어둔 다음, 이 코드들을 불러낼 수 있는 주소들을 제공함으로써 우리는 실제적으로 코드가 변경된 것과 같은 효과를 만들 수 있다. 아주 간단한 DAO 컨트랙에는 3가지 종류의 트랙잭션들이 있을 수 있는데, 그 구분은 그 트랜잭션이 제공하는 데이터의 종류에 따른다: - -* [0,i,K,V]는 저장공간 인덱스 k 에 있는 주소를 v 값으로 바꾸라는 인덱스 i 를 가진 제안을 등록 -* [0,i]는 제안 i 에 찬성하는 투표를 등록 -* [2,i] 는 충분한 투표가 이루어 졌을 때 제안 i 를 완결 - -컨트랙트는 상기 항목들 각각에 대한 조건절을 갖고 있을 것이다. 컨트랙은 모든 오픈스토리지에 일어난 변화들과 누가그 변화들에 대해 투표했는가하는 리스트를 보관유지하게 될 것이다. 컨트랙은 또한 전체 구성원 리스트도 보관한다. 어떤 스토리지 변경이던지 구성원의 2/3 의 투표를 받으면, 마지막으로 확정시키는 트랜잭션이 그 변경을 집행할 수 있게 된다. 이것보다 좀 더 발전된 형태는 내장 투표 기능을 이용해서 트랜잭션을 송신하거나, 구성원을 충원/탈퇴시키거나, 위임 민주주의 ([Liquid Democracy 또는 Delegative Democracy](http://en.wikipedia.org/wiki/Delegative_democracy))의 투표위임등의 기능도 추가할 수 있을 것이다. 이런 투표위임을 통해 누구에게나 자신을 위해 투표할 수 있도록 위임할 수 있고, 또 이 권한은 다른 사람에게 다시 전가가 될 수도 있다. A가 B에게 위임하고, B는 C에게 위임하면, C가 A의 투표를 결정한다. 이러한 설계를 통해서, DAO는 탈중앙화된 커뮤니티로 유기적으로 성장할 수 있으며, 더 나아가 누가 구성원인지 아닌지를 판단하는 기능을 전문가들에게 위임 할 수도 있도록 해줄 것이다. (물론 "현행시스템"과 달리, 각 커뮤니티 구성원들의 의견이 바뀜에 따라, 그러한 전문가들은 있을 수도/없을 수도 있게 된다.) - -이것과 비교되는 다른 모델은 탈중앙화된 기업이라고 할 수 있는데, 여기에서 각 어카운트는 0 또는 그 이상의 지분을 가질 수 있고, 어떤 결정을 내리기 위해서는 지분의 2/3 가 필요하다. 그것의 가장 단순화된 핵심 골격은 자산 관리 기능, 지분을 매매할 수 있는 오퍼를 낼 수 있는 능력, 그리고 다른 오퍼들을 수락할 수 있는(아마도 컨트랙트내에 있는 주문매칭 메커니즘을 통해) 능력들을 포함하게 될 것이다. "이사회" 개념을 일반화하는 유동식 민주주의(Liquid Democracy) 스타일의 위임제도 또한 있게 될 것이다. - -### 추가적인 어플리케이션들(Further Applications) - -1. **예금용 “전자지갑”**. 펀드를 안전하게 보관하고 싶은 A가 펀드를 잃어버리거나 누군가에게 그녀의 Private key를 해킹당할 것을 걱정한다고 가정해 보자. 그녀는 이더를 B라는 은행과의 컨트랙트에 다음과 같은 방식으로 집어 넣을 것이다. - -* A만이 하루에 그녀가 소유하는 펀드의 최대 1%를 출금할 수 있다. -* B또한 하루에 A가 소유하는 펀드의 최대 1%를 출금할 수 있지만, A는 그녀의 Private key를 통해 트랜스액션을 발송함으로써 B의 출금 권한을 없애버릴 수 있다. -* A와 B는 함께 어떤 금액도 출금할 수 있다. - -일반적으로 하루의 1%라는 상한선은 A에게 충분하며, 그 이상의 금액을 출금하고 싶을 시 A는 B에게 상한 조정 허가를 요청할 수 있다. Alice의 Private key가 해킹 당하였을 경우, B에게 펀드를 새로운 컨트랙트로 이체 시키라고 요청할수 있다. A가 본인의 Private key를 분실하는 경우, B는 오랜 시간에 걸쳐서라도 펀드의 금액을 출금할 수 있다. B가 악당인 경우에는 A는 B의 출금 권한을 정지시킬 수 있다. - -2. **작물보험**. 시세가 아닌 날씨 데이터피드를 이용해서 파생상품을 손쉽게 만들 수 있다. 아이오와주에 있는 농부가 강수량 데이터와 역비례하게 지불금이 산출되는 파생상품을 산다면, 가뭄이 있을 시 농부는 자동적으로 보상을 받을 수 있을 것이다. 이러한 어플리케이션은 자연재해 일반에 대한 보험상품으로 확대될 수 있을 것이다. - -3. **탈중앙화된 데이터피드**. “쉘링코인 ([SchellingCoin](http://blog.ethereum.org/2014/03/28/schellingcoin-a-minimal-trust-universal-data-feed/))”이라는 프로토콜을 사용하여, 변량 (Difference)을 다루는 금융계약(예, 로또)을 탈중앙화된 방식으로 운용할 수 있다. 쉘링코인은 다음과 같이 작동한다: 하나의 주어진 기준치(예, ETH/USD 시세)에 대해 N명의 참여자가 각각 자신들이 맞다고 생각하는 값을 시스템에 제공한다. 이러한 값들은 그 값의 크기에 따라 순위가 매겨지며, 이 때 25번째 퍼센타일과 75번째 퍼센타일 사이에 있는 값을 제시한 사람은 토큰 1개를 보상으로 받게 된다. 이렇게 되면 보상을 받기 위해서 모든 참가자들은 다른 사람들이 제시했을 똑같은 값을 제시하고자 할 것이고, 많은 다수의 참여자가 현실적으로 동의할 수 있는 유일한 값은 결국 명백한 기본값인 참값(truth)이 될 것이다. 이것은 ETH/USD 가격, 베를린의 온도, 심지어는 어려운 연산문제의 결과값까지도 포함하는, 어떤 수의 값들도 이론적으로 제공해줄 있는 탈중앙화된 프로토콜을 만들 수 있게 해준다. - -4. **스마트 멀티시그 공탁 계좌**. 비트코인은 멀티시그 트랜잭션을 만들 수 있게 해주는데, 이는, 가령, 5개의 키 중 3개를 갖고 서명해야 출금을 허용하는 방식의 트랜잭션을 지칭한다. 이더리움은 보다 높은 세밀도를 제공한다. 예를 들어, 5개 중 4개가 있으면 기금은 전체를 사용할 수 있고, 5개 중 3개가 있으면 하루에 기금의 10%을 사용할 수 있고, 2개가 있으면 하루에 0.5%를 사용할 수 있다. 추가적으로, 이더리움의 멀티시그는 동시에 집행해야 할 필요가 없다. 즉, 두 주체는 다른 시기에 블록체인에 본인의 전자 서명을 등록할 수 있고 최종의 전자서명이 이루어졌을 시 자동적으로 트랜잭션이 네트워크로 보내진다. - -5. **클라우드 컴퓨팅**. EVM 기술을 사용하여 입증 가능한 컴퓨팅 환경을 만들 수 있다. 입증 가능한 컴퓨팅 환경의 예시는 다음과 같다: 한 유저가 다른 유저에게 연산을 수행하게 한 후 랜덤한 시점에 연산을 수행한 주체에게 미리 설정된 연산 체크포인트가 올바른지에 대한 증명을 요구할 수 있다. 이 기술은 누구든지 자신의 데스크탑, 노트북, 또는 전문화된 서버를 갖고 참여할 수 있는 클라우드컴퓨팅 시장을 창조하게 될 것이며, 함께 연산의 정확성을 무작위 추출검사를 함으로써 시스템의 신뢰성이 더욱 강화될 것이다 (즉, 노드들이 이익을 내기 위해서는 유저들을 속일 수 없게 된다). 물론 그러한 시스템은 모든 작업들을 수행하는 데에 적합한 것은 아니다; 예를 들어, 높은 수준의 프로세스간 커뮤니케이션이 필요한 작업 같은 경우 여러 개의 클라우드 노드들로 수행하기에는 적합하지 않다. 하지만 그 외 작업들은 보다 수월하게 병렬진행이 가능하다; SETI@home, folding@home, 유전자 알고리즘 같은 경우는 분산화된 클라우드 컴퓨팅 플랫폼에서 쉽게 작업할 수 있는 프로젝트들이다. - -6. **P2P 도박**. Frank Stajano나 Richard Clayton의 [Cyberdice](http://www.cl.cam.ac.uk/~fms27/papers/2008-StajanoCla-cyberdice.pdf) 같은 P2P 도박 프로토콜들은 모두 이더리움의 블록체인 위에 구현될 수 있다. 가장 단순한 도박 프로토콜은 다음 블록의 해시값의 차이에 대한 컨트랙트이며, 0에 가까운 수수료와 그 누구도 사기를 칠 수 없는 보다 발전된 프로토콜이 그 위에 얹혀질 수 있다. - -7. **예측 시장**. 오라클(Oracle) 혹은 쉘링코인(Schelling Coin) 등을 갖고, Robin Hanson이 주창한 것과 같은 예측 시장도 쉽게 구현할 수 있다. 쉘링코인과 함께 예측시장은 분권화된 조직들에 대한 거버넌스 프로토콜로서 “퓨타키([Futarchy]((http://hanson.gmu.edu/futarchy.html), 역주: 정치인들이 국가복지에 관한 정책을 정의하면 예측시장이 정책 중 가장 긍정적인 효과가 많을 수 있는 정책을 결정하는 형식의 거버넌스)의 첫 번째 주류 어플리케이션이 될 수 있다. - -8. **블록체인상의 탈중앙화된 장터**. 신원조회 / 평판 시스템을 기반으로 원활하게 돌아가는 P2P 장터를 구축할 수 있다. - -## 그 밖의 이슈들 - -### 수정된 GHOST 도입(Modified GHOST Implementation) - -GHOST(Greedy Heaviest Observed Subtree)프로토콜은 Yonatan Sompolinsky and Aviv Zohar 에 의해 [2013년 12월](http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf)에 처음 소개된 혁신이다. GHOST의 문제의식은, 현재 빠른 확인시간(confirmation times)을 가지고 있는 블록체인들이 높은 스테일(stale) 비율로 인해 보안성 저하라는 문제를 겪고 있다는 것인데, 이는 블록들이 네트워크를 통해 전파되는데 일정한 시간이 걸리기 때문이라는 것이다. 만일 채굴자 A가 하나의 블록을 채굴했는데, 이 블록이 채굴자 B에게 전파되기전에 채굴자 B가 다른 또 하나의 블록을 채굴했다고 하면, 채굴자 B의 블록은 결국 낭비될 것이고, 네트워크 보안에 기여하지 못하게 될 것이다. - -게다가 중앙집중화(centralization) 이슈도 있다; 만일 채굴자 A가 30%의 해시파워를, 그리고 B가 10%의 해시파워를 가지고 있다면, A가 스테일 블록을 생산할 위험성은 매번 70%가 될 것이고(왜냐하면 다른 30%의 경우에는 A가 마지막 블록을 만들게 되었고, 따라서 즉각적으로 채굴데이터를 가지게 되기 때문이다), 반면 B는 매번 90%의 경우에 스테일 블록을 생산하게 될 위험성을 가지고 있다. 따라서 만일 블록 주기가 스테일 비율이 높은 것에 필요한 만큼 충분히 짧다면, A는 단순히 크기가 크다라는 사실 자체만으로 훨씬 더 높은 효율성을 가지게 된다. 이러한 두가지 효과가 결합되어서, 블록주기가 짧은 블록체인에서는, 높은 해시파워 점유율을 가진 단일한 풀이 채굴과정에 대한 사실상의 통제권을 가지게 될 가능성이 매우 높아진다. - -Sompolinsky와 Zohar가 설명했듯이, GHOST는 어느 체인이 “가장 긴(longest)”것인지 계산할 때 스테일 블록도 포함으로써 위에서 제기한 첫번째 이슈, 즉 네트워크 보안 손실이라는 문제를 해결한다. 다시 말해서 어느 블록이 가장 큰 전체 작업증명을 가지고 있는지 계산함에 있어서, 그 블록의 모블록(parent)과 그 조상(ancestors) 뿐만 아니라, 그 블록의 스테일 자손(stale descendants, 이더리움의 용어로는 “삼촌”)까지도 더한다는 것이다. 중앙화라는 두번째 문제를 해결하기 위해서 우리는 Sompolinsky와 Zohar가 설명한 프로토콜을 넘어서서, 스테일 블록들에 대해서도 블록보상을 제공한다. 스테일 블록도 기본 보상의 87.5%를 받게 되며, 그 스테일 블록을 포함하고 있는 사촌이 나머지 12.5%를 받는다. 하지만 수수료는 삼촌들에게는 주어지지 않는다. - -이더리움은 7단계 레벨만 포함하는 단순화된 GHOST 버전을 구현한다. 그것은 다음과 같이 구체적으로 정의된다; - -* 하나의 블록은 반드시 하나의 모블록을 지정해야 하며, 0 또는 그 이상의 삼촌을 지정해야 한다. -* 블록 B에 포함된 삼촌은 다음과 같은 속성들을 가지고 있어야 한다. - * B의 k번째 조상의 직접적인 자손이어야 한다. 여기서 2 <= k <= 7. - * B의 조상이어서는 안된다. - * 유효한 블록 헤더여야 하지만, 이전에 확인되었을 필요도, 또는 심지어 유효한 블록일 필요도 없다. - * 이전 블록들에 포함된 모든 삼촌들, 그리고 같은 블록에 포함된 모든 다른 삼촌들과는 달라야 한다(중복포함방지) -* 블록 B에 있는 각 삼촌 U에 대해, B의 채굴자는 코인베이스 보상에 더해 추가로 3.125%를 더 받고, U의 채굴자는 기본 코인베이스 보상의 93.75%를 받는다. - -단지 최대 7세대만 삼촌을 포함할 수 있는 제한된 GHOST 버전을 사용하는 이유는 두가지이다. 첫째, 무제한 GHOST는 하나의 블록에 대해 어떤 삼촌이 유효한지에 대한 계산을 매우 복잡하게 만든다.. 둘째, 만일 이더리움과 같은 방식의 보상을 하면서도 무제한 GHOST를 적용하게 되면 채굴자들이 공격자의 체인이 아니라 주체인(mainchain)에서 채굴를 할 동기를 잃게 될 것이다. - -### 수수료 - -블록체인에 올려지는 각 트랜잭션은 그것을 다운로드하고 검증하기 위한 비용을 네트워크에 부과하기 때문에, 남용을 방지하는 어떠한 규제 메커니즘, 일반적으로는 트랜잭션 수수료가 필요하게 된다. 비트코인에서 사용되는 기본적인 접근방법은 순수하게 자발적인 수수료를 징수하면서, 채굴자들이 게이트키퍼(gatekeeper)로서의 역할을 하고 유동적으로 최저액을 설정하도록 하는 것이다. 이런 접근방법은 비트코인 커뮤니티에서 매우 환영 받아왔는데, 그것이 “시장-기반”이기 때문에, 채굴자와 트랜잭션 송신자들간의 수요와 공급이 그 가격을 결정한다는 이유에서였다. - -하지만 이런식의 사고방식에는 문제가 있는데, 트랜잭션 처리는 시장에서 일어나는 것이 아니라는 점이다. 트랜잭션 처리를 채굴자가 송신자에 제공하는 하나의 서비스로 해석하는 것이 직관적으로 솔깃해 보이기는 하지만, 실제적으로는 채굴자가 포함하는 모든 트랜잭션들은 네트워크의 모든 노드들에 의해 처리되어야 하고, 따라서 트랜재션처리에 필요한 대부분의 비용은 제3자가 부담하는 것이지, 그 트랙재션을 포함할지 말지를 결정하는 채굴자들이 아니라는 것이다. 그러므로 공유지의 비극(tragedy-of-the-commons) 문제들이 매우 일어나기 쉽다는 것이다. - -하지만, 이러한 시장기반 메커니즘의 결함은 어떤 부정확한 단순화 전제들이 주워졌을 때, 마술처럼 그 결함자체를 상쇄하게 된다. 그 주장은 다음과 같다. -다음을 전제해 보자: - -1. 하나의 트랜잭션이 `k`개의 작업들(operations)을 초래하는데, 이 트랙잭션을 포함하는 채굴자에게 `kR`만큼의 보상을 제공하게 된다. 여기서 `R`은 송신자에 의해서 설정되고, `k` 와 `R`은 (대략적으로) 채굴자에게 사전에 노출된다. -2. 하나의 작업은 어떤 노드에 대해서든 C 만큼의 처리비용을 가진다(즉, 모든 노드들은 똑같은 효율성을 가지고 있다). -3. `N`개의 채굴노드들이 있고, 각각은 정확히 똑같은 처리파워(즉, 전체의 `1/N`)를 가지고 있다. -4. 채굴을 하지 않는 완전노드(full nodes)는 없다. - -채굴자는 어떠한 트랜잭션이 그 비용보다 기대보상이 클 경우 처리하려고 할 것이다. 따라서, 기대 보상은 kR/N인데, 왜냐하면 채굴자는 다음번 블록을 처리할 1/N 확률을 가지고 있으며, 이 채굴자에게 처리비용은 단순히 kC이다. 그러므로 채굴자들은 kR/N > kC 이거나, R > NC일때 트랜잭션들을 포함하려 할 것이다. 여기서 R은 송신자에 의해 제공된 단위작업(pre-operation)당 수수료이고, 따라서 이것은 송신자가 그 트랜잭션에서 보게 될 혜택에 대한 하한값이 되고, NC는 하나의 작업을 처리하기 위해 전체 네트워크에 부과된 비용임을 주목하자. 따라서 채굴자들은 비용보다 전체 공리적인 혜택이 큰 트랜잭션들만 포함하려 하는 인센티브를 갖게 된다. - -하지만 현실에서는 이러한 가정들이 맞지 않는 몇가지 중요한 차이들이 있다. - -1. 채굴자는 다른 검증 노드들보다 트랜잭션을 처리하는데 더 많은 비용을 지불하게 되는데, 왜냐하면, 추가적인 검증시간은 블록전파를 지연시키고, 따라서 블록이 스테일되는 확률을 증가시키기 때문이다. -2. 비채굴 완전노드(full note)들이 존재한다. -3. 채굴 파워의 분포는 실제로 심각하게 불평등하게 될 수 있다. -4. 네트워크에 피해를 주는 이해관계를 가진 투기자들, 정치적 적, 그리고 일탈자들이 존재하고, 그들은 다른 검증노드가 지불하는 비용보다 훨씬 적은 비용이 들게 될 그런 컨트랙트들을 교묘하게 만들 수 있다. - - -(1)은 채굴자가 더 적은 수의 트랜잭션들을 포함하게 되는 경향을 제공하게 되고, (2)는 NC를 증가시키게 되며, 따라서 이 두가지의 효과들은 부분적으로는 서로를 상쇄한다. (3)과 (4)가 주요한 문제인데, 이것들을 해결하기 위해, 플로팅 상한값(floating cap)을 도입한다. 어떤 블록이던지 BLK_LIMIT_FACTOR 곱하기 장기 지수 이동평균(the long-term exponential moving average)보다 더 많은 오퍼레이션들을 가질 수 없다는 것이다. 정확히는: - - blk.oplimit = floor((blk.parent.oplimit * (EMAFACTOR - 1) + floor(parent.opcount * BLK_LIMIT_FACTOR)) / EMA_FACTOR) - -BLK_LIMIT_FACTOR 와 EMA_FACTOR은 상수이며 각각 잠정적으로 65536와 1.5로 정해질 것이지만, 추후 분석 후에 바뀔 가능성이 많다. - -비트코인에 있어서 큰 블록크기를 막는 또 다른 요인도 있다. 큰 블록이 전파되는데에 더 오래 걸리기 때문에, 스테일 될 가능성이 높다는 점이다. 이더리움에서도 높은 가스(GAS)사용 블록은 전파되는데 더 오래걸리는데, 그것은 크기가 물리적으로 크다는 점과, 트랜잭션 상태변환들(state transitions)을 검증 처리하는데 더 오래 걸린다는 점 때문에 그러하다. 이러한 지연 불이익(delay disincentive)은 비트코인의 경우에는 중요한 고려사항이지만, 이더리움의 경우에는 GHOST프로토콜 덕분에 중요도가 낮아진다. 따라서 조정된 블록리미트(block limit)로 인해, 보다 안정적인 기본기준(baseline)을 얻을 수 있게 된다. - -### 연산과 튜링완전성(Computation And Turing-Completeness) - -중요한 점은 이더리움 가상 머신(EVM)이 튜링-완전하다는 것이다. 즉 EVM은 무한 순환을 포함한 상상가능한 모든 계산 수행을 코딩할 수 있다. EVM코드는 순환 계산을 다음 두 가지 방법으로 수행한다. -첫번째는 JUMP 명령어로 코드의 이전 장소로 되돌아가고, JUMPI 명령어로 while x < 27: x = x * 2 같은 문장처럼 조건에 따라 건너뛰게 하는 것이다. -두번째는 한 계약이 재귀 반복을 통해 순환을 일으킬 가능성이 있는 다른 계약을 호출하는 것이다. -이것은 자연스럽게 어떤 문제를 야기한다: 악의적인 사용자가 계산을 무한 순환에 빠뜨리는 방법으로 채굴자와 풀 노드를 마비시켜버릴 수 있을까? -컴퓨터 학계에서 정지문제(halting problem)라고 알려진 유명한 문제를 통해 이런 이슈를 피할 수 없음을 알 수 있다. 일반적으로 어떤 주어진 문제가 궁극적으로 멈추는지 아닌지를 미리 판별할 방법은 없다. -상태변환 과정에서 설명했듯이, 한 거래에 최대로 계산할 수 있는 단계 수를 설정함으로써 우리는 해답을 얻을 수 있다. 만약 계산 단계가 그 최대수보다 더 많으면 계산은 원점으로 돌아가지만 수수료는 그대로 지불된다 -메시지들도 같은 방법으로 작동한다. 우리가 제시한 해답의 의미를 더 잘 이해하기 위해, 아래와 같은 몇가지 보기를 생각해보자. - -* 한 악의적 공격자가 무한 순환을 실행하는 계약을 만들어 채굴자로 하여금 무한 순환을 실행하도록 거래를 보냈다고 하자. 채굴자는 거래를 진행하고 무한 순환을 실행해 가스를 다 소모해서 실행 도중에 멈춘다고 하더라도, 거래는 여전히 유효하고 채굴자는 여전히 공격자에게 이미 실행된 각 계산 단계마다의 수수료를 요구할 수 있다. -* 한 악의적 공격자가 채굴자에게 계산을 오랫동안 계속하게 할 목적으로 아주 긴 무한 순환 프로그램을 짰다고 하자. 계산이 끝났을 때 아주 조금의 블록만이 생성되어 채굴자가 수수료를 요구하기 위해 그 거래를 포함하는게 불가능하게 만드는 게 악의적 공격자의 목적이다. 하지만, 그 공격자는 실제 실행되는 계산 단계의 상한선을 규정하는 STARTGAS 명령어에 대한 값을 제출해야만 하고, 따라서 채굴자는 해당 계산이 과도하게 많은 단계의 수를 필요로 한다는 것을 계산 전에 미리 알게 된다. -* 예를 들어send(A,contract.storage[A]); contract.storage[A] = 0, 같은 명령이 들어간 계약이 있다고 하자. 한 악의적 공격자가 이 계약을 본 후 첫번째 계산 단계만 실행시키고 두번째 단계는 실행할 수 없을 만큼의(예를 들어 예금 인출만 한 다음 장부에 기록되는 스텝은 실행되지 않게) 가스만 넣고 거래를 진행시켰다고 하자. 계약 작성자는 이런 공격에 대해 방어를 걱정할 필요가 없다. 왜냐하면 계산 실행이 도중에 멈추면, 해당 변화도 원상복구되기 때문이다. -* 어떤 금융 계약이 9개의 금융상품 자료값의 평균을 취해 위험을 최소화하도록 작동하고 있다고 하자. 그 중 DAOs 섹션에서 설명된 것 같은 가변주소요청 메커니즘을 통해 변경가능하도록 디자인 된 하나의 자료값을 악의적 공격자가 취한다고 하자. 그렇게 함으로써 이 금융 계약으로부터 펀드를 찾으려는 모든 시도에 대해 가스가 다 소모되도록 시도하게 된다. 하지만 금융 계약은 이 문제를 막기 위해 메시지 위에 가스 한도를 설정해 두는 것으로 공격을 방어할 수 있다.. - -튜링-완전에 대한 대칭적인 개념은 튜링-비완전이다. 즉 JUMP 명령어나 JUMPI 명령어가 존재하지 않으며, 그 어떤 주어진 시간에도 오직 각각의 계약의 복사본 하나만이 허용된다. 이런 시스템 아래에서는 위에 서술된 수수료 시스템이라든지 우리가 제시한 해답의 효율성을 둘러싼 불확실성에 관한 논쟁은 불필요할 것이다. 한 계약을 실행하는데 드는 비용은 프로그램의 크기에 따라 상한선이 정해질 것이기 때문이다. -나아가, 튜링-비완전성은 그리 큰 제한도 아니다. 우리가 현재까지 상상했던 계약 가운데, 순환 명령을 필요로 했던 것은 단 하나 뿐이었다. 그리고 그 순환 명령조차도 프로그램 코딩에서 한 문장을 26번 반복함으로써 없앨수 있었다. -튜링-완전이 함의하고 있는 심각성과 그 제한적인 이점을 생각해볼 때, 왜 튜링-불완전 언어를 쓰면 안되는 걸까? -하지만 현실적으로, 튜링-불완전성은 순환 문제와 악성 공격에 대한 깔끔한 해답이 아니다. -왜 그런지를 알기 위해 아래와 같은 예제 계약을 보자. - - C0: call(C1); call(C1); - C1: call(C2); call(C2); - C2: call(C3); call(C3); - ... - C49: call(C50); call(C50); - C50: (프로그램의 한 단계를 실행한 후 그 변화를 저장소에 기록한다.) - -이제 A 에게 거래를 보내자. 51번의 거래에서 우리는 2 의 50승의 계산 단계를 계속하는 계약을 보낸다..채굴자들은 각 계약에 따른 계산 단계의 최대 수와 다른 계약을 재귀적으로 호출하는 계약에 대한 계산 단계 수를 모두 확보함으로써, 이런 논리 폭탄을 사전에 감지하려고 시도할 수 있을지도 모른다. 하지만 이런 시도는 채굴자들이 다른 계약을 호출하는 계약은 다루지 못하게 만든다. (왜냐하면 위의 모든 26개 계약의 작성과 실행은 한 줄의 계약으로 쉽게 합쳐질 수 있기 때문이다.) -다른 문제적 지점은 메시지의 주소 필드는 변수라는 점이다. 그래서 일반적으로, 주어진 계약이 사전에 미리 호출하는 다른 계약이 뭔지를 판별하는 것조차 불가능할지도 모른다. -그래서,결국 우리는 놀라운 결론에 도달한다. 튜링-완전은 놀랍도록 다루기 쉬우며, 만약 튜링완전성이 없으면 정확히 같은 계약으로 대체할 수 없는 한, 마찬가지로 다루기가 놀랍도록 어렵다는 점이다. 그렇다면, 그냥 그 프로토콜을 튜링-완전하게 놔두는게 좋을 것이다. - -### 통화 그리고 발행(Currency and Issuance) - -이더리움(Ethereum) 네트워크는 그 안에서 자체적으로 통용되는, ‘이더(Ether)’라는 화폐를 가지고 있다. 이더는 여러가지 가상자산들간의 효율적인 교환을 가능케하는 매개물의 역할을 하며, 또한 트랜잭션 수수료(transaction fee)를 지불하기 위한 방법을 제공한다. 사용자의 편의와 향후 있을 지 모르는 논쟁을 예방하는 차원에서, 이더(Ether)의 각 단위에 대한 명칭은 다음과 같이 미리 정해졌다. (비트코인 명칭과 관련하여 벌어지는 논쟁 참조) - -* 1: wei -* 1012: szabo -* 1015: finney -* 1018: ether - -위 명칭들은, 미화 명칭인 “달러”와 “센트” 또는 비트코인의 “BTC”와 “사토시” 등의 확장개념으로 생각하면 이해하는데 도움이 될 것이다. 가까운 미래에, “이더(ether)”는 일반 거래(transaction)를 위해, “피니(finney)”는 소액결제를 위해, 그리고 “싸보(szabo)”와 “웨이(wei)”가 수수료나 프로토콜 도입 등과 관련된 기술적논의를 위해 사용될 것으로 기대된다. 나머지 명칭들은, 지금 당장은 클라이언트에 포함시키지 않는다. - -화페발행 모델: - -* BTC 당 1000-2000개의 가격으로 이더를 판매한다. Matercoin이나 NXT와 같은 다른 암호화화폐 플랫폼에서 성공적으로 사용했던 방법으로, 이더리움 조직을 금전적으로 지원하고 개발에 필요한 비용을 댄다. 이 시기에 이더를 구매하는 구매자들은 큰 폭의 할인을 통해 저렴하게 이더를 얻게 된다. 이렇게 모인 자금은 전액, 개발자를 위한 월급과 보상, 그리고 여러가지의 이더리움 관련 영리와 비영리프로젝트를 위한 투자금으로써 사용된다. -* 판매 된 총 이더(60,102,216 ETH)의 0.099배 만큼(5,950,110)의 이더가 신규발행 되어, 이더리움 런칭 전의 초기기여자들과 ‘이더로 이미 발생 된 비용에 대한 미지급금’을 처리하기 위해 이더리움조직(Ethereum organization)에게 분배된다. -* 또 다른 0.099배 만큼의 이더는 장기보유금으로 신규 발행하여 적립해둔다. -* 채굴시점 이후부터 영구히 매년, 총 판매수량(60,102,216 ETH)의 0.26배 만큼(15,626,576)씩을 채굴자에게 신규 발행해준다. - -| 분류 | 런칭시 | 1년후 | 5년후 | -| ------------- | ------------- |-------------| ----------- | -| 초기판매 이더총량에 대한 배수 | 1.198X | 1.458X | 2.498X | -| 구매자 | 83.5% | 68.6% | 40.0% | -| 런칭전 미지급 적립금 | 8.26% | 6.79% | 3.96% | -| 런칭후 적립급 | 8.26% | 6.79% | 3.96% | -| 채굴자 채굴량 | 0% | 17.8% | 52.0% | - -** 이더 장기 공급 성장률(%)** - -![SPV in bitcoin](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/inflation.png) - -_매년 신규발행량이 일정함에도 불구하고, 비트코인이 그러한 것처럼, 발행된 총 이더에 대한 신규 이더의 발행률은 그 비중이 0을 향하여 계속 줄어들게 된다._ - -위 모델에서 결정되어야할 두 가지 선택이 있다. (1) 하나는, ‘재단보유금(endowment pool)’의 존재유무와 그 규모이며, (2) 둘째는 총 발행코인량이 정해져 있는 비트코인과는 달리, 신규코인을 끊임없이 발행해야 하는지의 여부이다. - -‘재단보유금(endowment pool)’의 정당성에 대해서는 다음과 같이 설명할 수 있다. 만일 이러한 보유금이 없는 상황이라면, 같은 인플레이션율을 유지하기 위해서는 연간 발행량이 26%가 아닌, 21.7%로 줄어들어야 한다. 그렇게 되면 이더의 총량은 16.5% 줄어들게 되며, 각 이더의 가치는 19.8%증가하게 된다. 이 경우 균형을 위해서는 19.8%의 이더가 더 프리세일에서 판매되어야 한다. 그렇게 되면 각 경우의 이더 가치는 서로 정확히 동일해진다. 그렇게 되면 이더리움 재단이 1.198배의 BTC를 가지게 되는데, 이를 처음 BTC 액수(1배수)와 추가된 0.198배수의 BTC로 나누어보면 결국 상황이 동일해진다는 점을 알 수 있다. 그러나 한 가지 차이점은 이 경우 조직이 가진것은 이더가 아닌 BTC이므로, 이더의 가치를 높이기 위한 인센티브를 얻지 못한다는 점이다. - -정해진 양의 이더를 영구적으로 신규발행하는 모델(permanent linear supply growth model)은 비트코인이 겪고있는 ‘부의 집중현상’을 완화시킬 수 있다. 또한 현재 또는 미래의 참여자들이 계속해서 이더를 시장이 아닌 채굴을 통해 얻을 수 있는 기회를 제공한다. 동시에, “공급성장률(Supply Growth Rate)”은 계속해서 0을 향해 줄어들게 된다. 우리측의 이론으로는 다음과 같은 현상을 예상해 볼 수 있다. 시간이 흐름에 따라 사용자들의 부주의, 죽음 등으로 인해 현실적으로 일부의 이더들이 계속해서 시장에서 사라지게 된다. 이렇게 사라지는 이더로 인해 점점 줄어드는 ‘시장유통가능 이더총량(the total currency supply in circulation)’은 매년 신규발행되는 이더에 의해 균형을 이루게 된다. (ex. 만일 총 이더량이 26배수(1,562,657,616 ETH)에 달했고, 매년 이 중 1%(0.26배수)에 해당하는 이더가 소실된다면, 이는 매년 새로이 발행되는 0.26배수의 이더와 균형을 이루게 된다) - -장래, 공급성장률을 약 ‘0에서 0.05배수 이내’가 되도록 수정을 하면서, POS로 채굴모델을 변경할 계획을 가지고 있다. 만일, ‘이더리움 재단(Ethereum organization)’이 보유금을 모두 잃거나, 또는 여타의 이유로 사라지게 되면, “사회적계약(social contract)”을 열어둘 것이다. 이를 통해, 이더 발행량을 최대 ‘60102216 * (1.198 + 0.26 * n)‘를 넘지 않도록만(n은 첫 블록 생성 이후의 총 년수) 지킨다면, 누구든지 이더리움의 ‘후속버전(a future candidate version:RC버전)’을 만들 수 있을 것이다. 이 후속버전의 창시자는 개발/관리에 필요한 비용을 충당하기 위해서, 공개판매(crowd-sell)를 하거나, ‘총 가능 이더발행량’과 ‘POS를 통한 공급량’ 간의 차액 중 일부나 전부를 이용할 수 있을 것이다. 만일 어떠한 창시자가 이러한 “사회적계약(social contract)”에 반하는 내용을 업데이트하게 된다면, 결국 대의에 의해 합당한(compliant) 버전에서 별개로 포크되어(forked)나와 탈락하게 될 것이다. - -### 채굴 중앙집중화(Mining Centralization) - -비트코인 채굴 방식은, 목표 값(현재 기준 약 2192)보다 낮은 값이 나올 때까지, 블록헤더에 대한 sha256 해싱 작업을 무한정 반복하는 것이다. 하지만 해당 방식에는 두 가지 약점이 존재한다. - -첫번째는 현재 채굴참여에 대한 장벽이 매우 높아졌다는 것이다. 현재 채굴생태계는 ASIC(특수목적을 위해 전용으로 설계된 반도체로, 범용반도체에 비해 성능이 뛰어남)에 의해 완전히 잠식되었다. 이러한 ASIC채굴기는 일반 GPU채굴기 등에 비해 수 천배 이상의 효율을 가지는데, 따라서 ASIC이 아닌 일반컴퓨터를 통한 일반사용자들의 채굴행위는 경쟁력에서 밀려 효용을 잃게 되었다. 과거의 채굴행위가 분권화되고 이타적인 참여자 중심의 ‘생태계’였다면, 현재는 수십억원의 투자가 되어야만 참여가 가능한 재력가들의 ‘사업’으로 변질되고 말았다. - -두번째는 채굴방식이다. 이전처럼 여러 지역에서 여러 참여자가 블록생성에 참여하는 것이 아니라, 중앙집중화된 채굴풀(Mining pool)이 제공하는 블록헤더(block header)에 의존하여 채굴에 참여한다는 점이다. 이로 인한 부작용이 상당한데, 현재 기준으로는, 3개 채굴풀들이 개인들의 컴퓨팅파워를 인계 받아서 무려 50%에 육박하는 해시를 간접적으로 통제하고 있다. 물론 해당 풀의 점유율이 50%를 넘어가기 전에 개인들이 다른 소규모 풀들로 이동을 할 수 있기 때문에, 풀들이 마음대로 자원을 남용할 수는 없겠지만, 이는 여전히 큰 문제이다. - -이더리움의 채굴 방식은 조금 다르다. 각 채굴자가 상태정보(the state)에서 무작위의 정보를 가져와서, 무작위로 선택 된 최근 몇개의 블록내역을 해싱 작업하고 결과값을 내놓는 것이다. 이렇게 하게 되면 두가지 이점이 있다. - -첫번째는 이더리움 계약이 모든 종류의 컴퓨터 계산방식을 포괄할 수 있다는 점이다. 따라서 자연히 ASIC도 모든 계산방식에 적합하게 설계되어야 하는데, 이렇게 되면 결국 ASIC이라기 보다는 일종의 고성능 CPU가 되는 셈이다. 즉 현실적으로 ASIC(주문형 전용반도체) 자체가 무용지물이 된다. - -두번째로, 채굴자들은 작업 시 전체 블록체인을 다운 받아 모든 이체내역을 검증해야 한다는 점이다. 이렇게 되면 중앙집중화 된 대형 풀이 필요없게 된다. 물론 대형풀 자체는 신규블록생성 보상을 균일하게 참여자들에게 배분해 주는 효과가 있긴 하지만, 그러한 효과는 P2P형식의 풀(pool)을 통해서도 충분히 구현이 가능하다. 굳이 중앙집중형 풀(centralized pool) 방식을 사용할 필요가 없다. - -물론 위의 채굴 모델이 아직 검증된 것은 아니다. 또한 ASIC장비에 대한 저항성을 높이는 작업도, 이론처럼 현실에서 적용이 될 수 있을지에 대하여는 의문의 여지가 있다. 하지만 한 가지 확실한 것은, 여러종류의 수많은 계약이 적용이 되면, 이를 모두 포괄하는 ASIC을 예전처럼 만들어 내기는 어렵다는 점이다. 또한 어떠한 종류의 작업에 특화 된 ASIC이 존재한다면, 이에 반하는 작업을 요하는 계약이 생성되는 것을 원치 않을 것이다. 그러면 해당 ASIC채굴자의 경쟁자는 그에 적대적인, 즉 비효율적인 작업을 요하는 계약들을 생성해 냄으로써 공격을 가할 것이다. 즉, 각 부분에 특화된 ASIC을 소유한 채굴자들은 서로에게 불리한 작업을 하게하는 계약들을 만들어 냄으로써 서로를 공격할 것이다. 물론 이러한 방법은 ‘기술적’인 접근이라기보다는 ‘경제학적 인간행동론’에 근거한 접근에 가깝다. - -### 확장성(Scalability) - -이더리움에 대한 한 가지 공통된 의문점은 확장성 부분이다. 비트코인과 마찬가지로 이더리움도 모든 이체작업이 네크워크 상의 전체 노드에 의해서 일일이 검증 및 작업이 되어야 한다는 약점이 있다. 비트코인의 경우, 현재 전체 블록체인의 크기가 약 15GB에 이르며, 그 크기는 매 시간 1MB씩 꾸준히 늘어나고 있다. VISA의 경우 초당 2,000여 건의 이체작업을 처리하는데, 이는 매 3초당 1MB씩의 확장(시간 당 1GB, 매 년 8TB)을 의미한다. 이더리움도 비슷한 문제를 겪을 것이고, 단순히 화폐로서의 역할 만하는 비트코인에 비한다면, 온갖 종류의 탈중앙화된 어플리케이션들(Dapps: Decentralized applications)을 포괄하는 이더리움은 이 부분에서 훨씬 더 많은 문제를 겪을 수도 있을 것이다. 하지만 한 가지 다른 점은, 이더리움은 ‘전체 블록체인 히스토리’가 아닌, 단지 ‘상태 정보(the state)’만 가지고 있으면 된다는 점이다. - -만일 개개의 모든 노드가 전체 블록체인을 보관해야 한다면, 아래와 같은 문제가 생길 수 있다. 블록체인의 크기가 점점 커져 100TB에 육박하게 되었다고 생각해보자. 이 정도 수준으로 보관해야하는 블록체인의 크기가 커지면, 오직 소수의 사업가나 기업 형태의 참여자만이 이를 감당할 수 있게 된다. 다수의 일반 사용자들은 ‘라이트 SPV(Simple Payment Verification)’ 노드만들 사용하게 될 것이다. 이렇게 되면, 전체 블록체인의 내역을 가진 소수의 참여자들이 결탁하여, 장부내역을 수정하거나 블록보상량을 바꿔치기 하는 등의 조작행위가 일어날 수 있을 것이다. 단순한 ‘라이트 노드(light node)’로서는 이러한 조작을 감지할 방법이 없다. 물론 ‘전체 블록체인를 소유한 노드(full node)’ 중에서도 선의의 참가자가 있을지 모른다. 그러나 다수의 ‘완전노드(full node)’가 작심하여 블록체인 조작을 시도한다면, 이를 발견하는 시점에서는 이미 늦었다고 봐야 할 것이다. 실제로 비트코인이 현재 이와 비슷한 문제에 처할 위험이 있다고 경고받고 있으며, 해당 문제를 완화시키는 방법에 대하여는 [Peter Todd에 의해 논의된 바](http://sourceforge.net/p/bitcoin/mailman/message/31709140/) 있다. - -위의 문제를 해결키 위해, 가까운 시일 안에 두 가지의 전략을 추가로 도입할 예정이다. 첫번째로 이더리움도 기본적으로 블록체인 기술을 바탕으로 한 채굴 알고리즘을 사용하고 있기 때문에, 모든 채굴자들은 ‘완전노드(full node)’가 되도록 의무화 될 것이며, 이는 필요한 최소한의 완전노드 숫자를 확보할 수 있도록 해줄 것이다 . 두번째로, 이체내역 검증 작업 이후 블록체인에 ‘중간상태 트리루트(an intermediate state tree root)’를 도입하는 것이다. 이렇게 되면, 아무리 블록생성 작업이 소수의 노드에 집중되더라도, 단 하나의 선의의 노드(honest node)만 존재한다면 검증 프로토콜(verification protocol)을 통해 이 문제를 해결할 수 있다. - -만일 어떠한 채굴노드가 전파한 블록이 검증오류(invalid)처리가 되었다면, 해당 블록의 ‘구성(format)’이 맞지 않거나 ‘상태내역 S [ n ]’이 틀린 경우일 것이다. ‘S [ 0 ]’ 상태가 옳은 것으로 간주되기 때문에, ‘S[ i-1 ]’이 맞다면, ‘S[ i ]’에 오류가 있는 것이다. 검증작업에 참여하는 노드는, ‘APPLY(S[i-1],TX[i]) -> S[i]’ 작업(processing)을 하는 ‘페트리샤 트리 노드의 부분집합(the subset of Patricia tree)’을 통해 ‘검증오류증명(proof of invalidity)’과 ‘인덱스 i’를 제공한다. 노드들은, 위의 노드들을 이용해 해당 작업을 수행하며, 생성한 ‘S[ i ]’가 제공받은 ‘S[ i ]’와 일치하지 않음을 발견하게 된다. - -또한 ‘불완전한 블록(incomplete block)’을 전파하려는 악의의 채굴노드들과 관련된 더욱 정교한 공격이 이루어질 수 있다. 블록을 검증하는데에 필요한 정보가 온전히 존재하지 않을 수도 있다. 이 경우, ‘질의-응답프로토콜(challenge-response protocol)’ 기법이 사용될 수 있다. 검증노드가 ‘목표 블록의 인덱스 형태(target transaction indices)’로 ‘질문(challenge)’을 생성하고, 노드를 수신하는 라이트노드(light node)는 해당 블록(challenge)을 일단 검증오류블록으로 취급한다. 이후, 다른 노드(채굴노드이든 검증노드이든)가 ‘페트리샤 트리 노드의 부분집합(the subset of Patricia tree)’을 검증증명(proof of validity)으로써 제공한다면, 그때서 위의 블록은 검증된(유효한) 것으로 취급된다. - -## 결론 - -이더리움 프로토콜은 본래 매우 범용적인 프로그래밍 언어를 통해 ‘블록체인상 에스크로나 인출한도설정, 금전계약, 도박 시장 등의 고급 기능’을 제공하는, 가상화폐의 업그레이드 버전으로 구상되었다. 이더리움 프로토콜은 이러한 어플리케이션들을 직접적으로 제공하는 것이 아니라, 튜링완전언어(Turing-complete programming language)를 통해 이론적으로 거의 모든 형태의 이체방식이나 어플리케이션을 만들어낼 수 있도록 지원한다. 더욱 흥미로운 점은, 이더리움은 단순한 ‘화폐’의 차원을 훨씬 뛰어넘는다는 점이다. 분산저장공간(DFS:decentralized file storage)이나, 분산컴퓨팅, 분산예측시장(decentralized prediction market) 프로토콜 등은 사실 수많은 응용개념들 중 일부에 불과하다. 이러한 새로운 개념들은 컴퓨팅 산업의 효율성을 폭발적으로 높일 수 있는 잠재력이 있으며, P2P프로토콜에 처음으로 ‘경제적인 차원(economic layer)’을 입힘으로써 엄청난 혁신을 가져올 수 있을 것이다. 마지막으로, 컴퓨팅이나 금융과 관련이 없는 분야들에서도 다양한 어플리케이션들이 나올 것이다. - -이더리움 프로토콜이 제공하는 ‘임의상태변환(arbitrary state transition function)’이라는 개념은 고유의 잠재력을 지닌 플랫폼을 탄생시킨다. 기존의 자료저장공간이나 도박, 금융 등의 하나의 목적에 특화된 폐쇠형 구조(close-ended)와는 달리, 이더리움은 자유롭게 조정이 가능한 구조(open-ended)이다. 우리는 이것이 몇 년 이내에, 금융부문이든 비금융부문이든 엄청나게 많은 종류의 서비스를 설계할 수 있도록 돕는 것에 특화된 기반이 될 것이라고 믿는다. - -## 주석과 추가자료 - -#### 주석 - -1. 관찰력이 좋은 독자라면, 비트코인 주소는 ‘공개키(public key)’가 아니라, ‘타원곡선공개키의 해시(the hash of the elliptic curve public key)’로 이루어져 있다는 것은 눈치챘을 것이다. 물론, 암호학적 관점에서 보자면 ‘공개키 해시(public key hash)’로 부르든 단순히 ‘공개키(public key)’로 부르든 차이는 없다. 왜냐하면, ‘비트코인 암호기법’ 자체가 ‘일종의 맞춤형 전자서명알고리즘’이고, 이 알고리즘에서는 공개키가 ‘타원곡선공개키의 해시(the hash of the Elliptic Curve public key)’를 포함하고 있고, 여기서의 ‘서명(signature)’은 ‘타원곡선서명(ECC signature)’과 연결된 ‘타원곡선공개키(ECC public key)’로 구성되어 있기 때문이다. 또한 ‘검증알고리즘’은 서명(signature) 안의 ‘타원곡선공개키(ECC public key)’를, 공개키로써 제공 된 ‘타원곡선공개키해시(the hash of the elliptic curve public key)’와 대조확인하고, 또한 ‘서명’을 ‘타원곡선공개키(ECC public key)’와 대조하여 검증하는 것이기 때문이다. - -2. 기술적으로는, 이전 11개 블록의 중간값(median)이다. - -3. 내부적으로는 2와 “CHARLIE” 모두 숫자이다. 다만 “CHARLIE”는 ‘빅 엔디언(big-endian)’ 기반의 256비트로 표시한 것이다. 숫자는 0부터 2256-1까지 사용한다. - -#### 추가자료 - -1. Intrinsic value: http://bitcoinmagazine.com/8640/an-exploration-of-intrinsic-value-what-it-is-why-bitcoin-doesnt-have-it-and-why-bitcoin-does-have-it/ -2. Smart property: https://en.bitcoin.it/wiki/Smart_Property -3. Smart contracts: https://en.bitcoin.it/wiki/Contracts -4. B-money: http://www.weidai.com/bmoney.txt -5. Reusable proofs of work: http://www.finney.org/~hal/rpow/ -6. Secure property titles with owner authority: http://szabo.best.vwh.net/securetitle.html -7. Bitcoin whitepaper: http://bitcoin.org/bitcoin.pdf -8. Namecoin: https://namecoin.org/ -9. Zooko's triangle: http://en.wikipedia.org/wiki/Zooko's_triangle -10. Colored coins whitepaper: https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit -11. Mastercoin whitepaper: https://github.com/mastercoin-MSC/spec -12. Decentralized autonomous corporations, Bitcoin Magazine: http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/ -13. Simplified payment verification: https://en.bitcoin.it/wiki/Scalability#Simplifiedpaymentverification -14. Merkle trees: http://en.wikipedia.org/wiki/Merkle_tree -15. Patricia trees: http://en.wikipedia.org/wiki/Patricia_tree -16. GHOST: http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf -17. StorJ and Autonomous Agents, Jeff Garzik: http://garzikrants.blogspot.ca/2013/01/storj-and-bitcoin-autonomous-agents.html -18. Mike Hearn on Smart Property at Turing Festival: http://www.youtube.com/watch?v=Pu4PAMFPo5Y -19. Ethereum RLP: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP -20. Ethereum Merkle Patricia trees: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree -21. Peter Todd on Merkle sum trees: http://sourceforge.net/p/bitcoin/mailman/message/31709140/ diff --git a/pages/other-languages/[persian]-white-paper.md b/pages/other-languages/[persian]-white-paper.md deleted file mode 100644 index 4588d4cae..000000000 --- a/pages/other-languages/[persian]-white-paper.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: White Paper -category: ---- - -# پلتفرم نسل بعدی قراردادهای هوشمند و نرم افزارهای غیر متمرکز -در چند ماه گذشته خیل عظیمی از علاقه مندی جهت استفاده از بلاک چین های نظیر بیت کوین وجود داشته است. - مکانیزمی که امکان توافقی جهانی را بر روی پایگاه داده ای از اطلاعات تملک افراد فراهم می آورد. - به عنوان چیزی بیش از صرفا یک پول! -این کاربردها عموما شامل دسترسی دیجیتالی مبتنی بر بلاک چین به ارزهای طراحی شده در این سیستم و ابزارهای مالی می شوند. (سکه های رنگی) «دارایی های هوشمند» ابزارهایی هستند مانند یک خودرو که یک سکه رنگی را بر روی یک بلاک چین دنبال میکنند تا مالک قانونی خود را معین کنند که به خوبی سایر نرم افزارهای مدرن نظیر صرافی غیر متمرکز، مشتقات مالی، بازی های بخت آزمایی نظیر به نظیر و هویت مبتنی بر بلاک چین و سیستم های اعتباری کار میکنند. -شاید بلند پروازانه ترین مورد در بین تمام برنامه های ذکر شده، مفهوم عوامل خودمختار یا سازمان خودمختار و غیر متمرکز (DAOs ) باشد- نهادهایی مستقل که در بلاک چین عمل میکنند و هیچ گونه کنترل مرکزی ندارند، اجتناب از هرگونه وابستگی به قراردادهای قانونی و آیین نامه های سازمانی با هدف داشتن منابع و بودجه مستقل توسط یک قرارداد هوشمند خودمختار که در بلاک چینی رمزنگاری شده اداره می شود. -با این حال، امروزه پیاده سازی بسیاری از این برنامه های کاربردی دشوار است، چرا که سیستم های برنامه نویسی بیت کوین و حتی نسل بعدی پروتکل های ارزهای رمزنگاری شده مانند بیت کوین مبتنی بر پروتکل سکه های رنگی و به اصطلاح "metacoins"، به مراتب محدودتر از آن هستند که اجازه انجام محاسبات دلخواه و پیچیده مورد نیاز DAOها را فراهم آورند. -کاری که این پروژه در صدد انجام آن است گرفتن نوآوری پروتکلهای اینچنین و ایجاد فضای کار رمزنگاری شده ای کاملا تکامل یافته و ….. (ولی با قواعد آزاد) است که به شرکت کنندگان امکان نگارش قراردادهای دلخواه پیچیده را می دهد، عوامل و روابطی که کاملا توسط بلاک چین نمایندگی خواهند شد. -کاربران بسیار بیشتر از آنکه محدود به یک سری انواع تراکنش ها باشند قادر خواهند بود از اتریوم به عنوان مجموعه ای از لگوهای ابزارهای مالی رمزنگاری شده استفاده کنند. گفته میشود که فرد قادر خواهد بود از هر قابلیتی که افراد در زبان های برنامه نویسی داخل کامپیوتر در اختیار دارند استفاده کند. -ارزهای سفارشی، مشتقات مالی، سیستم های تشخیص هویت و سازمانهای غیر متمرکز همگی به راحتی قابل اجرا خواهند بود، اما از همه مهمتر اینکه بر خلاف سیستم های قبلی امکان ایجاد آن دسته از تراکنشهایی که توسعه دهندگان ایتریوم حتی تصور آن را نمی کرده اند نیز فراهم است. امیدواریم ایتریوم به خوبی به عنوان تکمله ای بر اکوسیستم پول های رمزنگاری شده مورد توجه قرار گیرد چنانکه ظهور وب ۲ برای اینترنت غیر پویای سال ۱۹۹۹ بود. - diff --git a/pages/other-languages/[romanian]-patricia-tree.md b/pages/other-languages/[romanian]-patricia-tree.md deleted file mode 100644 index ce5bfdc45..000000000 --- a/pages/other-languages/[romanian]-patricia-tree.md +++ /dev/null @@ -1,137 +0,0 @@ ---- -name: Patricia Tree -category: ---- - -###Specificatiile Arborelui Merkle Patricia - -Arborele Merkle Patricia furnizeaza o structura autentificata cryptografic de date care poate fi folosita pentru stocarea tuturor legaturilor (key, valori), desi pentru scopul acestui document restrictionam valorile si keys la siruri (pentru a inlatura aceasta restrictie, folositi orice format de serializare pentru alte tipuri de date). Ele sunt complet deterministe, insemnand ca un arbore Patricia cu aceeasi legatura (valoare, key) va fi exact la fel pana la ultimul byte si astfel va avea aceeasi radacina hash, va furniza the holy grail al eficientei O(log(n)) pentru insertii, cautari si stergeri, si sunt mult mai usor de inteles si de codat decat alte alternative mai complexe bazate pe comparatii cum ar fi arborii rosu-negru. - -###PREAMBUL : Arborii Radix de baza - -Intr-un arbore de baza radix, fiecare nod arata astfel: - - [ value, i0, i1 ... in] - -Unde i0… in reprezentarea valorii simbolurilor alfabetului (deseori binare sau hex) este valoarea terminala a nodului, si valorile din i0… in sloturi sunt fie NULL fie indicatoare (in cazul nostr hash-uri) pentru alte noduri. Aceasta formeaza un stoc de baza (key, valoare), de exemplu, daca esti interesat de valoarea din arbore a obiectului “dog”, intai va trebui efectuata convertirea in alfabet ( rezultand 646f67 daca folosim hex), iar apoi de coboara pe traiectoria arborelui pana la sfarsitul ei, unde se poate citi valoarea. Adica, intai se cauta hash-ul radacina in stocarea key/value pentru a ajunge la nodul radacina, dupa care se cauta nodul 6 al nodului radacina, pentru a cobori acel nod cu un nivel, apoi se cauta nodul 4 al acestui rezultat, urmand nodul 6, si tot asa, mergand pe urmatoarul traseu root ->6->4->6->f->6->7, iar la sfarsit se cauta valoarea nodului obtinut si se returneaza rezultatul. - -Update-urile si operatiile de stergere pentru arborele radix sunt simple, si pot fi definite mai pe scurt dupa cum urmeaza: - -``` -def update(node,key,value): - if key == '': - curnode = db.get(node) if node else [ NULL ] * 17 - newnode = curnode.copy() - newnode['value'] = value - else: - curnode = db.get(node) if node else [ NULL ] * 17 - newnode = curnode.copy() - newindex = update(curnode[key[0]],key[1:],value) - newnode[key[0]] = newindex - db.put(hash(newnode),newnode) - return hash(newnode) - -def delete(node,key): - if key == '' or node is NULL: - return NULL - else: - curnode = db.get(node) - newnode = curnode.copy() - newindex = delete(curnode[key[0]],key[1:]) - newnode[key[0]] = newindex - if len(filter(x -> x is not NULL, newnode)) == 0: - return NULL - else: - db.put(hash(newnode),newnode) - return hash(newnode) -``` - -Partea “Merkle” din arborele radix provine din faptul ca hash-ul cryptografic deterministic al unui nod este utilizat ca indicator spre nod, si nu dintr-o locatie de memorie 32-bit sau 64-bit cum s-ar putea intampla intr-un arbore mai traditional implementat in C. Acesta furnizeaza o forma de autentificare cryptografica la structura datelor. Daca radacina hash a unui trie este cunoscuta public, atunci oricine poate furniza o dovada a unei (key/valori) perechi care nu exista din moment ce hash-ul radacina este bazat pe toate hash-urile de sub el, deci orice modificari ar schimba radacina hash. - -Cu toate acestea, arborii radix au o limitare majora: ineficienta. In cazul in care se doreste stocarea doar unei legaturi (key/valoare) unde key are o lungime de cateva sute de caractere, va fi necesar un KB de spatiu extra pentru a stoca cate un pivel per caracter, iar fiecare cautare sau stergere va insemna sute de pasi. Arborele Patricia rezolva aceasta problema. - -###Specificatie: Codarea compacta a secventei hex cu terminator optional - -Modul compact traditional de a coda un sir hex este de a-l converti in binar , adica un sir ca 0f1248 ar deveni 3 bytes 15,18,72. Cu toate acestea, aceasta abordare are o mica problema: daca lungimea sirului este impara? In acest caz, nu exista nici o modalitate de a distinge sirurile 0f1248 si f1248. In plus, aplicatia noastra in Arborele Merkle Patricia necesita trasatura aditionala cu care un sir hex poate avea un “simbol special terminator” la sfarsit (denotat de ‘T’). Un simbol terminator poate aparea o singura data, si doar la sfarsitul unui sir. Un mod alternativ de a privi lucrurile ar fi sa nu ne gandim la existenta unui simbol terminator, ""but instead treat bit specifying the existence of the terminator symbol as a bit specifying that the given node encodes a final node, where the value is an actual value, rather than the hash of yet another node."" - -Pentru a rezolva ambele probleme, fortam primul nibble al bytestreamului final pentru a coda doua flags, specificand ca lungimea e impara (ignorand simbolul T) si statusul terminator, acestea sunt plasate, respectiv, in cei mai de jos doi biti ai primului nibble.In eventualitatea in care un sir hex este par, trebuie introdus un al doile nibble (cu valoarea zero) pentru a asigura ca sirul hex este par in lungime si astfel este reprezentabil prin un numar intreg de bytes. Astfel putem construi urmatoarea codare: - -``` -def compact_encode(hexarray): - term = 1 if hexarray[-1] == 16 else 0 - if term: hexarray = hexarray[:-1] - oddlen = len(hexarray) % 2 - flags = 2 * term + oddlen - if oddlen: - hexarray = [flags] + hexarray - else: - hexarray = [flags] + [0] + hexarray - // hexarray now has an even length whose first nibble is the flags. - o = '' - for i in range(0,len(hexarray),2): - o += chr(16 * hexarray[i] + hexarray[i+1]) - return o -``` -Exemple: -``` -> [ 1, 2, 3, 4, 5 ] -'\x11\x23\x45' -> [ 0, 1, 2, 3, 4, 5 ] -'\x00\x01\x23\x45' -> [ 0, 15, 1, 12, 11, 8, T ] -'\x20\x0f\x1c\xb8' -> [ 15, 1, 12, 11, 8, T ] -'\x3f\x1c\xb8' -``` -###Principalele specificatii: Arborele Merkle Patricia - -Arborele Merkle Patricia rezolva problemele prezentate mai sus prin adaugarea unei extra complexitati structurii datelor. Un nod intr-un arbore Merkle Patricia este unul dintre urmatoarele: - -1. NULL (reprezentat ca un sir gol) -2. O multime cu doua elemente [key.valoare] -3. O multime de 17 elemente [v0…v15, vt] - -Ideea este aceea ca in eventualitatea in care exista o ruta lunga de noduri fiecare cu un singur element, facem un shortcut la un descent prin setarea unui nod [key/valoare], unde key coboara traiectoria hexadecimala, in codarea compacta descrisa mai sus, si valoarea este doar hash-ul nodului, la fel ca in arborele radix standard. Deasemenea, mai adaugam o schimbare conceptuala: nodurile interne nu mai au valori, only leaves with no children of their own can, cu toate acestea, pentru a fi generici vrem ca stocarea valoarea/key sa poata stoca keys cum ar fi “dog”, “doge” in acelasi timp, doar adaugam un simbol terminator (16) la alfabet astfel incat sa nu existe niciodata o valoare “en-route” pentru o alta valoare. Unde un nod are o referinta in alt nod, care este inclus H(rlp.encode(x)) unde H(x) = sha3(x) if len(x) >= 32 altfel x si codarea rlp este functia codarii RLP. Retineti ca in momentul updatarii unui trie, va trebui stocata perechea key/valoare (sha3(x), x) intr-un tabel de cautare persistenta cand se creeaza un nod cu lungimea >=32, dar daca nodul este mai scurt de atat nu este necesara cand lungimea <32 pentru ca functia f(x)=x este reversibila. - -Mai jos este codul extins pentru a obtine un nod intr-un arbore Merkle Patricia: -def get_helper(node,key): -``` - if key == []: return node - if node = '': return '' - curnode = rlp.decode(node if len(node) < 32 else db.get(node)) - if len(curnode) == 2: - (k2, v2) = curnode - k2 = compact_decode(k2) - if k2 == key[:len(k2)]: - return get(v2, key[len(k2):]) - else: - return '' - elif len(curnode) == 17: - return get_helper(curnode[key[0]],key[1:]) - -def get(node,key): - key2 = [] - for i in range(len(key)): - key2.push(int(ord(key) / 16)) - key2.push(ord(key) % 16) - key2.push(16) - return get_helper(node,key2) -``` -Exemplu: presupunem ca avem un arbore care contine perechile ('dog', 'puppy'), ('horse', 'stallion'), ('do', 'verb'), ('doge', 'coin'). In primul rand convertim keys in format hex: -``` -[ 6, 4, 6, 15, 16 ] : 'verb' -[ 6, 4, 6, 15, 6, 7, 16 ] : 'puppy' -[ 6, 4, 6, 15, 6, 7, 6, 5, 16 ] : 'coin' -[ 6, 8, 6, 15, 7, 2, 7, 3, 6, 5, 16 ] : 'stallion' -``` -Acum alcatuim arborele: -``` -ROOT: [ '\x16', A ] -A: [ '', '', '', '', B, '', '', '', C, '', '', '', '', '', '', '', '' ] -B: [ '\x00\x6f', D ] -D: [ '', '', '', '', '', '', E, '', '', '', '', '', '', '', '', '', 'verb' ] -E: [ '\x17', F ] -F: [ '', '', '', '', '', '', G, '', '', '', '', '', '', '', '', '', 'puppy' ] -G: [ '\x35', 'coin' ] -C: [ '\x20\x6f\x72\x73\x65', 'stallion' ] -``` \ No newline at end of file diff --git a/pages/other-languages/[romanian]-rlp.md b/pages/other-languages/[romanian]-rlp.md deleted file mode 100644 index 38b38565c..000000000 --- a/pages/other-languages/[romanian]-rlp.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -name: RLP -category: ---- - -Scopul RLP este acela de a coda matrici grupate arbitrar de date binare, si RLP este principala metoda folosita pentru a serializa obiecte in Ethereum. Singurul scop al RLP este acela de a coda structuri, codarea unor tipuri specifice de date atomice (strings, ints, float) sunt lasate pentru alte protocoale de ordin superior; in Ethereum standardul este reprezentarea numerelor intregi in forma endiana binara. Daca cineva doreste sa utilizeze RLP pentru a coda un dictionar, cele doua forme canonice sugerate vor folosi `[[k1,v1],[k2,v2]...]` keys in ordine lexicografica sau vor folosi codarea Patricia Tree, ca la Ethereum. - -###Definitie - -Functia de encodare RLP preia un element. Un element este definit dupa cum urmeaza: -- Un sir (ex. o matrice octet) este un element -- O lista de elemente este un element -De exemplu, un sir gol este un element, cum este sirul care conține cuvantul "pisica", o lista ce contine orice numar de siruri, ca si structuri de date mai complexe precum` ["pisica",["catelus","vaca"],"cal",[[]],"porc",[""],"oaie"]`. Retineti ca in contextul acestui articol, “sir” va fi folosit ca un sinonim pentru “un anumit numar de bytes de date binare”, nu sunt folosite codari speciale si nu implica resurse legate de continutul sirurilor. -Codarea RLP este definita dupa cum urmeaza: --Pentru un singur byte a carui valoare se incadreaza in `[0x00, 0x7f]` , acel byte este propria sa codare RLP. --Altfel, daca un sir are o lungime de 0-55 bytes, codarea RLP consta intr-un singur byte cu o valoare de 0x80 plus lungimea sirului, urmata de sir. Astfel, primul byte se incadreaza in intervalul `[0x80, 0xb7]`. --Daca un sir este mai lung de 55 bytes, codarea RLP consta intr-un singur byte cu valoarea 0xb7 plus lungimea lungimii sirului in forma binara, urmata de lungimea sirului,urmata de sir. De exemplu, un sir de o lungime 1024 ar fi codat \xb9\x04\x00 , urmat de sir. Intervalul in care se incadreaza primul byte este, deci, `[0xb8, 0xbf]`. - -- Daca sarcina utila a unei liste (payload) (ex. Suma lungimilor elementelor sale) are o lungime de 0-55 bytes, codarea RLP consta intr-un singur byte cu valoarea de 0xc0 plus lungimea listei urmata de concatenarea/juxtapunerea codarii RLP a elementelor. Intervalul in care se incadreaza primul byte este `[0xc0, 0xf7]`. -- Daca sarcina utila a unei liste (payload) este mai mare de 55 bytes, codarea RLP consta intr-un singur byte cu valoarea de 0xf7 plus lungimea lungimii listei in forma binara, urmata de lungimea listei , urmata de concatenarea/juxtapunerea codarii RLP a elementelor. Intervalul in care este plasat primul octet este `[0xf8, 0xff]`. - -Codul, arata astfel: -```python -def rlp_encode(input): - if isinstance(input,str): - if len(input) == 1 and chr(input) < 128: return input - else: return encode_length(len(input),128) + input - elif isinstance(input,list): - output = encode_length(len(input),192) - for item in input: output += rlp_encode(item) - return output - -def encode_length(L,offset): - if L < 56: - return chr(L + offset) - elif L < 256**8: - BL = to_binary(L) - return chr(len(BL) + offset + 55) + BL - else: - raise Exception("input too long") - -def to_binary(x): - return '' if x == 0 else to_binary(int(x / 256)) + chr(x % 256) -``` - -###Exemple: - -Sirul “dog”= `[ 0x83, 'd', 'o', 'g' ]` - -Lista [ "cat", "dog" ] = `[ 0xc8, 0x83, 'c', 'a', 't', 0x83, 'd', 'o', 'g' ]` - -Sirul gol ('null') = `[ 0x80 ]` - -Lista goala =`[ 0xc0 ]` - -Numarul intreg 15= `[ 0x0f ]` - -Numarul intreg 1024 =`[ 0x82, 0x04, 0x00 ]` - -Reprezentarea teoretica a setului de 2 , [ [], [[]], [ [], [[]] ] ] = `[ 0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc1, 0xc0 ]` - -Sirul "Lorem ipsum dolor sit amet, consectetur adipisicing elit" = `[ 0xb8, 0x38, 'L', 'o', 'r', 'e', 'm', ' ', ... , 'e', 'l', 'i', 't' ]` diff --git a/pages/other-languages/[romanian]-white-paper.md b/pages/other-languages/[romanian]-white-paper.md deleted file mode 100644 index 9ad87df31..000000000 --- a/pages/other-languages/[romanian]-white-paper.md +++ /dev/null @@ -1,559 +0,0 @@ ---- -name: White Paper -category: ---- - -###Ethereum: O platforma de aplicatii descentralizata ce faciliteaza crearea de contracte inteligente de ultima generatie. - -In ultimele cateva luni s-a manifestat un interes tot mai mare fata de utilizarea blockchain-urilor de tip Bitcoin- mecanismul care da intregii lumi sansa sa ajunga la un consens in privinta unei baze de date publice- pentru mai mult decat bani.Aplicatii frecvent citate includ utilizarea bunurilor digitale on-blockchain pentru a reprezenta valute personalizate si instrumente financiare ("[colored coins](https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit)"), dispozitive ["smart property"](https://en.bitcoin.it/wiki/Smart_Property) cum ar fi masinile, care pot urmari un "colored coin" pe un blockchain pentru a determina proprietarul legitim al acestora, insa exista si aplicatii mult mai avansate cum ar fi schimburi decentralizate, derivate financiare,peer-to-peer gambling(?) si sisteme on-blockchain de identitate/reputatie. Dintre toate aceste tipuri de aplicatii, poate cel mai ambitios este conceptul de agenti autonomi sau [Organizatii Autonome Descentralizate](http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/) (DAOs) - entitati autonome care opereaza in blockchain fara nici un fel de control central, evitand orice dependenta de contracte legale si statuturi organizatorice in favoarea resurselor si fondurilor administrate autonom de un smart-contract auto-impus pe un blockchain cryptografic. - -Totusi, majoritatea acestor aplicatii sunt dificil de implementat astazi, din simplul motiv ca sistemele de scripting ale Bitcoin, si chiar ale protocoalelor cryptocurrency de ultima generatie, cum ar fi protocoalele "colored coin" si asa-numitele "metacoins", sunt mult prea limitate pentru a permite metodele arbitrare complexe de calcul pe care DAO le solicita. Ceea ce intentioneaza acest proiect sa faca este sa preia inovatia adusa de astfel de protocoale si sa le generalizeze- create a fully-fledged, Turing-complete (but heavily fee-regulated) cryptographic ledger that allows participants to encode arbitrarily complex contracts, autonomous agents and relationships that will be mediated entirely by the blockchain. In loc sa se limiteze la un tip specific de tranczactii, utilizatorii vor putea folosi Ethereum ca un fel de "Lego de crypto-finante"-altfel spus, acestia vor putea implementa orice proprietate doresc doar prin codarea in limbajul scriptic intern protocolului.Valutele personalizate, derivatele financiare, sistemele de identitate si organizatiile decentralizate vor fi usor de facut, dar, mai important,spre deosebire de sistemele anterioare, va fi posibila construirea unor tipuri de tranzactii pe care nici macar dezvoltatorii Ethereum nu le-au prevazut.Per ansamblu, credem ca acest proiect este un pas in fata spre realizarea "cryptocurrency 2.0"; speram ca Ethereum va fi la fel de important in ecosistemul cryptocurrency pe cat a fost de semnificativa aparitia Web 2.0 pentru static-content-only internet in 1999. - -### Continut - -* [De ce o noua platforma](#de-ce-o-noua-platforma) - * [Colored Coins](#colored-coins) - * [Metacoins](#metacoins) -* [Filozofie](#philosophy) -* [Constructia de blocuri de date](#basic-building-blocks) - * [Implementarea GHOST modficata](#modified-ghost-implementation) - * [Ethereum Client P2P Protocol](#ethereum-client-p2p-protocol) - * [Moneda si emitere](#currency-and-issuance) - * [Formatul datei](#data-format) - * [Algoritmul de minare](#mining-algorithm) - * [Tranzactii](#transactions) - * [Adjustarea dificultatii](#difficulty-adjustment) - * [Rasplata pentru blocuri](#block-rewards) -* [Contracte](#contracts) - * [Aplicatii](#applications) - * [Sub-monede](#sub-currencies) - * [Derivate financiare](#financial-derivatives) - * [Sisteme de reputatie si identitate](#identity-and-reputation-systems) - * [Organizatii Autonome Descentralizate](#decentralized-autonomous-organizations) - * [Aplicatii ce vor urma](#further-applications) - * [Cum functioneaza contractele?](#how-do-contracts-work) - * [Specificatii referitoare la limbajul de programare](#language-specification) -* [Taxe](#fees) -* [Concluzii](#conclusion) -* [References and Further Reading](#references-and-further-reading) - - -## De ce o noua platforma - -Cand se doreste creearea unei noi aplicatii, in special intr-un domeniu delicat ca al criptografiei sau cryptocurrency, primul si cel mai corect instinct este acela de a se folosi protocoale existente pe cat mai mult posibil. Nu este nevoie sa se creeze un nou etalon monetar, sau chiar un nou protocol atunci cand problema poate fi rezolvata prin utilizarea tehnologiilor deja existente. Intradevar, complexitatea incercarilor de rezolvare a problemelor de smart property, smart contracts si corporatii autonome descentralizate, pe langa Bitcoin, este modul in care a aparut interesul fata de protocoalele cryptocurrency de ultima generatie. In decursul cercetarii noastre, totusi, devine evident ca in timp ce protocolul Bitcoin este mai mult decat adecvat pentru valuta, basic multisignature escrow and certain simple versions of smart contracts, there are fundamental limitations that make it non-viable for anything beyond a certain very limited scope of features. - - -###Colored Coins - -Prima incercare de a implementa un sistem de administrare pentru smart property si valute personalizate si bunuri pe un blockchain a fost construita ca un fel de supra-protocol al Bitcoin-ului, pe care multi l-au comparat, in anumite privinte cu felul in care, in suita de protocoale a internetului, HTTP functioneaza ca un strat asupra TCP-ului. Colored coins protocol este definit dupa cum urmeaza: - -Un emitent al colored coin determina ca output-ul unei anumite tranzactii H:i (H being the transaction hash and i the output index)reprezinta un anumit bun si publica o "color definition" specificand output-ul acestei tranzactii alaturi de ceea de ce reprezinta(ex. 1 satoshi de la H:i = 1 gram de aur rambursabil la Stephen's Gold Company) -Others "install" the color definition file in their colored coin clients. -Cand o culoare este emisa pentru prima data, output-ul H:i este singura tranzactie output care are acea culoare. -Daca o tranzactie foloseste input-uri cu o culoare X, atunci si output-ul va avea culoarea X. De exemplu, daca posesorul lui H:i face o tranzactie imediat, pentru a imparti acest output catre cinci adrese, atunci rezultatele acestei tranzactii vor avea, de asemenea, culoarea X. Daca o tranzactie are input-uri de culori diferite, atunci o "lege a transferului culorii" sau un "nucleu al culorii" va determina ce culoare are fiecare output (ex. o implementare mai facila ar determina culoarea output-ului 0 sa fie aceeasi cu cea a input-ului 0, output-ul 1 ar avea aceeasi culoare cu input-ul 1, etc) -Cand un client colored coin observa ca primeste un nou output al tranzactiei, foloseste in algoritm back-tracing bazat pe "nucleul culorii" pentru a determina culoarea acelui output.Pentru ca regula este determinista, toti clientii vor cadea de acord pentru a stabili ce culoare (sau culori) are fiecare output. -Cu toate acestea, protocolul are cateva imperfectiuni fundamentale: - -Verficarea platilor simplificate in Bitcoin - - -Stanga: este suficient sa se prezinte doar un numar mic de noduri intr-o schema Merkel pentru a dovedi validitatea unei ramuri. -Dreapta: orice incercare de a schimba orice parte a schemei Merkel va duce in cele din urma la o inconsecventa undeva in varful latului. -Dificultatea verificarii platilor simplificate- Constructia Schemei Merkel a Bitcoin-ului permite un protocol cunoscut ca "verificarea platilor simplificate", unde un client care nu downloadeaza intregul blockchain poate determina rapid validitatea unui output al unei tranzactii prin a cere altor noduri o dovada criptografica a valabilitatii unei ramuri a schemei. Clientul tot va trebui sa downloadeze header-ele block-ului, pentru a fi sigur, dar cantitatea de date (the amount of data bandwidth ) si timpul de verificare necesar scad cu un factor de aproape o mie.Cu colored coins insa, acest proces este mult mai dificil.Motivul este acela ca nu se poate determina culoarea unui output al unei tranzactii doar prin verficarea schemei Merkel; cu atat mai mult, trebuie folosit algoritmul de scanare inversa, prelundu-se mii de tranzactii si solicitandu-se dovada schemei Merkel de valabilitate pentru fiecare in parte, inainte ca un client sa fie pe deplin satisfacut ca o tranzactie are o anumita culoare. Dupa un an de investigatii, inclunzand si ajutorul nostru, nu s-a putut gasi nici o solutie pentru aceasta problema. -Incompatibilitatea cu script-urile- dupa cum am mentionat si mai sus, Bitcoin are un sistem de scripting flexibil moderat, de exemplu permite utilizatorilor sa semneze tranzactii de forma "Eliberez output-ul acestei tranzactii oricui este dispus sa plateasca 1 BTC". Alte exemple includ contracte de asigurare, microplati eficiente si licitatii on-blockchain. Cu toate acestea, acest sistem, in mod inerent, nu tine cont de culoare, altfel spus, clientul poate face o tranzactie de forma "Eliberez output-ul acestei tranzactii oricui este dispus sa imi plateasca o gold coin definita de originea H:i",pentru ca limbajul scriptului nu stie ca exista conceputl de "culoare".O consecinta majora a acestui lucru este ca in timp ce un schimb sigur intre doua colored coins este posibil, un schimb total descentralizat devine imposibil de obtinut,in conditiile in care nu exista o modalitate de a plasa o comanda de executare pentru a vinde sau pentru a cumpara. -Aceleasi limitari ca ale Bitcoin-ului -ideal, protocoalele on-blockchain ar trebui sa suporte derivate avansate, pariuri si multe forme de transferuri conditionale.Din pacate, colored coins mostenesc limitarile Bitcoin-ului in ceea ce priveste imposibilitatea existentei atator aranjamente. -Metacoins - -Alt concept, asezat deasupra Bitcoin-ului in spiritul HTTP, care este deasupra TCP-ului, este acela de "metacoins". Conceptul unui metacoin este simplu: protocolul metacoin furnizeaza calea de codare a datelor unei tranzactii metacoin in output-ul unei tranzactii Bitcoin, iar un nod metacoin functioneaza prin procesarea tuturor tranzactiilor Bitcoin si evaluarea tranzactiilor Bitcoin care sunt tranzactii metacoin valide pentru a determina balantele contului oricand.Spre exemplu, un protocol simplu metacoin poate solicita patru output-uri unei tranzactii: MARKER, FROM, TO and VALUE. MARKER ar fi o adresa de marcaj specifica pentru a identifica o tranzactie ca o tranzactie metacoin.FROM ar fi adresa de la care sunt trimise coins;TO- adresa unde sunt trimise acestea si VALUE ar fi adresa care codeaza cantitatea trimisa. Deoarece protocolul Bitcoin nu este constientizeaza metacoins, si astfel nu va respinge tranzactii metacoin invalide, protocolul metacoin trebuie sa trateze toate tranzactiile cu primul output in MARKER ca fiind valide si sa reactioneze in consecinta. De exemplu, o punere in aplicare a partii de procesare a tranzactiilor protocolului metacoin descris mai sus s-ar putea arata astfel: - - if tx.output[0] != MARKER: - break - else if balance[tx.output[1]] < decode_value(tx.output[3]): - break - else if not tx.hasSignature(tx.output[1]): - break - else: - balance[tx.output[1]] -= decode_value(tx.output[3]); - balance[tx.output[2]] += decode_value(tx.output[3]); -Avantajul unui protocol metacoin este acela ca protocolul poate permite mai tipuri de tranzactii avansate , incluzand valute personalizate, schimburi descentralizate, etc, care sunt imposibil de implementat folosind doar protocolul care sta la baza Bitcoin. Cu toate acestea, metacoins peste Bitcoin au un mare defect: verificarea platilor simplificate, deja dificil de facut cu colored coins, devine complet imposibila cu o metacoin.Motivul este acela ca se poate folosi SPV pentru a determina daca exista o tranzactie care trimite 30 metacoins la adresa X, dar in sine nu inseamna ca adresa X are 30 metacoins.Daca emitentul tranzactiei nu are 30 metacoins de la inceput si tranzactia este invalida? In cele din urma, aflarea oricarei parti din stadiul curent necesita scanarea tuturor tranzactiilor efectuate de la lansarea metacoin-ului pentru a stabili validitatea fiecarei tranzactii in parte. Astfel, devine imposibil posesia unui client sigur, fara a se downloada intregul blockchain Bitcoin. - -In ambele cazuri, concluzia este urmatoarea: efortul de a construi protocoale mai avansate deasupra Bitcoin-ului, ca HTTP peste TCP, este admirabil, si este intradevar modul corect de a aborda punerea implementarea aplicatiilor descentralizate avansate.Cu toate acestea, incercarea de a construi colored coins si metacoins peste Bitcoin seamana mai mult cu construirea HTTP peste SMTP. Scopul SMTP a fost acela de a transfera email-uri , nu sa serveasca drept motor principal pentru comunicare generica pe internet, iar pentru a-l face eficace ar fi trebuit implementate practici ineficiente si inestetice arhitectural. - -Ethereum rezolva problemele de scalabilitate, fiind hostat pe propriul blockchain, si prin stocarea unui "state tree" distinct in fiecare block impreuna cu o lista a tranzactiilor.Fiecare "state tree" reprezinta stadiul curent al intregului sistem , incluzand balantele adreselor si starea contractelor.Contractele Ethereum pot stoca datele in memorie(contracts are allowed to store data in a persistent memory storage). Aceasta stocare, combinata cu limbajul de scripting Turing-complete,ne permite sa codam un intreg etalon monetar intr-un singur contract, alaturi de numeroase alte tipuri de bunuri criptografice.Prin urmare, intentia Ethereum nu este aceea de a inlocui protocoalele colored coin si metacoin descrise mai sus. Mai degraba, Ethereum intentioneaza sa serveasca drept un strat fundamental superior oferind un sistem unic si puternic de scripting pe baza caruia se pot construi contracte arbitrare avansate, valute si alte aplicatii descentralizate.Daca proiectele deja existente de colored coins si metacoins s-ar muta in Ethereum , ar beneficia de SPV-ul oferit de Ethereum, de optiunea de a fi compatibile cu derivatele financiare ale Ethereum si de abilitatea de a lucra impreuna intr-o singura retea.Cu Ethereum, cineva care are o idee pentru un nou tip de contract sau tranzactie care poate imbunatati in mod considerabil ceea ce se poate face cu cryptocurrency nu ar mai trebui sa isi lanseze propria moneda; isi poate implementa simplu ideea in codul script al Ethereul. Pe scurt, Ethereum este o fundatie pentru inovatie. - - -###Filozofie - -Designul care sta in spatele Ethereum este creat sa urmeze principiile enumerate mai jos: - -Simplitate - Protocolul Ethereum trebuie sa fie cat mai simplu posibil, chiar si cu riscul unor ineficiente in ceea ce ce priveste timpul sau stocarea de date. Ideal, un programator obisnuit ar trebui sa poata urmari si implementa toate specificatiile, astfel incat sa se poata realiza pe deplin potentialul de democratizare fara precedent pe care cryptocurrency il aduce si sa promoveze Ethereum ca un protocol deschis tuturor.Orice optimizare ce adauga complexitate nu ar trebui inclusa decat in cazul in care acea optimizare poate aduce un beneficiu substential. -Universalitate - o parte fundamentala a filosofiei design-ului Ethereum este aceaa ca nu are "trasaturi". In loc de acest lucru, Ethereum asigura un limbaj de scripting intern Turing-complete, pe care un programator il poate folosi pentru a realiza orice smart contract sau tip de tranzactie ce poate fi definita matematic.Vrei sa iti realizezi propriul derivat financiar? Cu Ethereum poti face asta.Vrei sa iti faci propria valuta?Seteaz-o ca un contract Ethereum. Vrei sa instalezi Daemon sau Skynet la o scara larga?Cel mai probabil vei avea nevoie de cateva mii de contracte centralizate, si ai grija sa le feed them generously,pentru a realiza acest lucru, dar nu te opreste nimic daca ai Ethereum la dispozitie. -Modularitate - Partile protocolului Ethereum ar trebui construite modular, si, pe cat posibil, astfel incat sa poata fi separate.Pe parcursul dezvoltarii noaste, scopul este acela de a crea un program unde daca cineva ar face o mica modificare a protocolului, aplicatia ar continua sa functioneze fara alte modificari.Inovatii precum Dagger, Patricia trees si RLP trebuie implementate ca librarii separate si trebuie facute cu "trasaturi complete" chiar daca Ethereum nu are nevoie de anumite "trasaturi" pentru a le face utile si in alte protocoale.Dezvoltarea Ethereum trebuie realizata la cote maxime, spre beneficiul intrecugul ecosistem cryptocurrency, nu doar pentru al lui in sine. -Agilitate - detaliile protocolului Ethereum nu sunt de neclintit.details of the Ethereum protocol are not set in stone. Desi vom fi destul de judiciosi in legatura cu efectuarea modificarilor in constructii de nivel inalt cum ar fi limbajul de tipul C si sistemul de adrese, teste computationale efectuate ulterior ne pot conduce la concluzia ca anumite modificari ale algoritmului sau al limbajului de programare pot imbunatati considerabil scalabilitatea sau securitatea. In cazul in care se ivesc astfel de oportunitati, le vom explora. -Nondiscriminare- protocolul nu trebuie sa incerce sa resctrictioneze activ sau sa previna categorii de uzabilitate specifice.Toate mecanismele de reglementare din protocol trebuie sa fie create in asa fel incat sa regleze prejudicii si sa incerce sa nu se opuna unor anumite aplicatii nedorite specifice. Un programator poate chiar sa administreze un loop script peste Ethereum atat timp cat intentioneaza sa plateasca taxa pentru fiecare pas al tranzactiei. - -Basic Building Blocks - -La origine, Ethereum este a fairly regular memory-hard proof-of-work mined cryptocurrency without many extra complications. De fapt, Ethereum este , din anumite puncte de vedere, mai simplu decat cryptocurrencies bazate pe Bitcoin folosite astazi.Conceptul conform caruia o tranzactie poate avea mai multe output-uri si input-uri, de exemplu, a fost inlocuit cu model bazat pe balante mai intuitiv( pentru a preveni replay-attacks, (to prevent transaction replay attacks, as part of each account balance we also store an incrementing nonce). Sequence numbers and lock times are also removed, and all transaction and block data is encoded in a single format. Instead of addresses being the RIPEMD160 hash of the SHA256 hash of the public key prefixed with 04, addresses are simply the last 20 bytes of the SHA3 hash of the public key. Unlike other cryptocurrencies, which aim to offer a large number of "features", Ethereum intends to take features away, and instead provide its users with near-infinite power through an all-encompassing mechanism known as "contracts". - - -La origine, Ethereum este a fairly regular memory-hard proof-of-work mined cryptocurrency without many extra complications. De fapt, Ethereum este , din anumite puncte de vedere, mai simplu decat cryptocurrencies bazate pe Bitcoin folosite astazi.Conceptul conform caruia o tranzactie poate avea mai multe output-uri si input-uri, de exemplu, a fost inlocuit cu model bazat pe balante mai intuitiv( pentru a preveni replay-attacks, (to prevent transaction replay attacks, as part of each account balance we also store an incrementing nonce). Sequence numbers and lock times are also removed, and all transaction and block data is encoded in a single format. Instead of addresses being the RIPEMD160 hash of the SHA256 hash of the public key prefixed with 04, addresses are simply the last 20 bytes of the SHA3 hash of the public key. Unlike other cryptocurrencies, which aim to offer a large number of "features", Ethereum intends to take features away, and instead provide its users with near-infinite power through an all-encompassing mechanism known as "contracts". - - -Modified GHOST Implementation - -Protocolul "Greedy Heavist Observed Subtree" (GHOST) este o inovatie introdusa de Yonatan Sompolinsky si Aviv Zohar in Decembrie 2013. Motivul din spatele GHOST este acela ca in prezent, blockchains cu rata mare de confirmare sufera de probleme de securitate datorate unui stale rate ridicat – deoarece block-urile necesita un anume timp pentru a circula in retea; daca un miner A exploateaza un block si minerul B exploateaza un alt block, inainte ca block-ul minerului A sa se propage catre minerul B, block-ul minerului B se va corupe, si nu va contribui la securitatea retelei.Mai mult de atat, exista problema centralizarii: daca minerul A reprezinta un mining pool cu un hashpower de 30% si minerul B are hashpower de 10%, A risca sa produca stale blocks 70% din timp, iar B sa produca block-uri invalide 90% din timp. Astfel, daca stale rate este ridicat, A va fi mult mai eficient, numai multumita marimii sale.Combinand aceste doua efecte, acele blockchains care produc block-uri mai rapid sunt mai probabil sa conduca la un mining pool -cu un procentaj mare din hashpower-ul retelei- care sa aiba control efectiv asupra procesului de mining. - -Asa cum descriu Sompolinsky si Zohar, GHOST rezolva prima problema a pierderilor de securitate ale retelei prin includerea stale blocks in calculul care determina care lant este mai lung: asta inseamna ca nu numai predecesorii unui block, dar si stale blocks care deriva din acesti predecesori („unchi” in jargonul Ethereus) sunt luati in calcul in a determina care block are cea mai vizibila dovada de munca ca sa il sustina. Pentru a rezolva aceasta problema secundara a centralization bias, trebuie sa mergem dincolo de protocolul descris de Sompolinsky si Zohar, si sa atribuim block rewards pentru stale blocks: un stale block primeste 87.5% din base reward, si „nepotul” care include stale block-ul primeste cei 12.5% ramasi. Taxele de tranzactie totusi, nu sunt acordate „unchilor”. - -Ethereum implementeaza o versiune simplificata a GHOST care merge in jos doar un nivel. Un stale block poate fi inclus ca „unchi” numai de catre descendentul direct al unuia din „fratii” lui, nu si al altor block-uri mai indepartate. Aceasta s-a facut pentru mai multe motive. In primul rand, un protocol GHOST nelimitat ar include prea multe complicatii in calculul numarului de „unchi” valizi pentru fiecare block. In al doilea rand, un GHOST nelimitat, cu o compensare ca aceea folosita de Ethereum nu mai constrange un miner sa actioneze pe chain-ul principal si nu pe chain-ul unui atacator public. In ultimul rand, calculele arata ca GHOST la single-level are 80% din avantajele unui GHOST nelimitat, si ofera un stale rate comparabil cu Litecoin de 2.5 minute chiar si cu un block time de 40 de secunde. Totusi, ca sa nu exageram, vom pastra un block time de 60 de secunde, specific pentru Primecoin, deoarece block-urile individuale pot necesita mai mult timp pentru a fi verificate. - - -Ethereum Client P2P Protocol - -P2P Protocol - - -Clientul P2P de protocol Ethereum este un protocol standard de cryptocurrency, si poate fi folosit la fel de usor pentru alte tipuri de cryptocurrency; singura modificare este introducerea protocolului GHOST, descris mai sus. Clientul Ethereum va fi in mare parte reactiv; daca nu e provocat, singurul lucru care il va face de unul singur este sa determine daemon-ul de retea, sa mentina conexiunile, si sa trimita periodic un mesaj prin care sa ceara block-uri derivate din block-ul curent. De asemenea, clientul va fi mai puternic. Spre deosebire de Bitcoin, care stocheaza o cantitate limitata de date despre blockchain, clientul Ethereum va opera si ca un back-end functional pentru un block explorer. - -Cand clientul citeste un mesaj, va parcurge pasii urmatori: - -Hash the data, and check if the data with that hash has already been received. If so, exit. -Stabileste tipul de date. Daca datele sunt tranzactii, daca tranzactia este valida, este adaugata la lista de tranzactii locale, e procesata pe block-ul curent, si emisa pe retea. Daca datele reprezinta un mesaj, se raspunde la acesta. Daca datele reprezinta un block, se trece la pasul 3. -Verificati daca „parintele” unui block este deja stocat in baza de date. Daca nu este, iesiti. -Verificati daca este validat lucrul pe header-ul block-urilor din lista de „unchi”. Daca nu, iesiti. -Verificati daca fiecare block header din lista de „unchi” din block are ca parinte la randul lui fiecare parinte al block-ului respectiv. Daca nu, iesiti. Tineti minte ca block headers care sunt „unchi” nu trebuie sa fie in baza de date; ei trebuie doar sa aiba parintele corect si dovada de lucru. De asemenea, asigurati-va ca „unchii” sunt unici, si separati de parinte. -Verificati daca marcajul de timp al block-ului este cu maxim 15 minute in viitor, si inaintea timpului parintelui. Verificati daca dificultatea block-ului si numarul acestuia sunt corecte. Daca vreuna din aceste verificari esueaza, iesiti. -Incepeti cu starea parintelui blocului, si aplicati succesiv pe acesta fiecare tranzactie din block. La sfarsit, adaugati reward-urile minerului. Daca root hash a state tree-ului rezultat nu se potriveste cu state root din block header, iesiti. Daca se potriveste, adaugati blocul la baza de date si avansati la pasul urmator -Determinati TD(block) ("total difficulty") pentru noul block. TD se defineste prin TD(genesis_block) = 0 si TD(B) = TD(B.parent) + sum([u.difficulty for u in B.uncles]) + B.difficulty.Daca noul block are un TD mai mare decat block-ul curent, setati noul block pentru block-ul curent, si continuati la pasul urmator. Daca nu, iesiti. -Daca noul block a fost schimbat, aplicati toate tranzactiile in lista de tranzactii, omiteti-le pe cele invalide, si retrimiteti block-ul si tranzactiile pe retea. -„Current block” este un indicator pastrat de fiecare nod care se refera la blocul considerat reprezentativ pentru starea actuala a retelei. Toate mesajele care cer informatii referitoare la sold, starea contractelor etc, au raspunsurile calculate in raport cu current block. Daca un nod este in procesul de mining, procedeul este doar putin alterat: cand se fac operatiile de mai sus, nodul mineaza continuu current block-ul, folosindu-i lista de tranzactii ca si lista de tranzactii pentru block. - - -Currency and Issuance(Moneda si emiterea ei) - -Reteaua Ethereum are o moneda inclusa, numita „ether”. Exista doua motive pentru includerea unei monede in retea. In primul rand, ca si Bitcoin, ether este acordat minerilor pentru a stimula securitatea retelei.In al doilea rand, serveste ca metoda de plata pentru servicii anti-spam. Din cele doua alternative la taxa, dovada de lucru pentru fiecare tranzactie similara cu Hashcashsi metoda laissez-faire fara taxa, prima nu este eficienta cu resursele si prea punitiva pentru calculatoare slabe si smartphone-uri, pe cand cea din urma ar cauza ca reteaua sa fie suprasolicitata imediat de contracte tip „logic bomb” repetate. Pentru convenienta, si pentru a evita viitoare dispute (vezi dezbateream BTC/uBTC/satoshi), denominatiile vor fi pre-marcate: - -Dupa 1 an Dupa 5 ani -Currency units 1.9X 3.5X -Fundraiser participants 52.6% 28.6% -Fiduciary members and early contributors 11.8% 6.42% -Alocatii pre-lansare aditionale 2.63% 1.42% -Rezerve 11.8% 6.42% -Miners 21.1% 57.1% -1: wei -103: (nespecificat) -106: (nespecificat) -109: (nespecificat) -1012: szabo -1015: finney -1018: ether -Acestea trebuie vazute ca o viziune expandata a conceptelor de ""dolari" si "centi" sau ca "BTC" si "satoshi" reprezinta viitorul.Szabo, finney si ether putin probabil vor fi folosite in viitorul apropiat, in timp ce celelalte unitati vor fi folosite in continuare la fel de mult."ether" este destinata sa fie unitatea primara in sistem, cum este spre exemplu dolarul sau bitcoin-ul.Dreptul de a numi unitati 103, 106 si 109 va fi lasat ca recompensa secundara de nivel inalt pentru obiectul strangerii de fonduri, cu pre-aprobare de la noi. - -Modelul de emitere va arata in modul urmator: - -Ether va fi lansat intr-o strangere de fonduri la pretul de 1000-2000 ether per BTC, primii investitori primind preturi mai bune pentru a compensa numarul incert de mare al participantilor intr-o faza incipienta.Suma minima de finantare va fi de 0.01 BTC. Presupunem ca X ether sunt lansati in acest mod. -0.225X ether vor fi alocati membrilor fiduciari si primilor contribuabili care s-au implicat substantial in proiect, inaintea inceperii strangerii de fonduri. Aceasta parte va fi stocata intr-un contract time-lock, aproximativ 40% va putea fi folosita dupa un an, 70% dupa doi ani, iar 100% dupa 3 ani.. -0.05X ether vor fi alocati pentru un fond folosit pentru platile cheltuielilor si premiilor in ether in perioada dintre stratul strangerii de fonduri si lansarea valutei. -0.225X ether vor fi alocati ca rezerva pe termen lung pentru a plati cheltuieli, salarii si premii dupa lansarea valutei. -0.4X ether will be mined per year forever after that point -Rata de inflatie pe termen lung(procentaje) - - -Despite the linear currency issuance, just like with Bitcoin over time the inflation rate nevertheless tends to zero -De exemplu, dupa cinci ani si presupunand ca nu s-au realizat tranzactii, 28.6% din ether va reveni primilor participanti la strangerea de fonduri, 6.42% membrilor fiduciari si primilor contribuabili, 6.42% platiti pentru rezerve si 57.1% -miners Modelul permanent linear de inflatie reduce riscul unei concentrari de resurse financiare destul de mare in Bitcoin, dupa cum ar vedea unii, si da sanse egale indivizilor care traiesc in prezent, dar si celor din viitor, sa obtina unitati valutare,in acelasi timp retinand stimulente puternice pentru a obtine si pentru a pastra ether, pentru ca "rata" de inflatie tot va tinde catre zero pe parcursul timpului(ex. pe parcursul anului 1000001 "proviziile" de bani vor creste de la 500001.5 * X la 500002 * X, cu o rata de inflatie de 0.0001%).Mai mult decat atat, o mare parte din interesul in Ethereum va fi pe termen mediu, prezicem ca daca Ethereum va fi un succes,vom vedea cea mai mare parte a cresterii sale pe un interval de timp 1-10 ani, iar aprovizionarea in aceasta perioada va fi foarte limitata. - -De asemenea, sustinem ca, deoarece monedele sunt intotdeauna pierdute in timp din cauza neglijentei, etc, si pierderea monedei poate fi modelata ca un procent din totalul ofertei pe an, ca totalul valutei aflat in circulatie se va stabiliza, in cele din urma, la o valoare echivalenta cu emiterea anuala impartita la rata de pierdere (de exemplu, la o rata de pierdere de 1%, odată ce alimentarea ajunge 40X atunci 0.4X vor fi exploatate si 0.4X pierdute in fiecare an, creand un echilibru). - - -Data Format - -Toate datele din Ethereum vor fi stocate in recursive length prefix encoding, care serializeaza matrice de siruri de caractere de lungime si dimensiuni arbitrare in siruri de caractere. De exemplu, ['caine', 'pisica'] este serializat (in byte array format) ca [ 130, 67, 100, 111, 103, 67, 99, 97, 116]; ideea generala este sa se codeze tipul de date si lungimea acestora intr-un singur byte urmat de datele efective (ex. transformata intr-o matrice byte, 'caine' devine [ 100, 111, 103 ], deci serializarea sa este[ 67, 100, 111, 103 ].Dupa cum este sugerata si de numele sau, codarea RLP este recursiva; atunci cand folosim codarea RLP pentru o matrice, de fapt codam un sir care este concatenarea codificarii RLP al fiecarui element. In plus, retineti ca numarul de bloc, marcajele de timp, dificultatea, depozitele de memorie, soldurile conturilor si toate valorile din contractul de depozitare sunt numere intregi, si Patricia tree hashes,root hashes, adresele, listele tranzactii hash si toate cheile in depozite de contract sunt siruri de caractere.Principala diferenta dintre cele doua este ca sirurile de caractere sunt stocate ca date de lungime fixa (20 bytes pentru adrese, 32 bytes pentru orice altceva), si numerele intregi ocupa atat spatiu cat au nevoie. Numerele intregi sunt stocate intr-o baza de format 256 big-endian(ex. 32767 in format de matrice byte ca [ 127, 255 ]). - -Un block intreg este stocat ca: - - [ - block_header, - transaction_list, - uncle_list - ] -Unde: - - transaction_list = [ - transaction 1, - transaction 2, - ... - ] - - uncle list = [ - uncle_block_header_1, - uncle_block_header_2, - ... - ] - - block_header = [ - parent hash, - sha3(rlp_encode(uncle_list)), - coinbase address, - state_root, - sha3(rlp_encode(transaction_list)), - difficulty, - timestamp, - extra_data, - nonce - ] -Fiecare tranzactie si header de block unchi este in sine o lista.Datele pentru dovada de functionare este codarea RLP a block-ului FARA nonce. uncle_list si transaction_list sunt listele de headere block unchi si tranzactiile din block, respectiv . nonce si extra_data sunt ambele limitate la un maxin de 32 bytes, exceptand genesis block unde parametriiextra_data vor fi mult mai mari. - -State_root este radacina unei scheme Merkle Patricia continand (cheie, valoare) perechi pentru toate conturile in care fiecare adresa este reprezentata de un sir de caractere binar de 20 bytes. La adresa fiecarui cont in parte , valoarea stocata in schema Merkel Patricia este un sir de caractere serializarea RLP a unui obiect de forma: - - [ balance, nonce, contract_root, storage_deposit ] -nonce este numarul de tranzactii facute din cont si este incrementat de fiecare data cand este realizata o tranzactie.Scopul este acela de (1) a face o tranzactie valida o singura data pentru a preveni atacurile, si (2) pentru a face imposibil (mai exact cryptografic nefezabil) construirea unui contract cu acelasi hash ca al unui contract existent. balance se refera la balanta contului, denominata in wei. contract_root este radacina unei alte scheme Patricia, continand memoria contractului, daca acel cont este controlat de un contract.Daca un cont nu este controlat de un contract, contract root va fi un sir de caractere gol. storage_deposit este un contor care stocheaza taxele de depozitare achitate; functia sa va fi discutata in detaliu mai jos. - - - - -Mining algorithm - -O proprietate de dorit in mining algorithms este rezistenta la optimizare prin hardware specializat. La inceput, Bitcoin a fost conceput ca o moneda democratica, dand oricui sansa de a participa in procesul de mining cu un CPU. In 2010 totusi, mineri mai rapizi care exploatau paralelizarea oferita de procesoare video (GPU) au preluat controlul, crescand network hashpower cu un factor de 100, si lasand CPU-urile in urma. In 2013, o alta categorie de hardware specializat, application-specific integrated circuits (ASICs) a depasit ca performante GPU-urile, atingand viteze de 100 de ori mai mari, folosind chip-uri fabricate special pentru computarea SHA256 hashes. Astazi, este practic imposibila minarea fara achizitionarea unui mining device de la una din aceste companii, si exista ingrijorari ca in 5-10 ani, mining-ul va fi dominat in intregime de de corporatii centralizate precum AMD sau Intel. - -Pana acum, calea principala de a atinge acest scop a fost "memory-hardness", construirea unor algoritmi proof of work care necesita nu numai un numar mare de calcule, dar si multa memorie pentru validare, astfel reducand eficacitatea implementarilor de hardware paralelizat si specializat. Exista cateva implementari de memory-hard proof of work, fiecare cu defectele ei: - -Scrypt - este o functie proiectata sa ocupe 128 kb de memorie pentru calcul. In esenta, algoritmul functioneaza prin ocuparea unui memory array cu hashes, si apoi calculand valori intermediare si finalmente, un rezultat bazat pe aceste valori din memory array.Totusi, parametrul de 128 kb este o limitare, si ASICs pentru Litecoin sunt deja in proces de dezvoltare. In plus, exista o limita naturala pe cantitatea de memory hardness in Scrypt care poate fi atinsa, caci procesul de verificare necesita la fel de mult calcul si memorie, ca o etapa a procesului de mining. -Birthday attacks - ideea din spatele birthday-based proofs of work este simpla: gasiti valorile xn,i,j astfel incat i < k, j < k si|H(data+xn+i) - H(data+xn+j)| < 2^256 / d^2. Parametrul d seteaza dificultatea calculului de a gasi un block, si parametrul k seteaza memory hardness. Orice birthday algorithm trebuie sa stocheze cumva toate calculele de H(data+xn+i)in memorie, astfel ca viitoarele calcule sa fie comparate cu acestea. Aici, calculul este memory-hard, dar verificarea este memory-easy, permitand extreme memory hardness fara a compromite usurinta verificarii.Totusi, algoritmul este problematic din doua motive. In primul rand, exista un time-memory tradeoff attack, unde utilizatorii cu 2x mai putina memorie pot compensa cu 2x putere de calcul, prin urmare memory hardness nu este absoluta. In al doilea rand, echipamentul hardware specializat poate fi usor de construit, in special daca se trece de traditionala arhitectura pe baza de chip si procesor, catre diverse clase de hash tables bazate pe hardware sau probabilistic analog computing. -Dagger - ideea din spatele Dagger,, un algoritm in-house dezvoltat de echipa Ethereum, este aceea de a avea un algoritm similar lui Scrypt, dar proiectat special ca fiecare nonce sa depinda numai de o mica portiune din data tree care rezulta din fiecare grup de ~10 milioane nonces. Calculul nonces la un nivel rezonabil de eficienta solicita construirea unui intreg tree, ocupand 100mb de memorie, pe cand verificarea unui nonce necesita doar 100kb. Totusi, aloritmii in genul Dagger sunt vulnerabili la dispozitive cu circuite computationale multiple care impart aceeasi memorie, si desi acest pericol poate fi diminuat, este probabil imposibil de inlaturat complet. -Ca un standard, avem in vedere un algoritm in genul Dagger cu parametri ajustati sa minimizeze atacurile de hardware specializat, probabil impreuna cu un proof of stake algorithm ca propriul nostru Slasher, pentru securitate sporita, daca este necesar. Totusi, pentru a veni cu un proof-of-work algorithm mai bun ca al competitiei, intentia noastra este sa folosim o parte din fondurile stranse pentru a organiza o competitie cu premii, similara cu cele pentru a determina algoritmul pentru Advanced Encryption Standard (AES) in 2005 si SHA3 hash algorithm in 2013, unde grupuri de cercetare din toata lumea concureaza pentru a dezvolta mining algorithms rezistenti la ASIC, si sa avem un proces de selectie cu mai multe runde de jurizare pentru a alege invingatorii. Incurajam cercetari despre memory-hard proofs of work, self-modifying proofs of work, proofs of work bazate pe instructiuni x86, multiple proofs of work cu protocoale economice ca stimulente pentru dezvoltare, si orice design care atinge scopul dorit. De asemenea vor exista oportunitati de a explora alternative precum proof of stake, proof of burn si proof of excellence. - - - - -Tranzactii - -O tranzactie este stocata astfel: - -[ nonce, receiving_address, value, [ data item 0, data item 1 ... data item n ], v, r, s ] -nonce este numarul de trnazactii deja trimise de acel cont, codate in forma binara(ex. 0 -> '', 7 -> '\x07', 1000 -> '\x03\xd8'). (v,r,s) este semnatura bruta Electrum-style a tranzactiei fara ca acea semnatura sa fie facuta cu private key corespunzatoare contului expeditor, cu 0 <= v <= 3. De la o semnatura Electrum-style (65 bytes) este posibila extractia public key, si , deci, si adresa, in mod direct.O tranzactie valida este una in care (i) semnatura este bine formata(ie. 0 <= v <= 3, 0 <= r < P, 0 <= s < N, 0 <= r < P - N if v >= 2), si (ii) contul expeditor are destule fonduri pentru a plati taxele si valoarea.Un block valid nu poate contine o tranzactie invalida; cu toate acestea, daca un contract genereaza o tranzactie invalida, acea tranzactie pur si simplu nu va avea efect.Daca cineva doreste sa plateasca voluntar o taxa mai mare, este liber sa faca asta, prin construirea unui contract care trimite mai departe tranzactia , dar care trimite automat o suma sau un procentaj minerului block-ului curent. - -Tranzactiile trimise la un sir gol , ca adresa, sunt tranzactii speciale, creand un "contract". - - -Difficulty adjustment( Adjustarea dificultatilor) - -Dificultatea este adjustata prin formula: - -D(genesis_block) = 2^36 -D(block) = - if anc(block,1).timestamp >= anc(block,501).timestamp + 60 * 500: D(block.parent) - floor(D(block.parent) / 1000) - else: D(block.parent) + floor(D(block.parent) / 1000) -anc(block,n)este generatia "n" ascendenta a block-ului; toate block-urile dinaintea block-ului geneza(original) se presupune ca au acelasi timestamp ca block-ul geneza.Acesta se stabilizeaza automat in jurul a 60 de secunde. Alegerea valorii de 500 a fost facuta pentru a balansa preocuparea ca minerii cu valori mai mici , cu hashpower suficient pentru a produce des doua block-uri la rand ,ar avea imboldul de a da un timestapt incorect pentru a-si maximiza propria rasplata si, pentru ca, odata cu valorile mari si dificultatea oscileaza prea mult, cu constanta de 500 simularile arata ca un hashpower constant produce o variatie de aproximativ +/-20%. - - -Block Rewards - -Un miner primeste trei tipuri de rasplata: o rasplata static block pentru producerea unui block, platile din tranzactii si recompense "nepot/unchi" descrise in sectiunea GHOST de mai sus.Minerul va primi 100% din recompensa block, dar plata pentru tranzactie va fi impartita, astfel 50% din ea merge la miner, iar restul de 50% este impartit in mod egal intre ultimii 64 de mineri.Motivul pentru aceasta impartire este unul de preventie impotriva creerii de catre un miner a unui block Ethereum cu un numar nelimitat de operatii, care sa plateasca taxele de tranzactii catre ei insisi, mentinand in acelasi timp un stimulent pentru ca alti mineri sa includa tranzactii.Dupa cum am descris in in sectiunea GHOST, unchii primesc doar 87.5% din rasplata block, celelalte 12.5% procente ramanand la nepotul fiecaruia in parte, platile pentru tanzactiile provenite din block-uri vechi nu merg la nimeni. - - -Contracts - -In Ethereum exista doua tipuri de entitati care pot genera si pot primi tranzactii: persoane reale(sau bots, protocoalele cryptografice nu ii pot distinge) si contracte. Un contract este, esential , un agent automat care traieste in reteaua Ethereum, are o adresa si o balanta Ethereum, si care poate primi si trimite tranzactii.Un contract este "activat" de fiecare data cand cineva trimite o tranzactie spre el, punct in care isi ruleaza codul, poate modificandu-si starea interna sau chiar trimitand anumite tranzactii, dupa care se inchide (shut down)."Codul" pentru un contract este scris special intr-un limbaj de un nivel scazut, constand intr-o stiva , care nu este persistenta, si2256 storage entries care constituie starea permanenta a contractului. Retineti ca utilizatorii Ethereum nu vor trebui sa codeze in acest limbaj, vom furniza un C-like language cu variabile, expresii, conditionale, tablouri si while loops, si ofera un compiler down to Ethereum script code. - - -Applications - -Aici sunt cateva exemple a ceea ce se poate face cu contractele Ethereum, cu toate exemplele de coduri scrise in our C-like language. Variabileletx.sender, tx.value, tx.fee, tx.data si tx.datan sunt proprietati ale tranzactiilor viitoare, contract.storage, si contract.address ale contractului in sine, si block.contract_storage, block.account_balance, block.number, block.difficulty, block.parenthash, block.basefee si block.timestamp proprietati ale block-ului. block.basefee este "taxa de baza" in care toate taxele de tranzactii din Ethereum sunt calculate ca multipli (is the "base fee" which all transaction fees in Ethereum are calculated as a multiple of; for more info see the "fees" section below). Toate variabilele exprimate prin majuscule (ex. A) sunt constante, pentru a fi inlocuite de valori adevarate de creatorul contractului, in momentul in care acel contract este eliberat. - - -Sub-currencies - -Sub-currencies (sub-valutele) au multe aplicatii, de la valute care reprezinta bunuri ca dolari sau aur la actiuni si chiar valute emise cu o singura unitate pentru a reprezenta obiecte de colectie sau proprietate intelectuala (smart property).Protocoale financiare avansate cu destinatie avansata care se afla pe Ethereum pot dori sa se organizeze cu o valuta interna.Sub-currencies sunt surprinzator de usor de implementat in Ethereum, aceasta sectiune descrie un contract destul de simplu pentru acest lucru. - -Ideea este aceea ca daca cineva doreste sa trimita x unitati de valuta contului A in valuta contractului C,vor trebui sa faca o tranzactie de format(C, 100 * block.basefee, [A, X]), iar contractul analizeaza tranzactia si adjusteaza balanta corespunzator.Pentru ca o tranzactie sa fie valabila, trebuie trimisa de 100 de ori taxa de baza in ether, pentru a alimenta contractul (and the contract parses the transaction and adjusts balances accordingly. For a transaction to be valid, it must send 100 times the base fee worth of ether to the contract in order to "feed" the contract (cu fiecare pas computational ce urmeaza dupa primii 16 contractul va fi taxat cu o mica plata si contractul va inceta sa functioneze daca balanta sa ajunge la zero). - - if tx.value < 100 * block.basefee: - stop - elif contract.storage[1000]: - from = tx.sender - to = tx.data[0] - value = tx.data[1] - if to <= 1000: - stop - if contract.storage[from] < value: - stop - contract.storage[from] = contract.storage[from] - value - contract.storage[to] = contract.storage[to] + value - else: - contract.storage[mycreator] = 10^18 - contract.storage[1000] = 1 -Programatorii sub-valutelor Ethereum pot , deasemenea, sa doreasca adaugarea unor alte trasaturi mai avansate: - -Includerea unui mecanism prin care oamenii pot cumpara unitati valutare in schimbul ether-ilor, poate licitand un numar fix de unitati zilnic. -Permiterea platii taxelor de tranzactii in valute interne, si apoi rambursarea taxei pentru tranzactiile ether expeditorului.Acest lucru rezolva una din problemele majore pe care toate celelalte protocoale "sub-valuta" le-au avut pana in momentul de fata: faptul ca utilizatorii de sub-valute trebuie sa mentina o balanta de unitati de sub-valute pentru utilizare si unitati in principala valuta pentru a plati taxele pentru tanzactii.Aici, un cont nou ar trebui sa fie "activat" o data cu ether-ul, dar de aici mai departe nu ar mai trecui reincarcat. -Permiterea unui schimb trust-free descentralizat intre valuta si ether. Retineti ca acest schimb trust-free descentralizat intre orice doua contracte este teoretic posibil in Ethereum chiar si fara un suport special, dar suportul special va permite ca procesul sa fie realizat de aproximativ zece ori mai ieftin. - -Derivate financiare - -Ingredientul-cheie care sta la baza derivatelor financiare este un data feed care furnizeaza pretul unui bun, asa cum e desemnat in alt bun (in cazul Ethereum, al doilea bun va fi de obicei ether). Sunt mai multe cai de a implementa un data feed; o metoda, implementata de creatorii Mastercoin, consta in includerea data feed in blockchain. Codul este acesta: - - if tx.sender != FEEDOWNER: - stop - contract.storage[data[0]] = data[1] -Orice alt contract va putea apoi sa interogheze index-ul I din data store D folosind block.contract_storage(D)[I]. Un mod mai avansat de a implementa un data feed este efectuarea acestei operatii off-chain – provider-ul de data feed sa semneze toate valorile, facand posibila incercarea de a declansa contractul numai prin includerea signed data, si apoi folosirea functiei de internal scripting a Ethereum pentru a verifica semnatura. In mare, orice derivat poate fi efectuat astfel, incluzand leverage trading, optiuni si operatiuni mai avansate precum collateralized debt obligations (no bailouts here though, so be mindful of black swan risks). - -Pentru a exemplifica, facem un contract de hedging. Ideea de baza este ca acel contract este creat de o persoana A, care depune 4000 ether. Contractul este apoi disponibil pentru acceptare de catre altcineva, care mai depune 1000 ether. Sa spunem ca 1000 ether valoreaza 25$ cand este facut contractul, potrivit indexului I din data store D. Daca persoana B accepta, dupa 30 de zile oricine poate trimite o tranzactie pentru a face contractul sa proceseze, trimitand acelasi echivalent de dolari in ether (in exemplul nostru, 25$) inapoi la B si restul catre A. B are avatajul de a fi protejat de currency volatility risk, fara a fi nevoit sa depinda de alti emitenti. Singurul risc pe care si-l asuma B este daca valoarea ether scade cu 80% in 30 de zile – chiar si atunci, daca B este online, se poate transfera catre un alt hedging contract. Avantajul lui Aeste taxa implicita de 0.2% din contract, si A se poate feri de pierderi daca detine valuta (USD) in alte locatii (sau Apoate fi optimist in legatura cu viitorul Ethereum, si vrea sa mentina ether la un leverage de 1.25x, caz in care taxa ar fi in favoarea lui B). - - if tx.value < 200 * block.basefee: - stop - if contract.storage[1000] == 0: - if tx.value < 1000 * 10^18: - stop - contract.storage[1000] = 0 - contract.storage[1001] = 998 * block.contract_storage(D)[I] - contract.storage[1002] = block.timestamp + 30 * 86400 - contract.storage[1003] = tx.sender - else: - ethervalue = contract.storage[1001] / block.contract_storage(D)[I] - if ethervalue >= 5000 * 10^18: - mktx(contract.storage[1003],5000 * 10^18,0,0) - else if block.timestamp > contract.storage[1002]: - mktx(contract.storage[1003],ethervalue,0,0) - mktx(A,5000 - ethervalue,0,0) -Si alte contracte financiare avansate sunt posibile; optiuni de clauze complexe (ex: “Oricine, denumit in continuare X, poate revendica acest cont prin depunerea a 2$ pana la 1 decembrie). X va avea de ales pe 4 decembrie intre a primi 1.95$ pe 29 decembrie si dreptul de a se decide pe 11 decembrie intre 2.20$ pe 29 decembrie si dreptul de a alege pe 18 decembrie intre suma de 1.89 GBP si a plati 1 EUR si a primi 3.20 EUR pe 29 decembrie) pot fi definite mai simplu prin stocarea unui state variable la fel ca in contractul mentionat, dar cu mai multe clauze in cod, cate una pentru fiecare stare posibila. Tineti minte ca orice forma de contract financiar trebuie sa fie colaterale; reteaua Ethereum nu detine o agentie de executare silita si nu poate colecta datorii. - - -Identity and Reputation Systems - -Cea mai veche alternativa cryptocurrency, Namecoin,a incercat sa foloseasca un blockchain specific Bitcoin pentru a furniza un sistem de inregistrare a numelor, unde utilizatorii isi pot inregistra numele si si alte date intr-o baza de date publica. Cel mai folosit caz este un sistem DNScare alocheaza nume de domenii precum “bitcoin.org” (sau in cazul Namecoin, “bitcoin.bit”) unei adrese IP. In alte cazuri se includ autentificarea prin e-mail si posibil alte advanced reputation systems. Aici este un contract simplu pentru un sistem de inregistrare a numelor in genul Namecoin, in Ethereum: - - if tx.value < block.basefee * 200: - stop - if contract.storage[tx.data[0]] or tx.data[0] < 100: - stop - contract.storage[tx.data[0]] = tx.data[1] -Se poate adauga mai multa complexitate, pentru a permite utilizatorilor sa schimbe mappings, sa trimita tranzactii automat catre contract, de unde sa fie retrimise, si chiar sa adauge reputatie si web-of-trust mechanics. - - -Organizatii Descentralizate Autonome - -Conceptul general din spatele Organizatiilor Descentralizate Autonome este acela ca o entitate virtuala are un anumit numar de membri sau actionari, care daca detin 67% din actiuni, sunt autorizati sa foloseasca fondurile entitatii, si sa modifice codul. Membrii ar decide impreuna cum ar trebui alocate fondurile organizatiei. Metodele de alocare pot fi diverse: de la cadouri si salarii pana la implementarea unei monede interne sau bonusuri. In esenta, aceasta imita metodele folosite de o companie traditionala sau organizatie non-profit, doar ca foloseste tehnologia cryptographic blockchain. Pana acum discutiile legate de DAO au vizat modelul “capitalist” al corporatiilor descentralizate autonome (DAC) cu actionari care primesc dividende; o alternativa ar permite tuturor actionarilor sa aiba un rol egal in luarea deciziilor, si un numar de 67% din membri pentru a decide acceptarea sau eliminarea unui membri. Pretentia de a apartine unei singure companii va fi atunci impusa de grup. - -Exemple de “skeleton code” pentru o DAO - - -Exista 3 tipuri de tranzactii: - -[0,k]pentru a inregistra un vot pentru schimbarea codului -[1,k,L,v0,v1...vn]pentru a inregistra o shimbare de cod k in favoarea setarii memoriei incepand cu locatia L pana la v0, v1 ... vn -[2,k]pentru a finaliza o schimbare de cod -Tineti minte ca acest design e bazat pe un model aleatoriu de adrese si hashes, pentru a asigura integritatea datelor; contractul va fi corupt in vreun fel dupa 2^128 utilizari, dar acest numar este acceptabil, deoarece un astfel de nivel de uzare este improbabil in viitorul apropiat.2^255 este folosit ca un numar “magic” pentru a stoca numarul total de membri, si apartenenta este denotata cu un 1 la adresa membrului. Ultimele 3 randuri din contract sunt folosite pentru a adauga C ca un prim membru; din acel moment, va fi responsabilitatea lui C sa foloseasca protocolul democratic de a schimba codul pentru activitati precum adaugarea membrilor si bootstrap. - - if tx.value < tx.basefee * 200: - stop - if contract.storage[tx.sender] == 0: - stop - k = sha3(32,tx.data[1]) - if tx.data[0] == 0: - if contract.storage[k + tx.sender] == 0: - contract.storage[k + tx.sender] = 1 - contract.storage[k] += 1 - else if tx.data[0] == 1: - if tx.value <= tx.datan * block.basefee * 200 or contract.storage[k]: - stop - i = 2 - while i < tx.datan: - contract.storage[k + i] = tx.data[i] - i = i + 1 - contract.storage[k] = 1 - contract.storage[k+1] = tx.datan - else if tx.data[0] == 2: - if contract.storage[k] >= contract.storage[2 ^ 255] * 2 / 3: - if tx.value <= tx.datan * block.basefee * 200: - stop - i = 3 - L = contract.storage[k+1] - loc = contract.storage[k+2] - while i < L: - contract.storage[loc+i-3] = tx.data[i] - i = i + 1 - if contract.storage[2 ^ 255 + 1] == 0: - contract.storage[2 ^ 255 + 1] = 1 - contract.storage[C] = 1 -Aceasta implementeaza modelul egalitar DAO unde membrii au un numar egal de actiuni. Se poate adapta la un “shareholder model” prin introducerea numarului de actiuni detinute de fiecare membru, si furnizarea unui mod simplu de transfer de actiuni. - - -DAO si DAC au fost un punct de interes pentru utilizatorii de cryptocurrency ca o viitoare forma de organizare economica, si suntem incantati de potentialul oferit de DAO. Pe termen lung, chiar fondul Ethereum intentioneaza sa faca o tranzitie, devenind un DAO autonom. - -. - - -Alte Aplicatii - -1) Savings wallets. Sa presupunem ca Alice vrea sa aiba conturile in siguranta, dar e ingrijorata ca isi va pierde (sau cineva ii va fura) codul. Depune ether intr-un contract cu Bob, o banca, dupa cum urmeaza: Alice poate retrage maxim 1% din fonduri pe zi, Alice impreuna cu Bob pot retrage totul, si Bob de unul singur poate retrage 0.05% din fonduri. In mod normal, 1% pe zi este destul pentru Alice, si daca vrea sa retraga mai mult, poate cere ajutorul lui Bob. Daca codul lui Alice este folosit ilicit de altcineva, apeleaza la Bob pentru a muta fondurile pe un nou contract. Daca ea isi pierde codul, Bob va retrage fondurile in cele din urma. Daca Bob este rau intentionat, Alice oricum poate retrage de 20 de ori mai repede decat el. - -2) Crop insurance.Se poate face usor un “financial derivatives contract” folosind date de prognoza meteo in locul unui index de preturi. Daca un fermier in Iowa cumpara derivative achitate invers proportional bazat pe precipitatiile din Iowa si vine seceta, fermierul va primi automat bani; daca precipitatiile sunt abundente, fermierul va fi fericit ca recolta va prospera. - -3) Un decentrally managed data feed, care foloseste un sistem de votare proof-of-stake pentru a furniza o medie intre opiniile tuturor asupra pretului unui produs, vremea sau alte date relevante. - -4) Smart multisignature escrow. Bitcoin accepta contracte de tranzactii multisignature unde, de exemplu, 3 din 5 keys pot folosi fondurile. Ethereum permite mai multa granularitate; de exemplu, 4 din 5 pot cheltui toate fondurile, 3 din 5 pot folosi pana la 10% pe zi si 2 din 5 pot folosi pana la 0.5% pe zi. In plus, Ethereum multisig este asincron – doi membri isi pot inregistra semnaturile pe blockchain la perioade diferite, si ultima semnatura va trimite automat tranzactia. - -5) Peer-to-peer gambling. Orice numar de protocoale de gambling, precum Cyberdice, al lui Frank Stajano si Richard Clayton, poate fi implementat pe blockchain-ul Ethereum. Cel mai simplu gambling protocol este de fapt un contract de diferenta pe urmatorul block hash. De aici, servicii de gambling precum SatoshiDice pot fi imitate pe blockchain prin crearea unui contract unic pe pariu sau prin folosirea unui contract quasi-centralizat. - -6) O piata de capital on-chain pe scara larga. Prediction markets (piete de predictie) sunt de asemenea usor de implementat ca si consecinta triviala. - -7O piata on-chain descentralizata , care foloseste un sistem bazat pe identitate si reputatie. - -8) Dropbox Decentralizat. O metoda este aceea de a cripta un fisier, a organiza o schema Merkel, a depune o radacina Merkle intr-un contract alaturi de o anume suma de ether, si a distribui fisierul pe o retea secundara. In fiecare zi, contractul va alege o ramura aleatorie din acea schema Merkel in functie de block hash, si va acorda un numar X de ether primului nod care furnizeaza ramura catre contract, astfel incurajand nodurile sa stocheze datele pe termen lung, pentru a revendica premiul. Daca cineva incearca sa download-eze o portiune a fisierului, poate folosi un contract in stilul micropayment channel pentru a downloada fisierul de la cateva noduri, cate un block pe rand. - - -Cum functioneaza contractele? - -Un contract care face tranzactii este codat dupa cum urmeaza: - - [ - nonce, - '', - value, - [ - data item 0, - data item 1, - ... - ], - v, - r, - s - ] -Itemii data vor fi, in majoritatea cazurilor, coduri script(mai mult despre acest lucru , mai jos). Validarea tranzactiei crearii contractului se desfasoara dupa cum urmeaza: - -Deserializeaza tranzactia si extrage adresa expeditoare din semnatura sa. -Calculeaza taxa de tranzactie ca NEWCONTRACTFEE plus taxe de depozitare pentru cod.Verifica daca balanta creatorului este cel putin egala cu valoarea tranzactiei plus taxa. Daca nu, iese. -Ia ultimii 20 bytes ai sha3 hash ai codarii RLP a tranzactiei, realizand contractul. Daca un cont cu aceeasi adresa exista deja, se paraseste operatiunea. Altfel, creati contractul la acea adresa. -Se copiaza itemul data i pentru a depozita slotul i in contract pentru toti i in [0 ... n-1]unde n este numarul itemilor data din tranzactie, si initializeaza contractul cu valoarea tranzactiei ca fiind valoarea contractului. Se scade valoarea si taxa din balanta creatorului. - -Specificatii de limbaj - -Limbajul de scripting al contractului este un hibrid din limbajul de asamblare si din limbajul stack-based al Bitcoin-ului, mentinand un indicator de index care de obicei creste cu unu dupa fiecare operatie si proceseaza continuu operatia gasita la indicatorul de index curent. Toate opcodes sunt numere in gama[0 ... 63]; etichete mai departe in descrierea sa ca STOP, EXTRO si BALANCE se refera la valori specifice care sunt definite mai departe. Limbajul scripting are acces la tri feluri de memorie: - -Stack - o forma temporara de depozitare care este resetata pentru a goli lista de fiecare data cand un contract este executat. Operatiile , de obicei, adauga sau elimina valori la/de la varful stack-ului, astfel lungimea totala a unui stack va creste sau va scadea pe parcursul executarii programului. -Memory - un stoc temporar de valori/keys care este resetat la continutul tuturor zerourilor de fiecare data cand un contract este executat.Keys si valori in memorie sunt numere intregi in gama [0 ... 2^256-1] -Storage - un stoc persistent de valori/keys care initial este setat sa contina toate zerourile, exceptand anumite coduri script inserate la inceput cand contractul este creat. Valorile si keys aflate in storage sunt numere integrale aflate in gama [0 ... 2^256-1] -Oricand o tranzactie este trimisa catre un contract, contractul va executa codul sau scripting.Pasii precisi care sunt facuti atunci cand un contract primeste o tranzactie sunt urmatorii: - -Interpretarea Script-ului Contractelor - - -Balanta ether a contractului creste odata cu suma trimisa. -Indicatorul de index este setat la zero, si STEPCOUNT = 0 -Repeta la nesfarsit: -daca comanda de la indicatorul de index este STOP, invalida sau mai mare de 63, iesiti din bucla -setati MINERFEE = 0, VOIDFEE = 0 -setati STEPCOUNT <- STEPCOUNT + 1 -daca STEPCOUNT > 16, set MINERFEE <- MINERFEE + STEPFEE -verificati daca comanda este LOAD sau STORE. Daca este asa, setati MINERFEE <- MINERFEE + DATAFEE -vedeti daca comanda va modifica un camp de depozitare, sa spunem KEY din OLDVALUE in NEWVALUE. Lasati F(K,V)fie 0daca V == 0 altfel (len(K) + len(V)) * STORAGEFEE in bytes. Set VOIDFEE <- VOIDFEE - F(KEY,OLDVALUE) + F(KEY,NEWVALUE). Calcularea len(K) ignora leading zero bytes. -vedeti daca comanda este EXTRO sau BALANCE. Daca este asa, setati MINERFEE <- MINERFEE + EXTROFEE -verificati daca comanda este o operatie crypto.Daca este asa, setati MINERFEE <- MINERFEE + CRYPTOFEE -daca MINERFEE + VOIDFEE > CONTRACT.BALANCE, OPRITI-VA si iesiti din bucla -scadeti MINERFEE din balanta contractului si adaugati MINERFEE la un running counter care va fi daugat la balanta minerului odata ce toate tranzactiile sunt analizate. -setati DELTA = max(-CONTRACT.STORAGE_DEPOSIT,VOIDFEE) si CONTRACT.BALANCE <- CONTRACT.BALANCE - DELTA si CONTRACT.STORAGE_DEPOSIT <- CONTRACT.STORAGE_DEPOSIT + DELTA. Retineti ca DELTA poate fi pozitiva sau negativa; singura restrictie este aceea ca depozitul contractului nu poate merge sub zero. -rulati comanda -daca comanda nu a iesit cu o eroare, updatati indicatorul de index si intoarceti-va la inceputul buclei.Daca contractul a iesit cu o eroare, iesiti din bucla. Retineti ca un contract existent cu o eroare nu face tranzactia sau block-ul invalide; pur si simplu inseamna ca execturia contractului s-a oprit la mijlocul procesului. -In urmatoarele descrieri, S[-1], S[-2], etc reprezinta cei mai importanti, descrescator, itemi ai stack-ului. Opcode-urile individuale sunt definite dupa cum urmeaza: - -(0) STOP - opreste executia -(1) ADD - pops two items and pushes S[-2] + S[-1] mod 2^256 -(2) MUL - pops two items and pushes S[-2] * S[-1] mod 2^256 -(3) SUB - pops two items and pushes S[-2] - S[-1] mod 2^256 -(4) DIV - pops two items and pushes floor(S[-2] / S[-1]). If S[-1] = 0, opreste executia. -(5) SDIV - pops two items and pushes floor(S[-2] / S[-1]), but treating values above 2^255 - 1 as negative (ie. x -> 2^256 - x). If S[-1] = 0, halts execution. -(6) MOD - pops two items and pushes S[-2] mod S[-1]. If S[-1] = 0, halts execution. -(7) SMOD - pops two items and pushes S[-2] mod S[-1], but treating values above 2^255 - 1 as negative (ie. x -> 2^256 - x). If S[-1] = 0, halts execution. -(8) EXP - pops two items and pushes S[-2] ^ S[-1] mod 2^256 -(9) NEG - pops one item and pushes 2^256 - S[-1] -(10) LT - pops two items and pushes 1 if S[-2] < S[-1] else 0 -(11) LE - pops two items and pushes 1 if S[-2] <= S[-1] else 0 -(12) GT - pops two items and pushes 1 if S[-2] > S[-1] else 0 -(13) GE - pops two items and pushes 1 if S[-2] >= S[-1] else 0 -(14) EQ - pops two items and pushes 1 if S[-2] == S[-1] else 0 -(15) NOT - pops one item and pushes 1 if S[-1] == 0 else 0 -(16) MYADDRESS - pushes the contract's address as a number -(17) TXSENDER - pushes the transaction sender's address as a number -(18) TXVALUE - pushes the transaction value -(19) TXDATAN - pushes the number of data items -(20) TXDATA - pops one item and pushes data item S[-1], or zero if index out of range -(21) BLK_PREVHASH - pushes the hash of the previous block (NOT the current one since that's impossible!) -(22) BLK_COINBASE - pushes the coinbase of the current block -(23) BLK_TIMESTAMP - pushes the timestamp of the current block -(24) BLK_NUMBER - pushes the current block number -(25) BLK_DIFFICULTY - pushes the difficulty of the current block -(26) BLK_NONCE - pushes the nonce of the current block -(27) BASEFEE - pushes the base fee (x as defined in the fee section below) -(32) SHA256 - pops two items, and then constructs a string by taking the ceil(S[-1] / 32) items in memory from index S[-2] to (S[-2] + ceil(S[-1] / 32) - 1) mod 2^256, prepending zero bytes to each one if necessary to get them to 32 bytes, and takes the last S[-1] bytes. Pushes the SHA256 hash of the string -(33) RIPEMD160 - works just like SHA256 but with the RIPEMD-160 hash -(34) ECMUL - pops three items. If (S[-2],S[-1]) are a valid point in secp256k1, including both coordinates being less than P, pushes (S[-2],S[-1]) * S[-3], using (0,0) as the point at infinity. Otherwise, pushes (2^256 - 1, 2^256 - 1). Note that there are no restrictions on S[-3] -(35) ECADD - pops four items and pushes (S[-4],S[-3]) + (S[-2],S[-1]) if both points are valid, otherwise (2^256 - 1,2^256 - 1) -(36) ECSIGN - pops two items and pushes (v,r,s) as the Electrum-style RFC6979 deterministic signature of message hash S[-1] with private key S[-2] mod N with 0 <= v <= 3 -(37) ECRECOVER - pops four items and pushes (x,y) as the public key from the signature (S[-3],S[-2],S[-1]) of message hash S[-4]. If the signature has invalid v,r,s values (ie. v not in [27,28], r not in [0,P], s not in [0,N]), return (2^256 - 1,2^256 - 1) -(38) ECVALID - pops two items and pushes 1 if (S[-2],S[-1]) is a valid secp256k1 point (including (0,0)) else 0 -(39) SHA3 - works just like SHA256 but with the SHA3 hash, 256 bit version -(48) PUSH - pushes the item in memory at the index pointer + 1, and advances the index pointer by 2. -(49) POP - pops one item. -(50) DUP - pushes S[-1] to the stack. -(51) SWAP - pops two items and pushes S[-1] then S[-2] -(52) MLOAD - pops two items and sets the item in memory at index S[-1] to S[-2] -(53) MSTORE - pops two items and sets the item in memory at index S[-1] to S[-2] -(54) SLOAD - pops two items and sets the item in storage at index S[-1] to S[-2] -(55) SSTORE - pops two items and sets the item in storage at index S[-1] to S[-2] -(56) JMP - pops one item and sets the index pointer to S[-1] -(57) JMPI - pops two items and sets the index pointer to S[-2] only if S[-1] is nonzero -(58) IND - pushes the index pointer -(59) EXTRO - pops two items and pushes memory index S[-2] of contract S[-1] -(60) BALANCE - pops one item and pushes balance of the account with that address, or zero if the address is invalid -(61) MKTX - pops four items and initializes a transaction to send S[-2] ether to S[-1] with S[-3] data items. Takes items in memory from index S[-4] to index (S[-4] + S[-3] - 1) mod 2^256 as the transaction's data items. -(63) SUICIDE - pops one item, destroys the contract and clears all storage, sending the entire balance plus the contract deposit to the account at S[-1] -Dupa cum am mentionat si mai sus, intentia nu este ca oamenii sa scrie script-uri direct in codul script al Ethereum, ci, vom pune la dispozitie compilatoare pentru a genera ES din limbaje de un nivel mai inalt.Primul limbaj suportat va fi cel mai probabil limbajul simplu C-like utilizat in descrierile de mai sus, iar al doilea va fi mai un limbaj de prima clasa mai complet cu suport pentru matrice si pentru siruri de lungimi arbitrare.Compilarea limbajului C este destul de simpla in ceea ce priveste eficienta compilatoarelor: variabilelor le pot fi repartizate in index de memorie, si formarea unei expresii aritmetice implica, esential, convertirea la reverse Polish notation (eg. (3 + 5) * (x + y) -> PUSH 3 PUSH 5 ADD PUSH 0 MLOAD PUSH 1 MLOAD ADD MUL). Limbajul de prima clasa este mai implicat datorita definirii variabile a domeniului, dar problema este cu toate acestea usor de manuit. Solutia posibila va fi mentinerea unei liste linked a frame-urilor stack in memorie, dand fiecarui stack frame N sloturi de memorie unde N este numarul total de nume de variabile distincte in program.Accesul varialilelor va consta in cautarea in lista stck frame pana cand un frame va contine un indicator spre variabila, copiind indicatorul in varful stack-ului pentru scopuri de memorare, si returnarea valorii la indicator.Totusi, acestea sunt griji pe termen lung; compilarea este separata de protocolul in sine, si, astfel, va fi pobila continuarea cercetarii strategiilor de compilare si dupa ce reteaua este in functiune. - - -Taxe - -In Bitcoin, nu exista taxe obligatorii pe tranzactie. Tranzactiile pot include taxe platite catre mineri, si acestia pot decide ce taxe vor accepta. In Bitcoin, un astfel de mecanism este imperfect; nevoia unui block size limit de 1 MB pe langa mecanismul de taxare ilustreaza acest fapt. In Ethereum, datorita Turing-completeness, un sistem de taxare voluntara ar fi catastrofal. In loc, Ethereum va avea un sistem de taxe obligatorii, care includ taxele de tranzactie si 6 taxe pentru calculele contractului. - -Taxele sunt setate astfel: - -TXFEE (100x) - taxa pentru a trimite o tranzactie -NEWCONTRACTFEE (100x) - ftaxa pentru crearea unui nou contract; nu include taxa de stocare a fiecarui item in script code -STEPFEE (1x) - taxa pentru fiecare pas computational ce urmeaza dupa primii 16 in executia contractului -STORAGEFEE (5x) - taxa per-byte pentru a adauga la stocarea contractului. Taxa de stocare este singura taxa care nu este platita catre un miner, si e inapoiata cand spatiul de stocare folosit de un contract e redus sau eliminat. -DATAFEE (20x) - taxa pentru accesarea sau setarea memoriei unui contract, in interiorul acelui contract -EXTROFEE (40x) - taxa pentru accesarea memoriei dintr-un alt contract in alt contract -CRYPTOFEE (20x) - taxa pentru folosirea oricarei operatiuni criptografice -Coeficientii vor fi revizuiti pe masura ce creste numarul datelor despre costul computational al fiecarei operatii. Partea cea mai dificila va fi setarea valoarea lui x.In prezent avem in vedere doua solutii principale: - -Faceti x proportional cu radacina patrata a dificultatii, astfel ca x = floor(10^21 / floor(difficulty ^ 0.5)). Aceasta ajusteaza automat taxele pe masura ce valoarea ether creste, si scade taxele pe masura ce calculatoarele devin mai performante, datorita legii lui Moore. -Folositi votarea proof-of-stake pentru a stabili taxele. Teoretic, partile interesate nu beneficiaza direct de cresterea sau diminuarea taxelor, deci stimulentele ar fi luarea deciziilor pentru a maximiza valoarea retelei.. -O solutie hibrida este de asemenea posibila, prin folosirea votarii proof-of-stake, dar avand mecanismul inversului radacinii patrate ca metoda initiala. - - -Concluzie - -Filosofia de baza a protocolului Ethereum este in multe feluri diferita de cea din spatele multor feluri de cryptocurrency actuale. Alte cryptocurrencies urmaresc sa creasca complexitatea si sa mareasca numarul de "functii"; Ethereum, pe de alta parte, elimina din functii. Protocolul nu "suporta" tranzactii multisignature, multiple input-uri si output-uri, hash codes, lock times sau multe alte functii oferite chiar si de Bitcoin. In schimb, complexitatea vine dintr-un scripting language Turing universal, care poate fi folosit pentru a crea orice functie care poate fi descrisa matematic prin mecanismul contractului. Ca rezultat, avem un protocol cu un potential unic; departe de a fi un protocol limitat, cu un singur scop, intentionat pentru un numar specific de aplicatii in stocarea de date, gambling sau finante, Ethereum este open-ended in esenta, si avem motive sa credem ca este foarte potrivit pentru a servi ca fundatie pentru un numar mare de protocoale financiare si non-financiare in anii ce vor urma. - - -Referinte si Documentare - -Colored coins whitepaper: https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit -Mastercoin whitepaper: https://github.com/mastercoin-MSC/spec -Decentralized autonomous corporations, Bitcoin Magazine: http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/ -Smart property: https://en.bitcoin.it/wiki/Smart_Property -Smart contracts: https://en.bitcoin.it/wiki/Contracts -Simplified payment verification: https://en.bitcoin.it/wiki/Scalability#Simplifiedpaymentverification -Merkle trees: http://en.wikipedia.org/wiki/Merkle_tree -Patricia trees: http://en.wikipedia.org/wiki/Patricia_tree -Bitcoin whitepaper: http://bitcoin.org/bitcoin.pdf -GHOST: http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf -StorJ and Autonomous Agents, Jeff Garzik: http://garzikrants.blogspot.ca/2013/01/storj-and-bitcoin-autonomous-agents.html -Mike Hearn on Smart Property at Turing Festival: http://www.youtube.com/watch?v=Pu4PAMFPo5Y -Ethereum RLP: http://wiki.ethereum.org/index.php/RLP -Ethereum Merkle Patricia trees: http://wiki.ethereum.org/index.php/Patricia_Tree -Ethereum Dagger: http://wiki.ethereum.org/index.php/Dagger -Ethereum C-like language: http://wiki.ethereum.org/index.php/CLL -Ethereum Slasher: http://blog.ethereum.org/?p=39/slasher-a-punitive-proof-of-stake-algorithm -Scrypt parameters: https://litecoin.info/User:Iddo/ComparisonbetweenLitecoinandBitcoin#SHA256miningvsscryptmining -Litecoin ASICs: https://axablends.com/merchants-accepting-bitcoin/litecoin-discussion/litecoin-scrypt-asic-miners/ \ No newline at end of file diff --git a/pages/other-languages/[spanish]-ethereum-toc.md b/pages/other-languages/[spanish]-ethereum-toc.md deleted file mode 100644 index 1f4770a5b..000000000 --- a/pages/other-languages/[spanish]-ethereum-toc.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -name: Ethereum TOC -category: ---- - -### Bienvenidos a Ethereum, la plataforma para la siguiente generación de contratos inteligentes y aplicaciones descentralizadas. - -[Whitepaper de Ethereum](https://github.com/ethereum/wiki/wiki/White-Paper) - -[RLP](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP), Prefijo Linear Recursivo (Recursive Linear Prefix), usado para codificación de datos a través de Ethereum. - -[Patricia Tree](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree) especificaciones del árbol Merkle Patricia (“Merkle Patria Tree”, también conocido como Trie), la estructura usada para almacenar y procesar a través de funciones Hash el estado de la cadena de bloques en Ethereum. - -[Protocolo de conexión](https://github.com/ethereum/wiki/wiki/Ethereum-Wire-Protocol), especificaciones. - -[CLL](https://github.com/ethereum/wiki/blob/master/CLL.md), Lenguage de alto nivel similar a C usado para crear contratos, especificaciones. - -[Dagger](https://github.com/ethereum/wiki/blob/master/Dagger.md), Prueba de trabajo (Proof-of-work) de Ethereum. - -[Protocolo de Bloques 2.0](https://github.com/ethereum/wiki/blob/master/Block-Protocol-2.0.md) - -[Capas](https://github.com/ethereum/wiki/blob/master/Layers.md) - -[Cámara de compensación](https://github.com/ethereum/wiki/blob/master/Clearinghouse.md) diff --git "a/pages/other-languages/[\344\270\255\346\226\207]-Serpent\346\214\207\345\215\227.md" "b/pages/other-languages/[\344\270\255\346\226\207]-Serpent\346\214\207\345\215\227.md" deleted file mode 100644 index 347d9c706..000000000 --- "a/pages/other-languages/[\344\270\255\346\226\207]-Serpent\346\214\207\345\215\227.md" +++ /dev/null @@ -1,487 +0,0 @@ ---- -name: Serpent -category: ---- - -译者: jan - -**更多以太坊信息请访问[EthFans.org](http://ethfans.org)** - -有关Serpent 1.0的信息请查阅: https://github.com/ethereum/wiki/wiki/Serpent-1.0-(old) - -Serpent是一种用来编写以太坊合约(Ethereum Contract)的高级编程语言。Serpent翻译成中文意思是"大蛇",如这个名字所示,这是一种与Python类似的编程语言。Serpent在兼顾底层语言效率与良好编程风格的同时尽可能的追求简洁,还加入了一些针对合约编程的特性。Serpent编译器由C++实现,因此可以被轻松打包进任何客户端,最新版本可以在[Github](http://github.com/ethereum/serpent)上找到。 - -以下内容需要读者对以太坊的工作原理有一个基本认识,包括区块,交易,合约和消息的概念,以及合约是如何通过读入字节数组和输出字节数组工作的。读者可以通过阅读[以太坊开发指南](https://github.com/ethereum/wiki/wiki/Ethereum-Development-Tutorial)得到这些知识。 - -### Serpent与Python的区别 - -Serpent与Python之间的主要区别有: - -* Python中的数字类型没有大小限制,Serpent的数字类型则会在2256溢出。例如,在Serpent中计算`3^(2^254)`的结果是1,虽然事实上这是一个天文数字。 -* Serpent没有Decimal类型。 -* Serpent没有list comprehensions (例如`[x**2 for x in my_list]`这样的表达式),字典(Hash/Map),和其它一些高级特性。 -* Serpent没有first-class函数的概念。虽然合约中可以定义函数, 合约也可以调用这些函数,但是在两次函数调用之间变量(除了持久变量)是会丢失的。 -* Serpent有一个被称作”持久变量“(persistent storage variables)的概念。 -* 在Serpent中可以使用`extern`语句来调用其他合约中定义的函数。 - -### 安装 - -我们可以通过pip来安装Serpent的python库和可执行文件 (注:译者使用的Python版本为2.7): - - sudo pip install ethereum-serpent - -如果想要一个在C++中可以直接调用的库,可以自行编译Serpent: - - git clone http://github.com/ethereum/serpent - cd serpent - make - sudo make install - -### 指南 - -现在开始编写我们的第一个合约吧! - -首先创建一个叫做"mul2.se"的文件,内容如下: - - def double(x): - return(x * 2) - -这是一个非常简单的只有两行代码的合约,它定义了一个函数。一份Serpent合约通过函数向其他合约或者交易(transaction)提供”接口“(interface),合约定义的函数即可以被交易也可以被其他合约调用。例如一份定义货币的合约可能会定义类似`send(to,value)`和`check_balance(address)`的函数。 - -现在让我们来编译这份代码。在命令行中输入: - -``` -> serpent compile mul2.se -604380600b600039604e567c01000000000000000000000000000000000000000000000000000000006000350463eee9720681141560415760043560405260026040510260605260206060f35b505b6000f3 -``` - -执行成功后就得到了一串可以放入交易执行的16进制编码的字符串。如果你想要的是机器指令(opcodes),可以使用`pretty_compile`来编译: - - > serpent pretty_compile mul2.se - [PUSH1, 67, DUP1, PUSH1, 11, PUSH1, 0, CODECOPY, PUSH1, 78, JUMP, PUSH29, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, PUSH1, 0, CALLDATALOAD, DIV, PUSH4, 238, 233, 114, 6, DUP2, EQ, ISZERO, PUSH1, 65, JUMPI, PUSH1, 4, CALLDATALOAD, PUSH1, 64, MSTORE, PUSH1, 2, PUSH1, 64, MLOAD, MUL, PUSH1, 96, MSTORE, PUSH1, 32, PUSH1, 96, RETURN, JUMPDEST, POP, JUMPDEST, PUSH1, 0, RETURN] - -使用`compile_to_lll`可以查看LLL形式的中间编译结果: - -``` -> serpent compile_to_lll mul2.se -(return 0 - (lll - (with '__funid - (div (calldataload 0) - 26959946667150639794667015087019630673637144422540572481103610249216 - ) - (unless (iszero (eq (get '__funid) 4008276486)) - (seq - (set 'x (calldataload 4)) - (seq - (set '_temp_521 (mul (get 'x) 2)) - (return (ref '_temp_521) 32) - ) - ) - ) - ) - 0 - ) -) -``` - -让我们来理解一下上面编译结果的含义。与大多数合约一样,代码最外一层的目的仅仅是在合约初始化阶段将合约内部的代码复制并作为运算结果返回。初始化阶段返回的代码将会在每次调用合约的时候被执行。因此在EVM (Ethereum Virtual Machine)执行的代码中你可以看到`CODECOPY`指令, 在LLL表达式中对应的则是`lll`元操作。在`lll`元操作内部,首先是一段获取保存在合约数据头四个字节的函数ID(function ID)的代码(也就是`(div (calldataload 0) 26959946667150639794667015087019630673637144422540572481103610249216)`这一段,我们通过先读入32个字节,再将其除以2^224得到头四个字节)。再往下,则会将获得的函数ID与该合约支持的所有函数ID逐一比较。在我们的例子中,如果函数ID是4008276486,则会将消息数据中的4到35字节的数据赋值给一个名为`'x`的变量(对应的代码是`(calldataload 4)`),然后将`2 * x`的结果赋值给一个临时变量`'_temp_521`,最后将这个临时变量对应的内存地址中存放的32字节长的数据作为结果返回。 - -函数ID通过计算函数名字和参数的哈希值(Hash)的头四个字节得到。在我们的例子中,定义了一个名字为”double“,接受一个整型数作为参数的函数,因此可以通过如下命令得到其对应的函数ID: - - > serpent get_prefix double i - 4008276486 - -定义接受不同参数列表的同名函数是允许的。例如,我们可以定义一个接受三个整型数为参数的”double“函数,它会将每一个参数翻倍然后以数组形式返回。这个函数会有一个不同的函数ID (或者说前缀,prefix): - - > serpent get_prefix double iii - 1142360101 - -字母`i`代表整型或者定长字符串(32字节,在Serpern和EVM中与整型等价)参数,字母`s`代表变长字符串参数,而字母`a`代表数组参数。后文会对此做更详细的介绍。 - -那么如何运行这份合约呢?这时候我们需要使用[pyethereum](https://github.com/ethereum/pyethereum)。先通过pip(环境是python 2.7)安装pyethereum: - - > sudo pip install pyethereum - -在合约代码所在目录中打开Python控制台,输入: - - > from pyethereum import tester as t - > s = t.state() - > c = s.abi_contract('mul2.se') - > c.double(42) - [84] - -第二行创建了一个初始化的状态(类似于创世块, genesis block)。第三行创建了一个Python对象,代表mul2.se这个合约。你可以用`c.address`来查看这份合约存放的地址。第四行调用这个合约,传入参数42,然后我们看到这份合约返回给我们结果84。 - -如果要在testnet或者livenet上调用这样一份合约,你需要打包一个内容为”以整型参数42作为输入调用函数double“的消息发送给这份合约。使用下面的命令可以得到消息对应的字节码: - - > serpent encode_abi double i 42 - eee97206000000000000000000000000000000000000000000000000000000000000002a - -### 另一个实例:名称注册合约 (Name Registry) - -读者一定觉得在区块链上跑一个”乘以2“的函数略显无聊吧... 接下来让我们来实现一个更有趣的合约:名称注册。这个合约的主要接口是一个`register(key, value)`函数。通过这个接口可以检查给定的key是否已经被使用/注册了;如果没有,则将这个key注册为指定的键值然后返回1;如果已经被使用则直接返回0。这个合约还提供另外一个接口用来获取指定key对应的键值。下面就是合约代码: - - def register(key, value): - # Key not yet claimed - if not self.storage[key]: - self.storage[key] = value - return(1) - else: - return(0) # Key already claimed - - def ask(key): - return(self.storage[key]) - -这份合约首先定义了`register`函数,这个函数接受`key`和`value`变量作为参数。第二行是注释,以`#`开头,注释会被编译器忽略,仅仅用来帮助程序员更好的理解程序。然后是一个标准的if/else条件语句:先检查`self.storage[key]`是否为0(即表明这个key没有被使用),如果是0则执行赋值`self.storage[key] = value`然后返回1,否则直接返回0。`self.storage`是一个伪数组,有和数组类似的行为但是实际上没有一块内存与之对应。 - -让我们把这段代码放入一个名为"namecoin.se"的文件,然后在pyethereum中试试: - - > from pyethereum import tester as t - > s = t.state() - > c = s.abi_contract('namecoin.se') - > c.register(0x67656f726765, 45) - [1] - > c.register(0x67656f726765, 20) - [0] - > c.register(0x6861727279, 65) - [1] - > c.ask(0x6861727279) - [65] - -如果我们想要把上面的第一次调用写成消息的形式: - -``` -> serpent encode_abi register ii 0x67656f726765 45 -d66d6c10000000000000000000000000000000000000000000000000000067656f726765000000000000000000000000000000000000000000000000000000000000002d -``` - -### 引用代码和调用其他合约 - -当你的项目越来越大时把所有代码放在一个文件里面就很不科学了,所幸的是把合约代码分开保存在多个文件中是一件很容易的事情。假设我们创建了如下两个文件: - -mul2.se: - - def double(x): - return(x * 2) - -returnten.se: - - extern mul2: [double] - - MUL2 = create('mul2.se') - def returnten(): - return(MUL2.double(5, as=mul2)) - -现在打开Python,执行以下代码: - - > from pyethereum import tester as t - > s = t.state() - > c = s.abi_contract('returnten.se') - > c.returnten() - [10] - -通过这个例子我们可以看到一些新特性: - -* 使用`create`方法可以从文件中读入代码创建合约 -* 使用`extern`关键字可以声明一个合约类(class of contract),通过这个类可以知道合约中的函数名 -* 用来调用其他合约的编程接口 - -`create`方法很容易理解 - 使用它可以创建一份合约,返回值是这份合约的地址(address)。`extern`后面先是声明了合约类的名字,例子中是`mul2`,然后用一个数组声明了这个合约类中的所有方法名,例子中是`[double]`。声明之后,对于任何地址变量x(变量的值是一个地址),都可以通过`x.double(arg1, as=mul2)`来调用该地址中保存的合约。合约类通过`as`关键字提供(合约类用来确定`double`对应的函数ID;另一个合约类中如果`double`函数可能对应不同的ID)。`as`关键字是可选的,但是在两个合约类包含同名函数时会产生歧义。`arg1`是传给`double`函数的参数,如果传入的参数个数比函数声明需要的参数少,缺少的参数会以'0'补上;如果传入的参数比声明需要的参数多,多余的参数会被忽略。函数调用还支持一些其他的可选参数: - -* `gas=12414` - 设置函数执行可用的gas上限 (默认是所有gas,即合约可用gas上限)。 -* `value=10^19` - 随调用消息转账10^19 wei(10 ether) -* `data=x`, `datasz=5` - 用数组x中的头5个值作为参数调用函数;之前传入的参数会被覆盖掉;只指定data而不指定datasz会导致非法调用。 -* `outsz=7` - Serpent在默认情况下取运算结果的头32字节作为函数返回值,通过`outsz`可以要求函数通过数组返回更多的值。例如执行`y = x.fun(arg1, outsz=7)`之后你可以通过`y[0]`, `y[1]`等等操作返回值。 - -和`create`类似的一个操作是`inset('filename')`,它的作用是用文件中的代码替换调用的那一行,而不是创建一个合约。 - -### 持久化保存结构化数据 - -(注:原文用词是data structure,直译应为数据结构,但例子中定义的更像是数据而不是数据结构,因此翻译为结构化数据。) - -在更复杂的场景中,我们经常需要将结构化数据持久的保存。例如一份去中心话的交易所合约,既需要保存用户各种资金的余额,也需要保存待成交的包含了价格和数量信息的买单和卖单。因此Serpent内建支持自定义数据结构。以去中心化交易所合约为例,其中可能需要定义这样的结构化数据: - - data user_balances[][] - data orders[](buys[](user, price, quantity), sells[](user, price, quantity)) - -接下来可以使用这些定义好的数据: - - def fill_buy_order(currency, order_id): - # Available amount buyer is willing to buy - q = self.orders[currency].buys[order_id].quantity - # My balance in the currency - bal = self.user_balances[msg.sender][currency] - # The buyer - buyer = self.orders[currency].buys[order_id].user - if q > 0: - # The amount we can actually trade - amount = min(q, bal) - # Trade the currency against the base currency - self.user_balances[msg.sender][currency] -= amount - self.user_balances[buyer][currency] += amount - self.user_balances[msg.sender][0] += amount * self.orders[currency].buys[order_id].price - self.user_balances[buyer][0] -= amount * self.orders[currency].buys[order_id].price - # Reduce the remaining quantity on the order - self.orders[currency].buys[order_id].quantity -= amount - -请注意我们是如何先在顶部定义结构化数据,然后在合约中使用它们的。对这些结构化数据的读和写都会被转化成在持久化存储上的读写,因此这些结构化数据是持久保存的。 - -定义结构化数据的语法很简单。首先可以定义最简单的变量: - - data blah - - x = self.blah - self.blah = x + 1 - -还可以定义定长数组和不定长数组: - - data blah[1243] - data blaz[] - - x = self.blah[505] - y = self.blaz[3**160] - self.blah[125] = x + y - -我们应该优先考虑使用定长数组,因为在计算数组元素(array index)对应的存储位置(storage index)的时候,定长数组消耗的gas更少。 - -也可以定义元组(tuple),元组的元素也可以是结构化数据: - - data body(head(eyes[2], nose, mouth), arms[2], legs[2]) - - x = self.body.head.nose - y = self.body.arms[1] - -然后是元组数组(array of tuples): - - data bodies[100](head(eyes[2], nose, mouth), arms[2](fingers[5], elbow), legs[2]) - - x = self.bodies[45].head.eyes[1] - y = self.bodies[x].arms[1].fingers[3] - -注意下面这样的写法是不行的: - - data body(head(eyes[2], nose, mouth), arms[2], legs[2]) - - x = self.body.head - y = x.eyes[0] - -也就是说对结构化数据内部元素的存取必须在一行语句中完成。 - -还是以名称注册表(name registry)为例,让我们来看看具体如何使用结构化数据。我们要实现一个增强版的名称注册表,当用户注册key成功时他会成为key的所有者,key的所有者可以 (1) 转移所有权,以及(2) 改变key对应的键值(value)。为了简洁函数不再返回1或者0。 - - data registry[](owner, value) - - def register(key): - # Key not yet claimed - if not self.registry[key].owner: - self.registry[key].owner = msg.sender - - def transfer_ownership(key, new_owner): - if self.registry[key].owner == msg.sender: - self.registry[key].owner = new_owner - - def set_value(key, new_value): - if self.registry[key].owner == msg.sender: - self.registry[key].value = new_value - - def ask(key): - return([self.registry[key].owner, self.registry[key].value], items=2) - -最后定义的ask函数返回一个长度为2的数组。通过调用ask函数,例如`o = registry.ask(key, outsz=2)`,我们可以通过返回值`o[1]`和`o[1]`获取key对应的所有者和键值。 - -### 内存中的数组 - -使用内存中的数组有一套不同的语法。内存数组只能是定长数组,也不能有元组(tuple)或者更复杂的数组元素。例如: - - def bitwise_or(x, y): - blah = array(1243) - blah[567] = x - blah[568] = y - blah[569] = blah[567] | blah[568] - return(blah[569]) - -Serpent还定义了两个常用的数组操作: - - len(x) - -用于查询数组的长度。 - - slice(x, start, end) - -用于截取从start开始到end结束范围内数组元素,注意end必须大于等于start,否则执行是会出错。 - -### 数组与函数 - -函数可以接受数组作为参数,也可以返回一个数组: - - def compose(inputs:arr): - return(inputs[0] + inputs[1] * 10 + inputs[2] * 100) - - def decompose(x): - return([x % 10, (x % 100) / 10, x / 100]:arr) - -在参数定义后面加`:arr`表示这个参数是一个数组;而在返回值后面加`:arr`表示返回一个数组(如果不加`:arr`只写`return([x,y,z])`,函数的返回值将会是这个数组的内存地址)。 - -当合约调用自己定义的函数的时候,数组参数会被自动识别出来正确处理,例如: - - def compose(inputs:arr, radix): - return(inputs[0] + inputs[1] * radix + inputs[1] * radix ** 2) - - def main(): - return self.compose([1,2,3,4,5], 100) - -但是当合约需要调用另一份接受数组参数的合约时,你需要通过`extern`声明这一点,加入数组签名到函数签名中: - - extern composer: [compose:ai, main] - -这里`ai`的意思是“一个数组参数后面跟着一个整型参数”。同理,如果签名是`iiaa`,则代表“两个整型参数后面跟着两个数组参数”,而`iss`表示“一个整型参数,后面是两个字符串做参数”。如果函数名后面没有跟冒号(:),如本例中`main` 所示,则表示这个函数不接受参数。如果你想知道一个文件中定义了哪些函数签名,执行下面的命令即可: - - > serpent mk_signature compose_test.se - extern compose_test: [compose:ai, main] - -### 字符串 - -Serpent中有两种字符串:短字符串(short strings),例如`"george"`,以及长字符串(long strings),例如`text("afjqwhruqwhurhqkwrhguqwhrkuqwrkqwhwhrugquwrguwegtwetwet")`.用双引号括起来的短字符串和数字类型是等价的;用`text`关键字定义的长字符串则是类似与数组的对象。我们可以使用`getch(str, index)`和`setch(str, index)`方法来操作字符串中的字符。`str[0]`这样的写法则会将字符串当作数组处理,将字符当作数字返回。 - -将字符串用作函数参数或者返回值时,需要在函数签名中使用字符串标记`str`,类似使用`arr`来标记数组。使用`len(s)`方法可以得到字符串的长度,而`slice(s)`方法可以用来裁剪字符串。 - -下面是一个用字符串做参数和返回值的例子: - -``` -data str - -def t2(): - self.str = text("01") - log(data=self.str) - return(self.str, chars=2) - -def runThis(): - s = self.t2(outsz=2) - log(data=s) -``` - -### Macros (宏) - -**警告:这是新加入的未经测试的特性,大蛇出没注意!** - -通过macro我们可以创造重写规则,极大的增强程序的表达能力。例如,假设我们想写一条计算三个数字的中位数的命令: - - macro median($a, $b, $c): - min(min(max($a, $b), max($a, $c)), max($b, $c)) - -现在我们可以使用这个新定义的macro: - - x = median(5, 9, 7) - -接下来看另一个例子,一个查找数组中最大元素的macro: - - macro maxarray($a:$asz): # search pattern. below is substitution pattern - $m = 0 - $i = 0 - while i < $asz: - $m = max($m, $a[i]) - $i += 1 - $m - - x = maxarray([1, 9, 5, 6, 2, 4]:6) - -点击下面的链接可以看到更多展示macros牛逼用法的例子: - -https://github.com/ethereum/serpent/blob/poc7/examples/peano.se - -这里要提醒读者注意的是:macros不是函数(functions)。每次调用macro的时候,macro的定义都会被文本复制到调用的地方(宏展开)。因此当macro的定义变得很长时,请考虑定义一个函数替代它。还要注意的是占位符前面的$符号非常重要:如果$a前少了$符号,实际上是在使用名字为a的变量。我们也可以在替换模式(substitution pattern, 指宏的定义体)而不是搜索模式(search pattern,指宏定义的第一行)中使用$占位符,这样在每一次宏展开时会产生一个名字为随机前缀的变量。在替换模式中也可以使用普通变量(变量名前面没有$),结果就是所有宏展开使用的是同一个变量,而且该变量可能在宏展开之外的地方也会用到。 - -### 类型 - -**警告:这是新加入的未经测试的特性,大蛇出没注意!** - -Serpent中的穷人版类型系统是体现macros威力的绝佳例子,和macros一起使用时能产生非常有趣的结果。直接上例子: - - type float: [a, b, c] - - macro float($x) + float($y): - float($x + $y) - - macro float($x) - float($y): - float($x - $y) - - macro float($x) * float($y): - float($x * $y / 2^32) - - macro float($x) / float($y): - float($x * 2^32 / $y) - - macro unfloat($x): - $x / 2^32 - - macro floatfy($x): - float($x * 2^32) - - macro float($x) = float($y): - $x = $y - - macro with(float($x), float($y), $z): - with($x, $y, $z) - - a = floatfy(25) - b = a / floatfy(2) - c = b * b - return(unfloat(c)) - -这段代码的返回值是156,即12.5^2的整数部分。如果只用整型计算,结果将是144。这个技巧可以用来重写[椭圆曲线签名的公钥复原代码](https://github.com/ethereum/serpent/blob/df0aa0e1285d7667d4a0cc81b1e11e0abb31fff3/examples/ecc/jacobian_add.se),类型系统可以让里面的加法和乘法隐式的做模运算(modulo P),从而是代码更精巧;我们也可以利用[长整形](https://github.com/ethereum/serpent/blob/poc7/examples/long_integer_macros.se)来处理RSA以及其他基于大数的加密算法中的计算。 - -### 其他 - -更多的Serpent代码示例请参阅:https://github.com/ethereum/serpent/tree/master/examples - -pyethereum tester的一些有用技巧: - -* 区块数据 - 你可以通过`s.block`查看区块数据。例如,`s.block.number`, `s.block.get_balance(addr)`, `s.block.get_storage_data(addr, index)`等等。 -* 快照 - 通过`x = s.snapshot()`和`s.revert(x)`可以创建和恢复快照。 -* 挖矿 - 调用`s.mine(100)`会挖出100个块,块之间间隔60秒。通过`s.mine(100, addr)`可以指定获得挖矿收益的地址。 -* Dump所有区块数据 - `s.block.to_dict()` - -Serpent还提供了许多特别变量(special variables),以下是完整列表: - -* `tx.origin` - 交易的发送者 -* `tx.gas` - 剩余gas -* `tx.gasprice` - 交易包含的gasprice(油价) -* `msg.sender` - 消息的发送者 -* `msg.value` - 通过消息转移的wei(以太坊中最小的价值单位)的数量 -* `self` - 合约自身的地址 -* `self.balance` - 合约自身的余额(拥有多少wei) -* `x.balance` (对于任意的x) - x的账户余额 -* `block.coinbase` - 挖出当前块的矿工的收益地址(coinbase) -* `block.timestamp` - 当前块的时间戳 -* `block.prevhash` - 前一个块的hash -* `block.difficulty` - 当前的挖矿难度 -* `block.number` - 当前块的编号 -* `block.gaslimit` - 当前块的可用gas上限 - -Serpent支持以下特别函数(special functions): - -* `init` - 在创建合约时执行 -* `shared` - 在执行`init`和用户函数之前执行 -* `any` - 在用户函数之前执行 - -此外还提供了几个加密操作: - -* `addr = ecrecover(h, v, r, s)` - determines the address that produced the elliptic curve signature `v, r, s` of the hash `h` -* `x = sha256(a, items=4)` - 返回数组a中头4个元素构成的128字节的SHA256 hash。 -* `x = ripemd160(a, items=4)` - same as above but for ripemd160 -* 使用字符语法(chars syntax)可以计算任意数量字节的hash。例如:`x = sha256([0xf1fc122bc7f5d74df2b9441a42a1469500000000000000000000000000000000], chars=16)` - 返回的是头16个字节的hash。注意最后用0对齐,否则头16个字节会是0(因为一个word是32字节),计算的是16个0字节的hash。 - -### 小提示 - -* 如果函数的返回值和你预计的不同,仔细检查所有的变量名 - 使用没有声明过的变量是不会产生错误信息的。 - -* `Invalid argument count or LLL function`通常表示你将`self.foo()`写成了`foo()`。 - -* 有时你需要的是无符号运算符,例如div()和lt()而不是'/'和'<'。 - -* 升级Serpent的时候,需要先`pip uninstall ethereum-serpent`然后`python setup.py install`。避免使用`pip install ethereum-serpent`,因为pypi上的包八成已经过时了。 - -* 在调用abi_contract()时如果你遇到`Exception: Error (file "main", line 1, char 5): Invalid object member (ie. a foo.bar not mapped to anything)`这样的错误,确认你要编译的文件所在路径写对了。 - -* 如果在调用abi_contract()的时候遇到core dump,确认你没有定义同名函数。 diff --git "a/pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212Wiki\347\233\256\345\275\225.md" "b/pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212Wiki\347\233\256\345\275\225.md" deleted file mode 100644 index d9344f794..000000000 --- "a/pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212Wiki\347\233\256\345\275\225.md" +++ /dev/null @@ -1,11 +0,0 @@ -中文读者可以在[以太坊爱好者社区](http://ethfans.org)获知最新信息。 - -白皮书:[以太坊(Ethereum ):下一代智能合约和去中心化应用平台](https://github.com/ethereum/wiki/blob/master/%5B%E4%B8%AD%E6%96%87%5D-%E4%BB%A5%E5%A4%AA%E5%9D%8A%E7%99%BD%E7%9A%AE%E4%B9%A6.md) - -[Serpent语言指南](https://github.com/ethereum/wiki/blob/master/%5B%E4%B8%AD%E6%96%87%5D-Serpent%E6%8C%87%E5%8D%97.md) - -[以太坊开发计划](https://github.com/ethereum/wiki/blob/master/%5B%E4%B8%AD%E6%96%87%5D-%E4%BB%A5%E5%A4%AA%E5%9D%8A%E5%BC%80%E5%8F%91%E8%AE%A1%E5%88%92.md) - -[术语表](https://github.com/ethereum/wiki/blob/master/%5B%E4%B8%AD%E6%96%87%5D-%E4%BB%A5%E5%A4%AA%E5%9D%8A%E6%9C%AF%E8%AF%AD%E8%A1%A8.md) - -[网络状态监控](https://github.com/ethereum/wiki/blob/master/%5B%E4%B8%AD%E6%96%87%5D-%E7%BD%91%E7%BB%9C%E7%8A%B6%E6%80%81.md) diff --git "a/pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\345\274\200\345\217\221\350\256\241\345\210\222.md" "b/pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\345\274\200\345\217\221\350\256\241\345\210\222.md" deleted file mode 100644 index 555f733d3..000000000 --- "a/pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\345\274\200\345\217\221\350\256\241\345\210\222.md" +++ /dev/null @@ -1,278 +0,0 @@ ---- -name: 以太坊开发计划 -category: ---- - -翻译:Andy - -介绍 - - - -以太坊是一个开源平台,可以创建和发布去中心化的应用程序。 - -欲了解更多信息,请参阅 - -白皮书(内有关于以太坊平台的概述,并包括平台发布), - -黄皮书(内有关于以太坊技术的实现规范), - -官方网站[https://www.ethereum.org/](https://www.ethereum.org/) 里面有关于包括介绍的视频等以太坊的简要概述, - -本文档介绍了ĐΞV计划如何制定以太坊的软件平台,在以太坊项目的大背景下ĐΞV计划的定位。 - - - -历史与愿景 - - - -在2013年11月创始人Vitalik Buterin对以太坊的核心理念开始有一个明确的看法。动机是为了创建一个有内置的编程语言的加密平台,试图归纳成以下的概念,比如取款限额的存储钱包,多重签名托管,投注,差价合约等。“合同”这个全方位的概念将允许用户用任意算术公式的复杂组合和嵌套的if-then语句来设定资金使用的条件。 - -为了简单和易于开发,项目在质数币的基础上建立元币(为了不激怒比特币的开发者们,因为他们担心以比特币为基础的的已有的元币将会使得块链表不断膨胀),并定于在2014年1月的月底开始发布。在2013年12月Vitalik私下散发了原始的概念白皮书,后来白皮书随着时间的推移被散发到了更广泛的圈子里。 - -此后,该项目的范围已被大大扩展了。早在十二月中旬,随着大量的且出乎意外的爱好者被吸引进来,该项目第一次扩展,具体化成一个独立的块链。然后逐渐扩展到其他的副项目,例如抗集中化的POW算法,一个加密货币研究小组,在美国和瑞士的法务经营,以及以太浏览器的最终理念,还有目前处于概念阶段的代号为“细语(whisper)”和“蜂群(swarm)”的辅助协议。此外,为了有一些重要的基础级应用,真正让以太坊的生态系统大放异彩的要求越来越清晰:一个智能合约和分散式应用程序(Đapps)的开发和调试环境,一个能加强经济和社交互动的信誉系统,一个能公平地分配应用子符号的身份制度,智能合约和网页的的大量域名注册,钱包,当然还有一个应用程序的商店本身(但要注意,下载的应用程序将是免费的)。 - -当然,ĐΞV并不打算开发一切。利用这个技术,目前的贡献者,以及数百位其他加密学家和之前的开发者已经开发并将其应用于解决一系列困难的领域的问题,如消费者保护,公民自由,国际金融和合同,法律,分布式治理,并且可在漫长而艰苦的旅程中保持持续发展。尽管在每一个领域都已经有组织开始行动了。 在一个因为利用加密方式而变得可能的开放,透明,分布式的未来里,ĐΞV只希望并且成为一个小小的但很重要的部分。 - - - -组织结构 - - - -以太坊项目将由以下3个组织组成 - -![](http://bitcoin8btc.qiniudn.com/wp-content/uploads/2014/11/file0002.jpg) - -以太坊基金会: - -总部设在瑞士楚格州的非营利基金会,这个基金是负责为未来加密货币研发和推进开发的其他机构分配资源的伞形公司。该基金会的董事会由Vitalik Buterin(主席),Mihai Alisie(副主席),Taylor Gerring, Stephan Tual, Joseph Lubin, Jeffrey Wilcke 还有 Gavin Wood组成。该基金会将重点放在首要的“使命”上,即,使运营机构来完成每天的日常工作。 - -以太坊瑞士有限公司: - -总部设在瑞士的一家公司,为了领导创世块链的发行,将负责运营2014年度的一部分工作。该公司由以太坊基金会100%控制,计划在创世块链发行后停止运作。 - -ĐΞV: - -将得到两档基金来专门建立的一个非营利性组织,优化和推广以太坊1.0版本。主导开发者Vitalik Buterin,Gavin Wood 和 Jeffrey Wilcke为董事。 - -其他组织: - -包括自律组织(SRO)和非营利性研究机构,这些组织可能会同时得到资助。根据预计,以太坊瑞士有限公司将会协助这些研究机构的起步,以太坊基金会可能将会监督SRO的活动。最终,以太坊基金会还将监督研究机构本身。 - -资助优先顺序: - -以太坊瑞士有限公司将从以太币预售里获得的利润,按照盈利用途资料(其它帖中有解释)中描述一样进行分配。但它保留在必要时修改盈利用途的权利。 - - - -以太坊1.0 - - - -以太坊1.0代表了ĐΞV和以太坊瑞士有限公司和的首要目标。以太坊基金会则将会把兴趣放在促进整个加密空间的发展上。在此时(2014年8月份),以太坊平台发展的状态可以被预计为处于从开始到结束中的中途状态,预计1.0版在2014年末2015年初的期间被发行。 - -自2014年1月份项目成立以来,自愿贡献的开发人员已经完成了以下功能: - -黄皮书中说明的完整的以太坊协议4个近乎兼容的以太坊客户端,分别由C+ +,Go,Python和Java构成Serpent, LLL 和 Mutan的3种编程语言,以及完全正常工作的编译器, 一个可用的JavaScript API ,一个块链协议的概念,允许有12秒的阻塞时间,马上就要被实现建立在经过数个月的对挖矿和POS的研究上的概念=阿尔法版本POW - -由于上述的努力,第三方开发者已经可以并且建成功能完备的分布式应用(“Đapps”),如域名注册,货币,彩票,众筹应用程序和去中心化治理的实用程序,例如由社区建立的“DOUG人民共和国“。 然而,许多困难的工作,包括安全审计,优化策略的即时编译,建立在浏览器上的用户界面和集成开发环境尚未完成。具体的进度请参阅网站上的以太坊1.0开发路线图。 - - - -以太坊客户端 - - - -目前有四个可运行的,分别由C+ +,Go,Python和Java实现的几乎全兼容以太坊协议的客户端。C + +和Go实现的客户端目前完全兼容。 - -Go专用客户端开发 - - ![](http://bitcoin8btc.qiniudn.com/wp-content/uploads/2014/11/file0003.jpg) - -![](http://bitcoin8btc.qiniudn.com/wp-content/uploads/2014/11/file0001.jpg) - - 以太坊浏览器 - -ĐΞV有意使Go客户端成为以太浏览器(EtherBrowser),作为最基本的客户端被个人用户用以访问建立在以太坊上的Đapps。这个客户端正如其所建议的名字的一样,将会成为基于WebKit和Qt的一个全功能的类Web浏览器。我们有意使用同一个应用程序同时浏览传统的集中式网络以及去中心的,更“以太”的网站。目前,这一功能的基本实现已经存在。也可以写一个标准的HTML/ CSS/ JavaScript的网页,使用以ETH对象为JS API与blockchain交互,用户可以使用Go客户端访问该页面以使用Đapp。用QML写Đapps也是一个选项。 还有若干有待完成的重要任务,主要是在提高用户界面体验上。还有一个需要架构和ĐΞV建成的重要组成部分是一个多重钱包和权限制度,为用户提供一个简单而直观的方式来准确地限制Đapps在个人账户上的活动和消费。 - -C++专用客户端开发 - -![](http://bitcoin8btc.qiniudn.com/wp-content/uploads/2014/11/file0004.jpg) - -ĐΞV定义C + +客户端为最基本的开发客户端,允许人们轻松的建立和调试智能合约和Dapp,包括面向合约编程语言和javascrip的语法树意识代码编辑工具,库和软件开发工具包和其他齐全功能。 - -C + +客户端作为以太坊的全功能客户端,包括对以太坊虚拟机(EVM)与块链协议的完全支持,并且包括一个双向步进调试器以帮助开发人员编写智能合同。然而,仍有待做的为去中心化应用提供完整的,产品级的开发环境,全部内容包括JavaScript/ QML和智能合同,集成测试,完整的多语言支持,语法意识的代码编辑器,和其他组件和工具。 - -其他客户端 - -其他三个基准客户端用Python,Java和JavaScript编写。 - -Python的客户端是易于安装,易于使用,多功能的,对开发人员友好的命令行客户端,有可能但不一定会带有最简单的图形用户界面,但功能基本能满足类似pybitcointools库的角色。 - -JavaScript的客户端将会一个简单而简约的装置,主要用于在浏览器中的教学功能,但它最终可能会被用在基于浏览器扩展的客户端。 - -Java客户端可作为特殊硬件的后台程序和Android智能手机。 - -维护在多样化的客户端上的连接和以太坊网络运行强制一个更加整洁的协议的开发和文档备案,并且增加整个系统的健壮性:假设其他的客户端的实现不被影响的前提下,一个问题的客户端的实现不会的话可能会导致整个网络崩溃。 - -扩展性团体目前正在开发其他客户端,包括例如Clojure的,Objective C和node.js。 - - - ![](http://bitcoin8btc.qiniudn.com/wp-content/uploads/2014/11/file0005.jpg) - -共识和安全性测试 - - - -在ĐΞV的努力下,以太坊虚拟机(EVM)的开发者正在试图解决一个非常困难的挑战:用多种实现方式,创建一个递归的,图灵完备的,可以定量计算的虚拟机的规范。每个实现都能对每个程序和输入数据进行同样的处理。因为模型的简约性,在模型中,使用一个自定义,重度封装的虚拟机语言,除非交易允许否则没有网络处理,文件系统访问,直接存储器操作或任何种类的I/O处理。太多的复杂性被大大降低,即便如此仍然需要一个非常广泛的测试套件,以确保错误是尽可能不存在的。 - -另一个重要问题是安全性,在以太坊中有两种类型的的潜在安全问题。首先是虚拟机的安全问题:经常被关注的安全性问题是针对某种缓冲区的溢出攻击是否可能。我们针对这种攻击的防御是简约性,正如之前关于共识的讨论,事实上,共识机制的脆弱性本身就是一个上面提到的非常有效的早期预警系统。如果有一种方法可以在EVM中从“外面的世界”获取数据,那么只要这种方法被利用,无论是故意或由随机的尝试,不同的用户将以不同的方式处理代码,因为它们具有不同的外部状态,将导致可被检测到的即时共识失败。如果研究和协商的结果使得ĐΞV相信,这些论据不足够的话,正式的沙箱的附加层可能会被添加。 - -第二个安全问题是恶意的误导用户的智能合同或Đapps(隐藏其处理的真实理)。为了解决此问题,一个结合权限系统,合同认证和在Đapp商店的信誉系统的多层次方法还有正式的证据将会被使用。合同认证不是必要的,针对某种特殊类型的Dapp,会增加一层监督和保证以确认。当然,任何开发人员可以自由地创建自己的认证系统。 - -共识和安全是主要关键路径项目,没有共识和安全,以太坊1.0将无法发布。 如下图所示,ĐΞV预计,重要的项目大致时间表如下: - -1,开发一个庞大而最大可能完整的测试库,并确保每个EVM通过所有这些测试(4-8周)。 - -2,确保测试继续通过,同时实现即时编译,字典树存储优化和轻客户端的协议(1-4个月)。 - -3,持续的安全审查和测试(最多3个月)。 - -![](http://bitcoin8btc.qiniudn.com/wp-content/uploads/2014/11/file0006.jpg) - - - -细语(Whisper)与蜂群(Swarm)协议 - - - -细语(Whisper)是ĐΞV目前正在开发的一个处于概念阶段的协议,计划成为一个通用的点到点(P2P)通信协议。在以太坊的每个节点可以为自己生成一个基于公钥的地址。细语可让客户端将消息发送给某个特定的接收者,或者通过附加到信息里的描述性标签或“主题“,将消息广播给多个接收者。 节点会聪明的利用尽可能多的有效信息,在彼此之间的路由消息。信息包括已知的有趣的话题(节点可以自由的用广播过滤他们对之感兴趣的话题),以及消息的生存时间(短的消息往往有更高的优先级)。所有的信息都含有生存时间,这样即使接收者处于离线状态,消息可最终通过。 - -细语可能需要1-2周的时间来研究适当的协议规范,然后一个专门的团队在2-4周的时间来实现最初的原型(可能与其他开发并行进行)。我们会持续的把原型改进成一个成熟的实现。 - -![](http://bitcoin8btc.qiniudn.com/wp-content/uploads/2014/11/file0007.jpg) - -蜂群(Swarm) - -蜂群目前是一个处于概念阶段的文件存储和传输协议,专门针对静态网页内容的托管。在峰群里的每一块内容将被存储在P2P网络并通过其哈希值寻址。这样做的目的为了让细语,蜂群和以太坊协议一起被实现,并且可从以太浏览器上访问的,最终成为几乎所有的理论上可以分散的应用程序的的骨干。例如,一个分散的消息系统,它使用户能够即时和异步发送140个文字的消息给其客户,将使用以太坊的名称登记,映射人类可读的帐户的用户名到系统识别的基于公钥的身份认证,因为你肯定不喜欢发送decentralized-blast@ cd2a3d9f938e13cd947ec05abc7fe734df8dd826。这种类型的分散式消息服务将采用细语来发送消息,并用蜂群来存储包括HTML/JS/CSS网页的静态内容。 - -轻量级实现与移动实现 - -自从以太坊项目成立以来,包容性一直是其指导性原则。这意味着努力使以太坊平台向所有人开放。 ĐΞV将努力使轻量级客户端适用于iPhone,安卓以及其它的智能手机用户,无法使用旧笔记电脑处理下载完整区块链的用户,不能做任何实质性的加密技术的特殊手机的用户。在前者的场合,以太坊协议包括一个强壮的轻量级客户端,使轻量级客户端能够取得正确的区块链数据,提供至少一个诚实的充分验证的节点(是单个诚实的节点,而不是多个)。ĐΞV打算用多种编程语言来实现这个协议,以便包容跨平台手机。咋后者场合,可能需要做出一个基于服务器的更集中的的钱包,因为所有的用户都应该得到最好的体验。 - -挖矿算法的研究与发展 - -中本聪原本​​打算让每个人都具有用台式电脑来挖采比特币的能力,从而形成高度分散的共识和平等分配方案。今天的比特币挖矿是一个高度集中的行业。大约有一半的矿工通过两个大型矿池在挖矿,几乎所有的挖矿都由少数几家公司生产的高度专业化的硬件来完成。深圳的一个工厂目前占了几乎所有新的被添加到系统中的哈希力的25%。找出一个更分散的,公平的挖矿算法是困难的但重要的任务,从2013年12月开始已经有不同的人在实现这个任务。 - -有2个挖矿想法被证明是死路,正处在开发的中途阶段的是一个基于更严格的数学策略,随机生成哈希函数的想法,这个想法看起来可以通过初次审核 。 ĐΞV打算开发这个算法,也许会另外加入股权证明(POS),来作为以太坊1.0的共识算法。剩下的主要行动项目是来自学术界和加密货币社区内的专业评审,这一过程很可能会大大的改变算法,还有就是许多重要参数的指导选择(如包含哪些操作,是否要让它内存困难,如何平衡回路的长度和宽度)。 - -![](http://bitcoin8btc.qiniudn.com/wp-content/uploads/2014/11/file0008.jpg) - -分布式应用开发 - -在过去的几年里加密货币技术的发展已逐渐让人们更容易的构建分布式应用。以太坊的区块链和以太浏览器是帮助推动这一趋势的重要工具。然而,还可以建立其它的组件来帮助让Đapps充分发挥其潜力。从本质上说,我们的意图是要建立一套核心应用程序,将提供必要的实用功能,比如说钱包和消息,具体关注“元Đapps”ー帮助其他Đapps的Dapps。这方面的一些例子包括Đapp商店(当然其本身就是Đapp),名称登记(一个或几个),信誉系统,防女巫攻击系统(理想就是在高信任度的场合,让这最后的组件强大到足以作为护照的功能性替代品)和分权治理的工具。以下的列出来的是有可能需要建设和支持的重要的核心Đapps。 - -钱包 - -在加密货币平台最基本的一个应用是钱包。但是,今天能看到的基本的比特币钱包,除了像BitGo一样的创新者以外,在面对可用性和安全性的平衡的挑战上大多数相当薄弱。以太坊平台允许,以先进的取款策略,模仿银行式的保护措施,比如取款限额和不需要信任何来自第三方的单方监管或取款权的双重身份验证,的钱包简单开发出来。建立一个结合上述策略,同时为10美元,1000美元到10万美元提供安全性和便利性之间的最佳平衡的钱包是一项重要的任务。同时拥有使用以太币以及基于以太坊的子货币甚至有可能其他加密货币的能力的钱包将是生态系统的重要福利。 - -细语(Whisper) - -消息平台 – 加密货币的用户喜欢分权和喜欢Skype一样多。但因为以太坊将有细语,还有基于区块链的账户名字登记。为什么不拿出一些资源,创造一个能替代现有的群文本聊天系统的平台?这个平台既是开源的又是点对点的,能使用以太浏览器及相关工具,在一个庞大而成熟的社区形成后启动以太坊平台。随着时间的推移,这样的平台也可以扩展到音频,视频和甚至异步通信,例如电子邮件。细语说明图 - -http://bitcoin8btc.qiniudn.com/wp-content/uploads/2014/11/file0009.jpg - -声望系统 - -为了让电子商务获得成功,在很多情况下,人们必须能够知道谁值得信赖。在某些情况下,你需要分辨诚实的人和骗子。在有些情况下,你要分辨专家的和新手。还有一些时候,它不只是关系到一个人的当前声望是什么,还有他们是如何快速的提高了当前声望,这样你可以确定的,他们不能通过一拍子买卖来欺骗大家获利。即使在现代社会的今天,线上和线下,这些问题是很难解决。在分散自律组织的情况下,这些问题变得更加困难。搞清楚什么可以做,什么应该做的,还有考虑到不同的形式Đapps彼此之间的信任关系,有效的信誉基础设施而言将会是关键问题。 - -身份系统 - -有一种特殊的声望,它涉及一个具体的问题:某个账号是真实存在的人吗?还是由一个人或一个自动化的系统创建的5000个帐户之一。解决这个问题要搞清楚,如何公平地分配应用程序代币或应用程序的使用优先权,即使没有花钱也要让每个人都可以有限的访问生态系统,等事情的关键。一个有趣的建议是,用准分散的方式实现的话,可以用“非女巫式代币”的投机市场。任何人都可以创建一个“完全自动化的公共图灵测试来分辨计算机和人类”(简称CAPTCHA)方案(理论上可以包括抄写一些字母和数字,玩游戏,证明社会关系,或者比较传统的像手机号码或护照),但只有在公开的情况下否则违反任何个人方案都会非常有利可图的。任意一个ĐAO/Đapp可以观察一下整个系统,看看哪些CAPTCHA机制仍然是安全的,并自动使用这些安全的机制。 - -分散的挖矿池基础设施 - -如果区块链变得非常大,挖矿变得普及起来话,那么就像比特币的情况一样,矿池可能会变得有必要。然而,在这种情况下,ĐΞV决心要最大限度地让分散式的代替方案更有利,比如说P2P矿池而不是集中式解决方案。即便要求必须要用集中式的解决方案,保守的预计我们会建立一个“制作自己矿池”的工具,使市场更具流动性,减少因为矿工规模大小而导致的支付差异,降低入门门槛。 - -除了这些重要的核心应用,如果在被给予足够多的资源的前提下,也有一些是ĐΞV可以选择参与建立的其他应用程序。包括: - -1、分散式交易所(基于以太币的资产和不同的加密货币之间) -2、分散式市场 -3、众筹 -4、托管,消费者保护和仲裁 -5、内容发布(包括激励内容创作者) -6、金融应用(例如对冲,先令美元,保险) -7、分散的广告协议 -8、分散的组织管理 - -虽然ĐΞV打算在“核心”的应用程序上努力,但我们可能会有以下几种形式来参与更多外围Đapps上的开发:在某个项目上ĐΞV可以完全靠自己的努力,ĐΞV可以简单地建立某解决方案的核心部分,并允许其他人继续完成其他部分。或者ĐΞV可以从向社区中的已经接受任务的外部团体提供资金,技术或开发支持给。 - -社区推广以及教育 - -虽然推动以太坊发展的底层的技术可以说相当先进,我们的主要目标一直是让广大的开发者能够接触到以太坊平台的强大功能。 HTML的技能,再加上一些JavaScript的知识是建立大多数分散型应用的全部知识。底层的“加密”层被巧妙的抽象到了面对用户友好的API的背后。对于终端用户而言,如果他们愿意使用Web浏览器,他们肯定会喜欢上使用以太浏览器的。 - -一个无需开发人员和终端用户的以太坊平台,将看到朝着分散式网络努力已经是徒劳的。因此ĐΞV需要确保(1)人们了解以太坊和(2)人们都知道如何利用它。为此,该项目的一个重要组成部分,是维护我们的在线和离线的存在,帮助支持世界各地的中心和社区,并最终组织或合作组织会议(无论是专门针对以太坊,还是针对分散式网络这个整体)。 - -这一努力的另一个重要组成部分是教育,包括发布易于使用的在线教程和为了理解以太坊平台的网络大学Udemy的课程,以及智能合约/Đapp编程研讨会。黑客马拉松也可能属于这一类。 - -网上开放课程 - -海量的网络公开课 – 从头到尾的完整的以太坊和智能合约/Dapp开发的在线课程已经被指定开发了。课程将会包括视频,文字材料,练习和人们可以很容易地尝试编写以太坊代码的编程环境。这个课程的目的是能对任何想学习以太坊平台使用的人有用处。ĐΞV也可能,或者是靠自己或者依靠协同合作,来创造不同的难度/深度/水平或不同学科领域的多种课程(如经济学,加密学,社会理论,计算机科学和编程)。 - -开放教程 - -教程和文档 – 对于那些没有耐心去通过完整课程的人,需要有描述以太坊平台的高层次和低层次的所有组成部分,还有解释如何执行作为一个开发者想做的的所有常见的操作(如写智能合同,开发Đapp,发布Đapp,发送交易,使用蜂群Swarm,使用细语Whisper),并且容易理解的文档。此外,还有可能需要用户的教程,虽然首要任务是使分散的Web像传统的,现时的浏览器一样简单和随便。 - -开放交流 - -在线交流 – 这包括继续对我们的公共博客,论坛,维基渠道,以及任何其他第三方渠道(比如Facebook,Twitter,Google+,Reddit)的交流进行维护。主要目的是确保每个人都可以很简单的获得最新和准确的关于对以太坊计划中的所有部分的状态和信息 - -开放社区 - -离线交流 – 这主要包括全世界各地支持以太坊和关注于分散式网络的群体的聚会,这最终可能会扩展到成完全成熟的会议。 ĐΞV打算在世界上尽可能多的地方设立代表,包括北美洲,中/南美洲,欧洲,亚洲和非洲。我们目前的聚会地点的人脉网络将成为这一工作的中坚力量。 - -开放访问性 - -翻译 – 国际化的一个重要组成部分是支持多种语言的使用。目前已经有部分中文翻译,以及一些德语和西班牙语的翻译,但最终所有的以太坊平台的客户端,文档和在线课程材料都必须被翻译成多国语言。 ĐΞV总是在寻找的各种语言的具有技术常识的翻译者。 - -加密经济学研究和继续开发 - -以太坊的当前状态是很强大的,1.0版本发布后也会如此,但是这离完美还远远不够。挖矿算法可能不会坚持分散性这个目标,也许计算生态系统作为一个整体可能会非常严重地转向瘦客户机,作为一个整体的,分散性的计算能力可能会成为一个无法实现的理想。它的可扩展性目前与比特币相比较也好不到哪里去,因为每个节点仍然必须处理每笔交易。比如PeterTodd的树链,超立方体链,资源证明,还有如Eli Ben-Sasson的 的简洁计算完整性和保密性协议(简称SCIP,也被称为PCP或ZK-SNARK)等可能的“月亮数学”加密,之类的新概念可能不会被包含在以太坊1.0版本中。 - -由于加密货币将来的发展有很多可能的方向,没有人能预测在遥远的将来正确的决定是什么,所以在以太坊1.0发布后,不能做出任何关于开发可能性的细节承诺。但是,关于目前加密货币研究的一个大方向,已经有一个相当不错的愿景已经浮现了。 - -扩展性 – 这里的主要挑战是要拿出一个区块链设计来打破现在的区块链的扩展性的障碍。事实上现在,每一个充分验证的节点必须处理每一笔交易。已经有主要是关于比特币的一些想法被发展起来,如合并挖矿的超立方体链,Peter Todd’s的树连锁的想法,还有基于先进的加密技术(SCIP/zk-SNARK)的策略,但仍有很多研究需要做。一个成功的有扩展性的解决方案将需要处理跨越不同的实体存储在不同国家的货币,不能牺牲(太多)挖矿的安全,即使有些数据不可用,必须保证该协议继续工作。运气好的话,一个解决方案将在2014年和2015年期间被完成。 - -共识 – 正如上面所讨论的,共识算法是远远不够完善的。计划里,用基于区块链的POW,还有随机计算树,似乎很有希望来解决这个问题。但最终的这种形式的以太坊1.0版本很可能无法承受长期的攻击。一个理想的算法,同时具有对社会的无成本和负成本,促进高水平的分权和安全性,可能会需要新颖的下列方法的组合,如交易的POS(股权证明),委托POS(DPOS),有用的POW(工作证明),新一代抗集中/ ASIC的POS和更奇特的涉及带宽和存储的策略。开发这样的算法,并确保它确实可行,是确保明天的区块链安全的一个重要的优先事项。 - -隐私保护 – 区块链的极不完善的隐私性是非常有名的。到今日的以太坊平台的设计,在这方面也是公认的没有特别的有效方案。然而,未来的提高隐私的开发,如基于SCIP/zk-SNARK的算法都将来临,有的一些基于如CryptoNote和CoinJoin的技术已经存在了。 - -语言和开发工具的设计 – 从以太坊平台早期的讨论和规划中涌现出的另一个重要的子交付是完全确定计算量的,状态散列的多个完全可互相操作的虚拟机的实现。以太坊虚拟机(EVM)无论是在区块链还是对手的,资源受限的环境中都非常有用,并会从不断开发中就其本身受益。如果多区块链架构成为主流范式,EVM还可能需要被更新,以处理诸如不同步的情况。除了EVM本身,有Serpent, LLL and Mutan的高级语言,为了建立分布式应用ĐΞV已经开始致力于建立专门的开发环境。 - -后量子加密 – 如果量子计算机变的普及起来。那目前以太坊平台上的签名交易,依赖的椭圆曲线签名算法,会被破坏。然而,确实存在着一类签名算法,它们能够抵抗量子计算的攻击,最著名的是Lamport签名。Lamport签名在其构建时候除了一个哈希算法外没有使用任何其它东西,但它占用上千字节的,且仅限于一次性使用。被改善的称为Merkle签名树和哈希阶梯将解决这些问题,但还是不完美的。这些算法改善得越多,更多的人就可以对量子计算到来的那一天不会出现问题而感到自如。 - -月亮数学加密(Moon-math cryptography) -在纯加密科学界最令人振奋的开发围绕着3个圣杯。 第一个是完全同态加密:在不知道数据是什么的情况下,能够对加密数据运行函数来得到一个加密的结果,这将允许云计算做到几近完全的隐私。二是上面提到的SCIP,有效简洁的可验证的证明允许一个特定的长的计算有一个给定的结果。最后一个是困惑:能够在不知道函数是什么的情况下,运行数据加密功能,它允许使用带有私有数据的脚本在区块链上运行。所有这些问题都有从开发的早期到中期阶段的解决方案,但解决方案目前不是在效率就是在信任要求上有大量的缺点。如果解决方案能够完善或至少改进到有生存能力的那点的话(SCIP是非常接近了),加密经济协议可能会变得更加强大。 - -DAO化 – 可以建立在以太坊上的事情的想法中,最令人兴奋的是去中心化自治组织(DAO)的概念。传统的组织,无论是企业还是非营利性,无非是一套人马,一组资源和一套管理谁可以使用资源的规则。在DAO里,规则并不是如同在现实世界里的被强制执行的和司法系统,而是在区块链上以分散和透明的方式强制执行。比如说不同于传统的现代跨国公司,那里是核心的智能化和外围的自动化,在一个DAO里,核心是自动化,外围是人类智慧来提供创意输入。DAO的主要的中期吸引人的地方在(1)消除员工,投资者,客户和非雇员之间的严重差别的梦想,让DAO促进更细致的,更活跃的关系,并充分利用人类贡献的全部幂律曲线以及(2)尝试新的​​组织管理机制,如流动体民主主义和部分被投机市场控制的理论上的政府。最后,DAO,工厂自动化和AI的概念甚至可能完全合并。 - -CCRG – 为了专门推动加密货币研究,ĐΞV正在推出一个叫作加密货币研究小组的机构。这个机构正处于开发的早期阶段。它的领域活动包括加密技术,加密货币,经济,金融,法律,政治及其他,在未来数个月内将会大幅加速发展。预计它会成长为一个从其他加密货币空间的团体,以及高新技术企业和慈善家来吸取资金,完全或很大程度上自治的组织。可能会创建独立的机构来专门开发协议。如果要想知道加密货币研究的更多的全面的意义,请读正在写作中的“加密经济难题”论文。 - -自律组织 – 从技术的角度来看或许是乏味的,实现接受分散式技术的一般使命的重要部分就是就是参与合法的流程,并帮助开拓一个合法的环境,在这个环境里一些项目,例如以太坊平台,建立在以太坊平台上的Dapp,还有其它的加密货币/基于Web的初步的分散式网络,可以安全地茁壮成长而不受过分的限制。其中,以太坊瑞士有限公司正在进行的初步行动是,与OpenTransactions,比特币瑞士等进行协作,为了这个目的在其家乡瑞士开发一个自律组织。以太坊瑞士有限公司正在与有自律组织的建成经验的当地律师事务所一起紧密合作,并且最小的自律组织可以用低于10万美元来维持运营。额外的资金可以让自律组织扩大其范围和影响力,也迟早会让这些工作超越瑞士。 - -其他项目 - -当然,上面只是一个向导,ĐΞV可以选择不追求上面的一些或者采用超出上述类别的其他项目。一些特定的可能性包括: - -DAO化 – 虽然DAO化肯定会是加密货币的一个主要的研究重点,长期的计划总是把不同的以太坊组织变成DAO,通过建立一个长期的管理平台,可以用于继续研究和开发来作为一个驱动社区发展的活动。 - -会议 – ĐΞV可以选择,无论是单方还是在与业内其他团体协调,来组织与分散网络相关的技术,法律,社会可能性的会议。这样的会议可以是以营利为目的获得持续收入来源或非营利但以收回成本的原则运行。除了会议,还有组织以开发人员为中心的教育研究会的可能。 - -中心 – 在比特币社区有一个流行的想法,即创建特定的比特币中心。在设施中,比特币用户可以正常工作,可能生活和互动。在蒙特利尔和特拉维夫的比特币大使馆,在多伦多的比特币非中心和在纽约的比特币中心都是突出的例子。 ĐΞV不妨为社区建设活动而协助建立更多这类中心。 - -本文供参考。 - - - - diff --git "a/pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\346\234\257\350\257\255\350\241\250.md" "b/pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\346\234\257\350\257\255\350\241\250.md" deleted file mode 100644 index 787cf22e5..000000000 --- "a/pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\346\234\257\350\257\255\350\241\250.md" +++ /dev/null @@ -1,128 +0,0 @@ ---- -name: 术语表 -category: ---- - -翻译:Andy - -关于加密货币以及任何新的技术的令人不爽的一件事,就是其用于描述所有新概念的词汇的绝对数量。只要不是临时的,最基本的处理的情况,任何与在点对点互联网软件打交道的人都需要与加密的概念打交道,包括散列,签名,公钥,私钥,对称和不对称加密,服务保护拒绝,还有例如分布式哈希表,信任网络之类的神秘的构造。新的比特币用户被迫与学习加密的基本常识而奋斗,还有额外的内部术语,如“区块”,“确认”,“挖矿”,“SPV客户”和“51%的攻击”,以及经济概念,如激励相容和集权与分权的微妙差别。以太坊,作为一个基于加密货币的泛化的分散的应用开发平台,必然既包含这些概念的集合,也增加了许多自身的概念。为了帮助新来以太坊的人,无论他们是加密货币爱好者,企业家,社会或政治愿景家,Web开发人员或只是看看这项技术能如何改善生活的普通人,下面的列表的目的是为了提供一个以太坊用户常常使用的词汇的基本总结: - -密码学 - -另请参阅:http://en.wikipedia.org/wiki/Public-key_cryptography - -计算上不可行:一个处理被称为是计算上不可行,如果有人想有兴趣完成一个处理但是需要采取一种不切实际的长的时间来做到这一点的(如几十亿年)。通常,2的80次方的计算步骤被认为是计算上不可行的下限。 - -散列:一个散列函数(或散列算法)是一个处理,依靠这个处理,一个文档(比如一个数据块或文件)被加工成看起来完全是随机的小片数据(通常为32个字节),从中没有意义的数据可以被复原为文档,并且最重要的性能是散列一个特定的文档的结果总是一样的。 - -此外,极为重要的是,找到具有相同散列的两个文件在计算上是不可能的。一般情况下,即使改变文件的一个字母也将完全打乱散列;例如,“ Saturday”的SHA3散列为c38bbc8e93c09f6ed3fe39b5135da91ad1a99d397ef16948606cdcbd14929f9d,而Caturday的SHA3散列是b4013c0eed56d5a0b448b02ec1d10dd18c1b3832068fbbdc65b98fa9b14b6dbf。散列值经常被用作以下用途:为无法伪造的特定文档而创建的全局商定标识符。 - -加密:与被称为钥匙(例如c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4)的短字符串的数据相结合,对文档(明文)所进行的处理。加密会产生一个输出(密文),这个密文可以被其他掌握这个钥匙的人“解密”回原来的明文,但是对于没有掌握钥匙的人来说是解密是费解的且计算上不可行。 - -公钥加密:一种特殊的加密,具有在同一时间生成两个密钥的处理(通常称为私钥和公钥),使得利用一个钥匙对文档进行加密后,可以用另外一个钥匙进行解密。一般地,正如其名字所建议的,个人发布他们的公钥,并给自己保留私钥。 - -数字签名:数字签名算法是一种用户可以用私钥为文档产生一段叫做签名的短字符串数据的处理,以至于任何拥有相应公钥,签名和文档的人可以验证(1)该文件是由特定的私钥的拥有者“签名”的,(2)该文档在签名后没有被改变过。请注意,这不同于传统的签名,在传统签名上你可以在签名后涂抹多余的文字,而且这样做无法被分辨;在数字签名后任何对文档的改变会使签名无效。 - -区块链 - -也可参考:https://bitcoin.org/zh_CN/vocabulary - -地址:一个地址本质上是属于特定用户的公钥的表现;例如,与上面给出的私钥的相关联的地址是cd2a3d9f938e13cd947ec05abc7fe734df8dd826。注意,在实际中,地址从技术上来说是一个公钥的散列值,但为了简单起见,最好忽略这种区别。 - -交易:一个交易是一个文档,授权与区块链相关的一些特定的动作。在一种货币里,主要的交易类型是发送的货币单位或代币给别人;在其他系统,如域名注册,作出和完成报价和订立合约的行为也是有效的交易类型。 - -区块:一个区块是一个数据包,其中包含零个或多个交易,前块(“父块”)的散列值,以及可选的其它数据。除了初始的“创世区块”以外每个区块都包含它父块的散列值,区块的全部集合被称为区块链,并且包含了一个网络里的全部交易历史。注意有些基于区块链的加密货币使用“总账”这个词语来代替区块链。这2者的意思是大致相同的,虽然在使用“总账”这个术语的系统里,每个区块都通常包括每个账户的目前状态(比如货币余额,部分履行的合约,注册)的全部拷贝,并允许用户抛弃过时的历史数据。 - -帐户:帐户是在总账中的记录,由它的地址来索引,总账包含有关该帐户的状态的完整的数据。在一个货币系统里,这包含了货币余额,或许未完成的的交易订单;在其它情况下更复杂的关系可以被存储到账户内。 - -工作证明:在比特币,以太坊和许多其他加密总账里的一个重要特性,意思是在区块中的散列值必须比某个目标值小。这个必要的原因是,在分散式系统中任何人可以产生区块,因此为了防止网络中区块泛滥,并提供一种方法来衡量在区块链的一个特定版本后有多少共识,使得产生一个区块非常艰难。由于散列值是伪随机的,找一个散列值比0000000100000000000000000000000000000000000000000000000000000000还小的区块,平均需要43亿次尝试。在所有这些系统中,目标值进行自我调整以便在网络上的一个节点平均每N分钟(例如,比特币N =10,以太坊N=1)发现一个区块, - -随机数:在一个区块里的一个无意义的值,为了努力满足工作证明的条件来进行调整。 - -挖矿:挖矿是反复总计交易,构建区块,并尝试不同的随机数,直到找到一个随机数可以符合工作证明的条件的过程。如果一个矿工走运并产生一个有效的区块的话,会被授予的一定数量的币(区块中的交易全部费用)作为奖励。而且所有的矿工开始尝试创建新的区块,这个新区块包含作为父块的最新的区块的散列。 - -陈腐区块:对于同一个父块,已经有另外一个区块被创建出来之后,又被创建的区块;陈旧区块通常被丢弃,是精力的浪费。 - -分叉:指向同一个父块的2个区块被同时生成的情况,某些部分的矿工看到其中一个区块,其他的矿工则看到另外一个区块。这导致2种区块链同时增长。通常来说,随着在一个链上的矿工得到幸运并且那条链增长的话,所有的矿工都会转到那条链上,数学上分几乎会在4个区块内完结自己。 - -双重花费:是一个故意的分叉,当一个有着大量挖矿能力的用户发送一个交易来购买产品,在收到产品后又做出另外一个交易把相同量的币发给自己。攻击者创造一个区块,这个区块和包含原始交易的区块在同一个层次上,但是包含并非原始交易而是第二个交易,并且开始在这个分叉上开始挖矿。如果攻击者有超过50%的挖矿能力的话,双重花费最终可以在保证在任何区块深度上成功。低于50%的话,有部分可能性成功。但是它经常在深度2-5上有唯一显著的可能。因此在大多数的加密货币交易所,博彩站点还有金融服务在接受支付之前需要等待6个区块被生产出来(也叫“6次确认”)。 - -SPV客户端(或轻客户端):一个只下载一小部分区块链的客户端,使拥有像智能手机和笔记本电脑之类的低功率或低存储硬件的用户能够保持几乎相同的安全保证,这是通过有时选择性的下载的小部分的状态,而在区块链验证和维护时,不需要花费兆字节的带宽或者千兆字节的存储空间。 - -以太坊区块链 - -也可参考: http://1tf.org/index.php?p=/discussion/71/ - -序列化:将一个数据结构转换成一个字节序列的过程。以太坊在内部使用的编码格式称为递归长度前缀编码(RLP),在这里有描述 - -帕特里夏树:一种数据结构,它会存储每个帐户的状态。这个树的建立是通过从每个节点开始,然后将节点分成多达16个组,然后散列每个组,然后对散列结果继续散列,直到整个树有一个最后的“根散列”。该树具有重要的特性:(1)只有正好一个可能的树,因此,每个数据集对应一个可能的根散列(2)很容易的更新,添加,或者删除树节点,以及生成新的根散列,(3)不改变根散列的话没有办法修改树的任何部分,所以如果根散列被包括在签名的文档或有效区块中话,签名或工作证明可以担保整个树( 4)任何人只可以提供一个下到特定节点的分支,可以加密得证明拥有确切内容的节点的确是在树里。帕特里夏树也被用来存储账户,交易已经叔块的内部存储。在这里能看到更详细的说明。 - -幽灵(Ghost):幽灵是一个协议,通过这个协议,区块可以包含不只是他们父块的散列值,也散列父块的父块的其他子块(被称为叔块)的陈腐区块。这确保了陈腐区块仍然有助于区块链的安全性,并减轻了大型矿工在快速区块链上的有优势的问题,因为他们能够立即得知自己的区块,因此不太可能产生陈腐区块。 - -叔块:是父区块的父区块的子区块,但不是自个的父区块,或更一般的说是祖先的子区块,但不是自己的祖先。如果A是B的一个叔区块,那B是A的侄区块。 - -帐户随机数:每个账号的交易计数。这样可以防止重放攻击,其中一个交易发送比如 20个币从A到B,并可以被B重放一遍又一遍,直到不断抽干A的账户余额。 - -EVM代码:以太坊虚拟机代码,以太坊的区块链可以包含的编程语言的代码。与帐户相关联的EVM代码在每次消息被发到这个账户的时候被执行,并且具有读/写存储和自身发送消息的能力。 - -消息:一种由EVM代码从一个账户发送到另一个账户的“虚拟交易”。需要注意的是“交易”和“消息”在以太坊种是不同的;在以太坊用语的“交易”具体指的是物理的数字签名的一串数据,并且每个交易触发相关联的消息,但消息也可以通过EVM代码发送,在这种情况下,它们从不表示成任何数据。 - -储存:包含在每个帐户里的键/值数据库,其中键和值都是32个字节的字符串,但可以以其他方式包含任何东西。 - -外部拥有账户:通过私钥控制的账户。外部拥有账户不能包含EVM代码。 - -合约:一个包含并且受EVM的代码控制的账户。合约不能通过私钥直接进行控制,除非被编译成EVM代码,一旦合约被发行就没有所有者。 - -以太(Ether):以太坊网络的内部基础的加密代币。以太是用来支付交易和以太坊交易的计算费用。 - -瓦斯:大致相当于计算步骤的计量。每一笔交易需要包括瓦斯的限制,还有愿意为每瓦斯支付的费用;矿工可以选择是否收录交易和收集费用。由包括原始消息以及任何可能被触发的子消息的交易产生的计算所使用的瓦斯总量,如果大于或者等于瓦斯的限制,则交易被处理。除非交易仍然有效并且费用仍然被矿工收集,否则瓦斯的总量小于限制则所有变更被还原。每一个操作都有瓦斯支出;对于大多数操作,花费是1瓦斯,尽管一些昂贵的操作会支出高达100瓦斯,交易本身会有500瓦斯的支出。 - -非区块链 - -以太浏览器(Mist):即将到来的以太坊基础客户端,会以Web浏览器的形式存在,可被用来访问正常的网站以及建立在以太坊平台上的应用程序。 - -耳语(Whisper):即将到来的点到点信息协议,将会被整合到以太浏览器。 - -蜂群(Swarm):即将到来的,为静态web托管而优化的点到点数据存储协议,将被整合到以太浏览器。 - -LLL,Serpent和Mutan:为编写合约代码的编程语言,可被编译成EVM代码。serpent可以被编译为LLL。 - -PoC:概念证明(proof-of-concept)的英文缩写,预发布版的另一个称呼。 - -周边概念:应用程序和治理 - -分散化应用程序:为了某些特定目的(如:在某些市场上连接买家和卖家,共享文件,网络文件存储,维持货币),无论是使用还是创建一个分散的网络,由许多人来运行的程序。基于以太坊的分散式的应用程序(也称为Đapps,其中Đ为北欧字母“eth”)通常包括一个HTML/ JavaScript的网页,并且如果在以太浏览器内部查看的话,可识别特殊的Javascript的API,用于发送交易数据到区块链,从区块链读取数据,和耳语,蜂群交互数据。一个Đapp通常在区块链上有特定的相关合约,但有利于创造许多合约的Đapps是完全可能的。 - -分散化组织(GDO):一个没有中央领导,而是使用正式民主投票进程和共识主动性自我组织的结合来作为其基本操作原则。一个不太令人印象深刻,但有时混淆的概念是“地理上的分散化组织”(GDO),组织里人在相距甚远的地方工作,甚至可能都没有办公室; GDOs可能会有正式的中央领导。 - -忒修斯标准:用于查明一个组织的分散化程度的测试。测试如下:假设组织有N个人,然后外星人一次从组织中(比如每周一次)挑选K个人出来,摧毁他们存在,在每个群里以K个对组织不了解的新人来代替。现在为了让组织起作用,K可以高达多少人呢?在独裁政权里,当K=1即独裁者被摧毁后就会失败。美国政府稍微好一点,但如果参议院和国会的所有638成员突然消失了的话,仍然会有很大的问题。但像比特币或BitTorrent即便对极高的K值也具有复原性,因为新的代理人可以简单地根据自己的经济动机来填补缺失的角色。还有一个更严格的测试,拜占庭忒修斯标准,它包含同一时间内随机的用恶意行为者取代K个用户一段时间,之后再替换成新用户。 - -委任式民主(或流动式民主):一个对于DOs(分散式组织)和DAO(分散式自治组织)的治理机制,在默认情况下每个人对每件事情都投票,但在某些特定的问题上个人可以选择特定的他人为他们投票。这个想法概括了以下2种民主的权衡,完全直接民主(每个人都有相同的权力)和专家意见/有某些特定人提供的快速决策能力(允许人们自己顺从朋友,政治家,领域专家或者自己选择的任何人)。 - -部分被投机市场控制的理论上的政府:最初是由Robin Hanson提出的,为了管理政治组织治理机制。但它实际上是非常适用DOs和DAO的:通过预测市场来管理。从根本上,一些易于衡量成功的标准被选择,还有发行由成功标准的值来决定的代币,这些代币将在未来的某个时间(例如,1年后)被支付,对于每个可能要采取的行动都用一个这样的代币。这些代币都被兑换为相应的美元代币,如果相应的措施被执行,正好1美元会被支付 (如果相应的措施没有被执行,这两种类型的代币支付0美元,所以正在被执行的行动的概率不会影响价格)。市场预计的行动将有最好的结果,当其代币在市场上有高价格时会被执行。这提供了另一种自治的,选择机制,同时奖励专家的意见。 - -经济学 - -代币制度:本质上是可以交易的虚拟代替物。更正式地说,代币制度是一个数据库,它映射地址到数字,并具有以下属性,基本允许的操作是把N个代币从A转给B,条件是N是非负,且N不小于A的当前余额,授权该转账的证件由A进行数字签名。二次“发行”和“消费”的操作也可以存在,交易费用也可以被收集,许多当事人同时进行转账也是可能的。典型应用案例,包括货币,网络加密代币,公司的股份和数字礼品卡。 - -命名空间:一个映射名字到值的数据库。举个最简单的例子,如果名称尚未被占有的话(也许可以在支付一些费用之后)任何人可以注册一个条目。如果名称已经被占有了,那么就只能被改变(如果有的话),由作出原始注册的账户(在许多系统中,所有权也转移)。命名空间可以用来存储用户名,公钥,互联网域名,代币制度或其他命名空间,和许多其他应用。 - -身份:一组可以加密验证的互动,具有同一个人创建的的属性。 - -唯一的身份:一组可以加密验证的互动,具有以下属性:同一个人创建的。再加上一个人不能有多个唯一身份的约束。 - -激励相容:如果每个人都更好的“遵守规则”而不是试图欺骗,除非至少要大量的人都同意同时一起欺骗,那么协议是激励相容的。 - -基本收入:每隔一段时间(比如几个月)就给每一个唯一的身份发送一定量的代币的想法。其最终目的是为了让不愿意工作或者不能工作的人能够依靠这份津贴活下来。这些代币可以简单的凭空制作出来,或者来自收益流(比如来自创收实体或政府)。为了单靠基本收入使人能够生活,可能会用到多个收益流的组合。 - -公益:一个为非常多的人提供了一个非常小的好处的服务。这样就没有任何个体对是否进行生产有影响力,因此也没有人有动力来支付。 - -声誉:身份的一个属性,其他实体认为这个身份可以(1)胜任一些特定的任务,或(2)在一些情况下是值得信赖。比如说不太可能因为短期的获利而出卖别人。 - -信任网络:如下的想法,如果A高度信任B,B高度信任C,则A可能是信任C的。为决定特定个体在特定概念下的可靠性的复杂而有力的机制,理论上可以由这个原则推断出来。 - -第三方托管:如果两个低信誉的实体所从事的贸易时,付款人可能希望把钱留在具有高信誉的第三方,并指示只有在产品交付后,才让第三方把钱发给收款人。这减少了付款人或收款人欺诈的风险。 - -保证金:放入合约里的涉及另外一方的数字资产,如果某些条件不满足时,该资产会自动被对方没收。 - -抵押:放入合约里的涉及另外一方的数字资产,如果某些条件不满足时,该资产会自动被销毁或据献给慈善或者基本收入基金。也许可以让利益广泛分配,但必须让特定的个人不能显著的受益。 diff --git "a/pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\347\231\275\347\232\256\344\271\246.md" "b/pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\347\231\275\347\232\256\344\271\246.md" deleted file mode 100644 index a2e59f48e..000000000 --- "a/pages/other-languages/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\347\231\275\347\232\256\344\271\246.md" +++ /dev/null @@ -1,475 +0,0 @@ -### 以太坊(Ethereum ):下一代智能合约和去中心化应用平台 - -翻译:巨蟹 、少平 - -译者注:中文读者可以到[以太坊爱好者社区](http://www.ethfans.org)获取最新的以太坊信息。 - -当中本聪在2009年1月启动比特币区块链时,他同时向世界引入了两种未经测试的革命性的新概念。第一种就是比特币(bitcoin),一种去中心化的点对点的网上货币,在没有任何资产担保、内在价值或者中心发行者的情况下维持着价值。到目前为止,比特币已经吸引了大量的公众注意力, 就政治方面而言它是一种没有中央银行的货币并且有着剧烈的价格波动。然而,中本聪的伟大试验还有与比特币同等重要的一部分:基于工作量证明的区块链概念使得人们可以就交易顺序达成共识。作为应用的比特币可以被描述为一个先申请(first-to-file)系统:如果某人有50BTC并且同时向A和B发送这50BTC,只有被首先被确认的交易才会生效。没有固有方法可以决定两笔交易哪一笔先到,这个问题阻碍了去中心化数字货币的发展许多年。中本聪的区块链是第一个可靠的去中心化解决办法。现在,开发者们的注意力开始迅速地转向比特币技术的第二部分,区块链怎样应用于货币以外的领域。 - -常被提及的应用包括使用链上数字资产来代表定制货币和金融工具(彩色币),某种基础物理设备的所有权(智能资产),如域名一样的没有可替代性的资产(域名币)以及如去中心化交易所,金融衍生品,点到点赌博和链上身份和信誉系统等更高级的应用。另一个常被问询的重要领域是“智能合约”- 根据事先任意制订的规则来自动转移数字资产的系统。例如,一个人可能有一个存储合约,形式为“A可以每天最多提现X个币,B每天最多Y个,A和B一起可以随意提取,A可以停掉B的提现权”。这种合约的符合逻辑的扩展就是去中心化自治组织(DAOs)-长期的包含一个组织的资产并把组织的规则编码的智能合约。以太坊的目标就是提供一个带有内置的成熟的图灵完备语言的区块链,用这种语言可以创建合约来编码任意状态转换功能,用户只要简单地用几行代码来实现逻辑,就能够创建以上提及的所有系统以及许多我们还想象不到的的其它系统。 - -### 目录 - -* 历史 - * 作为状态转换系统的比特币 - * 挖矿 - * 默克尔树 - * 替代区块链应用 - * 脚本 -* 以太坊 - * 以太坊账户 - * 消息和交易 - * 以太坊状态转换功能 - * 代码执行 - * 区块链和挖矿 -* 应用 - * 令牌系统 - * 金融衍生品 - * 身份和信誉系统 - * 去中心化文件存储 - * 去中心化自治组织 - * 进一步的应用 -* 杂项和关注 - * 改进版幽灵协议的实施 - * 费用 - * 计算和图灵完备 - * 货币和发行 - * 挖矿的中心化 - * 扩展性 -* 综述:去中心化应用 -* 结论 - * 注解和进阶阅读 - -### 历史 - -去中心化的数字货币概念,正如财产登记这样的替代应用一样,早在几十年以前就被提出来了。1980和1990年代的匿名电子现金协议,大部分是以乔姆盲签技术(Chaumian blinding)为基础的。这些电子现金协议提供具有高度隐私性的货币,但是这些协议都没有流行起来,因为它们都依赖于一个中心化的中介机构。1998年,戴伟(Wei Dai)的b-money首次引入了通过解决计算难题和去中心化共识创造货币的思想,但是该建议并未给出如何实现去中心化共识的具体方法。2005年,芬尼(Hal Finney)引入了“可重复使用的工作量证明机制”(reusable proofs of work)概念,它同时使用b-money的思想和Adam Back提出的计算困难的哈希现金(Hashcash)难题来创造密码学货币。但是,这种概念再次迷失于理想化,因为它依赖于可信任的计算作为后端。 - -因为货币是一个先申请应用,交易的顺序至关重要,所以去中心化的货币需要找到实现去中心化共识的方法。比特币以前的所有电子货币协议所遇到的主要障碍是,尽管对如何创建安全的拜占庭问题容错(Byzantine-fault-tolerant)多方共识系统的研究已经历时多年,但是上述协议只解决了问题的一半。这些协议假设系统的所有参与者是已知的,并产生如“如果有N方参与到系统中,那么系统可以容忍N/4的恶意参与者”这样形式的安全边界。然而这个假设的问题在于,在匿名的情况下,系统设置的安全边界容易遭受女巫攻击,因为一个攻击者可以在一台服务器或者僵尸网络上创建数以千计的节点,从而单方面确保拥有多数份额。 - -中本聪的创新是引入这样一个理念:将一个非常简单的基于节点的去中心化共识协议与工作量证明机制结合在一起。节点通过工作量证明机制获得参与到系统的权利,每十分钟将交易打包到“区块”中,从而创建出不断增长的区块链。拥有大量算力的节点有更大的影响力,但获得比整个网络更多的算力比创建一百万个节点困难得多。尽管比特币区块链模型非常简陋,但是实践证明它已经足够好用了,在未来五年,它将成为全世界两百个以上的货币和协议的基石。 - -### 作为状态转换系统的比特币 - -![](https://camo.githubusercontent.com/e7a1fc59abdd42654fa8c54c0f847eb2c8fda72e/687474703a2f2f766974616c696b2e63612f66696c65732f73746174657472616e736974696f6e2e706e673f32) - -从技术角度讲,比特币账本可以被认为是一个状态转换系统,该系统包括所有现存的比特币所有权状态和“状态转换函数”。状态转换函数以当前状态和交易为输入,输出新的状态。例如,在标准的银行系统中,状态就是一个资产负债表,一个从A账户向B账户转账X美元的请求是一笔交易,状态转换函数将从A账户中减去X美元,向B账户增加X美元。如果A账户的余额小于X美元,状态转换函数就会返回错误提示。所以我们可以如下定义状态转换函数: - - APPLY(S,TX) ­> S' or ERROR - -在上面提到的银行系统中,状态转换函数如下: - - APPLY({ Alice: $50, Bob: $50 },"send $20 from Alice to Bob") = { Alice: $30,Bob: $70 } - -但是: - - APPLY({ Alice: $50, Bob: $50 },"send $70 from Alice to Bob") = ERROR - -比特币系统的“状态”是所有已经被挖出的、没有花费的比特币(技术上称为“未花费的交易输出,unspent transaction outputs 或UTXO”)的集合。每个UTXO都有一个面值和所有者(由20个字节的本质上是密码学公钥的地址所定义[1])。一笔交易包括一个或多个输入和一个或多个输出。每个输入包含一个对现有UTXO的引用和由与所有者地址相对应的私钥创建的密码学签名。每个输出包含一个新的加入到状态中的UTXO。 - -在比特币系统中,状态转换函数`APPLY(S,TX)->S’`大体上可以如下定义: - -1. 交易的每个输入: - * 如果引用的UTXO不存在于现在的状态中(`S`),返回错误提示 - * 如果签名与UTXO所有者的签名不一致,返回错误提示 -2. 如果所有的UTXO输入面值总额小于所有的UTXO输出面值总额,返回错误提示 -3. 返回新状态`S’`,新状态`S`中移除了所有的输入UTXO,增加了所有的输出UTXO。 - -第一步的第一部分防止交易的发送者花费不存在的比特币,第二部分防止交易的发送者花费其他人的比特币。第二步确保价值守恒。比特币的支付协议如下。假设Alice想给Bob发送11.7BTC。事实上,Alice不可能正好有11.7BTC。假设,她能得到的最小数额比特币的方式是:6+4+2=12。所以,她可以创建一笔有3个输入,2个输出的交易。第一个输出的面值是11.7BTC,所有者是Bob(Bob的比特币地址),第二个输出的面值是0.3BTC,所有者是Alice自己,也就是找零。 - -### 挖矿 - -![](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/block.png) - -如果我们拥有可信任的中心化服务机构,状态转换系统可以很容易地实现,可以简单地将上述功能准确编码。然而,我们想把比特币系统建成为去中心化的货币系统,为了确保每个人都同意交易的顺序,我们需要将状态转换系统与一个共识系统结合起来。比特币的去中心化共识进程要求网络中的节点不断尝试将交易打包成“区块”。网络被设计为大约每十分钟产生一个区块,每个区块包含一个时间戳、一个随机数、一个对上一个区块的引用(即哈希)和上一区块生成以来发生的所有交易列表。这样随着时间流逝就创建出了一个持续增长的区块链,它不断地更新,从而能够代表比特币账本的最新状态。 - -依照这个范式,检查一个区块是否有效的算法如下: - -1. 检查区块引用的上一个区块是否存在且有效。 -2. 检查区块的时间戳是否晚于以前的区块的时间戳,而且早于未来2小时[2]。 -3. 检查区块的工作量证明是否有效。 -4. 将上一个区块的最终状态赋于`S[0]`。 -5. 假设TX是区块的交易列表,包含n笔交易。对于属于0……n-1的所有i,进行状态转换`S[i+1] = APPLY(S[i],TX[i])`。如果任何一笔交易i在状态转换中出错,退出程序,返回错误。 -6. 返回正确,状态`S[n]`是这一区块的最终状态。 - -本质上,区块中的每笔交易必须提供一个正确的状态转换,要注意的是,“状态”并不是编码到区块的。它纯粹只是被校验节点记住的抽象概念,对于任意区块都可以从创世状态开始,按顺序加上每一个区块的每一笔交易,(妥妥地)计算出当前的状态。另外,需要注意矿工将交易收录进区块的顺序。如果一个区块中有A、B两笔交易,B花费的是A创建的UTXO,如果A在B以前,这个区块是有效的,否则,这个区块是无效的。 - -区块验证算法的有趣部分是“工作量证明”概念:对每个区块进行SHA256哈希处理,将得到的哈希视为长度为256比特的数值,该数值必须小于不断动态调整的目标数值,本书写作时目标数值大约是2^190。工作量证明的目的是使区块的创建变得困难,从而阻止女巫攻击者恶意重新生成区块链。因为SHA256是完全不可预测的伪随机函数,创建有效区块的唯一方法就是简单地不断试错,不断地增加随机数的数值,查看新的哈希数值是否小于目标数值。如果当前的目标数值是2^192,就意味着平均需要尝试2^64次才能生成有效的区块。一般而言,比特币网络每隔2016个区块重新设定目标数值,保证平均每十分钟生成一个区块。为了对矿工的计算工作进行奖励,每一个成功生成区块的矿工有权在区块中包含一笔凭空发给他们自己25BTC的交易。另外,如果交易的输入大于输出,差额部分就作为“交易费用”付给矿工。顺便提一下,对矿工的奖励是比特币发行的唯一机制,创世状态中并没有比特币。 - -为了更好地理解挖矿的目的,让我们分析比特币网络出现恶意攻击者时会发生什么。因为比特币的密码学基础是非常安全的,所以攻击者会选择攻击没有被密码学直接保护的部分:交易顺序。攻击者的策略非常简单: - -1. 向卖家发送100BTC购买商品(尤其是无需邮寄的电子商品)。 -2. 等待直至商品发出。 -3. 创建另一笔交易,将相同的100BTC发送给自己的账户。 -4. 使比特币网络相信发送给自己账户的交易是最先发出的。 - -一旦步骤(1)发生,几分钟后矿工将把这笔交易打包到区块,假设是第270000个区块。大约一个小时以后,在此区块后面将会有五个区块,每个区块间接地指向这笔交易,从而确认这笔交易。这时卖家收到货款,并向买家发货。因为我们假设这是数字商品,攻击者可以即时收到货。现在,攻击者创建另一笔交易,将相同的100BTC发送到自己的账户。如果攻击者只是向全网广播这一消息,这一笔交易不会被处理。矿工会运行状态转换函数`APPLY(S,TX)`,发现这笔交易将花费已经不在状态中的UTXO。所以,攻击者会对区块链进行分叉,将第269999个区块作为父区块重新生成第270000个区块,在此区块中用新的交易取代旧的交易。因为区块数据是不同的,这要求重新进行工作量证明。另外,因为攻击者生成的新的第270000个区块有不同的哈希,所以原来的第270001到第270005的区块不指向它,因此原有的区块链和攻击者的新区块是完全分离的。在发生区块链分叉时,区块链长的分支被认为是诚实的区块链,合法的的矿工将会沿着原有的第270005区块后挖矿,只有攻击者一人在新的第270000区块后挖矿。攻击者为了使得他的区块链最长,他需要拥有比除了他以外的全网更多的算力来追赶(即51%攻击)。 - -### 默克尔树 - -![比特币中的简化支付确认](https://raw.githubusercontent.com/ethereum/www/master-postsale/src/extras/gh_wiki/spv_bitcoin.png) - -左:仅提供默克尔树(Merkle tree)上的少量节点已经足够给出分支的合法证明。 -右:任何对于默克尔树的任何部分进行改变的尝试都会最终导致链上某处的不一致。 - -比特币系统的一个重要的可扩展特性是:它的区块存储在多层次的数据结构中。一个区块的哈希实际上只是区块头的哈希,区块头是包含时间戳、随机数、上个区块哈希和存储了所有的区块交易的默克尔树的根哈希的长度大约为200字节的一段数据。 - -默克尔树是一种二叉树,由一组叶节点、一组中间节点和一个根节点构成。最下面的大量的叶节点包含基础数据,每个中间节点是它的两个子节点的哈希,根节点也是由它的两个子节点的哈希,代表了默克尔树的顶部。默克尔树的目的是允许区块的数据可以零散地传送:节点可以从一个源下载区块头,从另外的源下载与其有关的树的其它部分,而依然能够确认所有的数据都是正确的。之所以如此是因为哈希向上的扩散:如果一个恶意用户尝试在树的下部加入一个伪造的交易,所引起的改动将导致树的上层节点的改动,以及更上层节点的改动,最终导致根节点的改动以及区块哈希的改动,这样协议就会将其记录为一个完全不同的区块(几乎可以肯定是带着不正确的工作量证明的)。 - -默克尔树协议对比特币的长期持续性可以说是至关重要的。在2014年4月,比特币网络中的一个全节点-存储和处理所有区块的全部数据的节点-需要占用15GB的内存空间,而且还以每个月超过1GB的速度增长。目前,这一存储空间对台式计算机来说尚可接受,但是手机已经负载不了如此巨大的数据了。未来只有商业机构和爱好者才会充当完整节点。简化支付确认(SPV)协议允许另一种节点存在,这样的节点被成为“轻节点”,它下载区块头,使用区块头确认工作量证明,然后只下载与其交易相关的默克尔树“分支”。这使得轻节点只要下载整个区块链的一小部分就可以安全地确定任何一笔比特币交易的状态和账户的当前余额。 - -### 其它的区块链应用 - -将区块链的思想应用到其它领域的想法早就出现了。在2005年,尼克萨博提出了“用所有权为财产冠名”的概念,文中描述了复制数据库技术的发展如何使基于区块链的系统可以应用于登记土地所有权,创建包括例如房产权、违法侵占和乔治亚州土地税等概念的详细框架。然而,不幸的是在那时还没有实用的复制数据库系统,所以这个协议被没有被付诸实践。不过,自2009年比特币系统的去中心化共识开发成功以来,许多区块链的其它应用开始快速出现。 - -* **域名币(namecoin)**- 创建于2010年,被称为去中心化的名称注册数据库。像Tor、Bitcoin和BitMessage这样的去中心化协议,需要一些确认账户的方法,这样其他人才能够与用户进行交互。但是,在所有的现存的解决方案中仅有的可用的身份标识是象`1LW79wp5ZBqaHW1jL5TciBCrhQYtHagUWy`这样的伪随机哈希。理想的情况下,人们希望拥有一个带有象“george”这样的名称的账户。然而,问题是如果有人可以创建“george”账户,那么其他人同样也可以创建“george”账户来假扮。唯一的解决方法是先申请原则(first-to-file),只有第一个注册者可以成功注册,第二个不能再次注册同一个账户。这一问题就可以利用比特币的共识协议。域名币是利用区块链实现名称注册系统的最早的、最成功的系统。 -* **彩色币(Colored coins)**- 彩色币的目的是为人们在比特币区块链上创建自己的数字货币,或者,在更重要的一般意义上的货币 – 数字令牌提供服务。依照彩色币协议,人们可以通过为某一特别的比特币UTXO指定颜色,发行新的货币。该协议递归地将其它UTXO定义为与交易输入UTXO相同的颜色。这就允许用户保持只包含某一特定颜色的UTXO,发送这些UTXO就像发送普通的比特币一样,通过回溯全部的区块链判断收到的UTXO颜色。 -* **元币(Metacoins)**- 元币的理念是在比特币区块链上创建新的协议,利用比特币的交易保存元币的交易,但是采用了不同的状态转换函数APPLY’。因为元币协议不能阻止比特币区块链上的无效的元币交易,所以增加一个规则如果APPLY'(S,TX)返回错误,这一协议将默认APPLY'(S,TX) = S。这为创建任意的、先进的不能在比特币系统中实现的密码学货币协议提供了一个简单的解决方法,而且开发成本非常低,因为挖矿和网络的问题已经由比特币协议处理好了。 - -因此,一般而言,建立共识协议有两种方法:建立一个独立的网络和在比特币网络上建立协议。虽然像域名币这样的应用使用第一种方法已经获得了成功,但是该方法的实施非常困难,因为每一个应用需要创建独立的区块链和建立、测试所有状态转换和网络代码。另外,我们预测去中心化共识技术的应用将会服从幂律分布,大多数的应用太小不足以保证自由区块链的安全,我们还注意到大量的去中心化应用,尤其是去中心化自治组织,需要进行应用之间的交互。 - -另一方面,基于比特币的方法存在缺点,它没有继承比特币可以进行简化确认支付(SPV) 的特性。比特币可以实现简化确认支付,因为比特币可以将区块链深度作为有效性确认代理。在某一点上,一旦一笔交易的祖先们距离现在足够远时,就可以认为它们是合法状态的一部分。与之相反,基于比特币区块链的元币协议不能强迫区块链不包括不符合元币协议的交易。因此,安全的元币协议的简化支付确认需要后向扫描所有的区块,直到区块链的初始点,以确认某一交易是否有效。目前,所有基于比特币的元币协议的“轻”实施都依赖可信任的服务器提供数据,这对主要目的之一是消除信任需要的密码学货币而言,只是一个相当次优的结果。 - -### 脚本 - -即使不对比特币协议进行扩展,它也能在一定程度上实现”智能合约”。比特币的UTXO可以被不只被一个公钥拥有,也可以被用基于堆栈的编程语言所编写的更加复杂的脚本所拥有。在这一模式下,花费这样的UTXO,必须提供满足脚本的数据。事实上,基本的公钥所有权机制也是通过脚本实现的:脚本将椭圆曲线签名作为输入,验证交易和拥有这一UTXO的地址,如果验证成功,返回1,否则返回0。更加复杂的脚本用于其它不同的应用情况。例如,人们可以创建要求集齐三把私钥中的两把才能进行交易确认的脚本(多重签名),对公司账户、储蓄账户和某些商业代理来说,这种脚本是非常有用的。脚本也能用来对解决计算问题的用户发送奖励。人们甚至可以创建这样的脚本“如果你能够提供你已经发送一定数额的的狗币给我的简化确认支付证明,这一比特币UTXO就是你的了”,本质上,比特币系统允许不同的密码学货币进行去中心化的兑换。 - -然而,比特币系统的脚本语言存在一些严重的限制: - -* **缺少图灵完备性** – 这就是说,尽管比特币脚本语言可以支持多种计算,但是它不能支持所有的计算。最主要的缺失是循环语句。不支持循环语句的目的是避免交易确认时出现无限循环。理论上,对于脚本程序员来说,这是可以克服的障碍,因为任何循环都可以用多次重复if 语句的方式来模拟,但是这样做会导致脚本空间利用上的低效率,例如,实施一个替代的椭圆曲线签名算法可能将需要256次重复的乘法,而每次都需要单独编码。 -* **价值盲(Value-blindness)**。UTXO脚本不能为账户的取款额度提供精细的的控制。例如,预言机合约(oracle contract)的一个强大应用是对冲合约,A和B各自向对冲合约中发送价值1000美元的比特币,30天以后,脚本向A发送价值1000美元的比特币,向B发送剩余的比特币。虽然实现对冲合约需要一个预言机(oracle)决定一比特币值多少美元,但是与现在完全中心化的解决方案相比,这一机制已经在减少信任和基础设施方面有了巨大的进步。然而,因为UTXO是不可分割的,为实现此合约,唯一的方法是非常低效地采用许多有不同面值的UTXO(例如对应于最大为30的每个k,有一个2^k的UTXO)并使预言机挑出正确的UTXO发送给A和B。 -* **缺少状态** – UTXO只能是已花费或者未花费状态,这就没有给需要任何其它内部状态的多阶段合约或者脚本留出生存空间。这使得实现多阶段期权合约、去中心化的交换要约或者两阶段加密承诺协议(对确保计算奖励非常必要)非常困难。这也意味着UTXO只能用于建立简单的、一次性的合约,而不是例如去中心化组织这样的有着更加复杂的状态的合约,使得元协议难以实现。二元状态与价值盲结合在一起意味着另一个重要的应用-取款限额-是不可能实现的。 -* **区块链盲(Blockchain-blindness)**- UTXO看不到区块链的数据,例如随机数和上一个区块的哈希。这一缺陷剥夺了脚本语言所拥有的基于随机性的潜在价值,严重地限制了博彩等其它领域应用。 - -我们已经考察了在密码学货币上建立高级应用的三种方法:建立一个新的区块链,在比特币区块链上使用脚本,在比特币区块链上建立元币协议。建立新区块链的方法可以自由地实现任意的特性,成本是开发时间和培育努力。使用脚本的方法非常容易实现和标准化,但是它的能力有限。元币协议尽管非常容易实现,但是存在扩展性差的缺陷。在以太坊系统中,我们的目的是建立一个能够同时具有这三种模式的所有优势的通用框架。 - -## 以太坊 - -以太坊的目的是基于脚本、竞争币和链上元协议(on-chain meta-protocol)概念进行整合和提高,使得开发者能够创建任意的基于共识的、可扩展的、标准化的、特性完备的、易于开发的和协同的应用。以太坊通过建立终极的抽象的基础层-内置有图灵完备编程语言的区块链-使得任何人都能够创建合约和去中心化应用并在其中设立他们自由定义的所有权规则、交易方式和状态转换函数。域名币的主体框架只需要两行代码就可以实现,诸如货币和信誉系统等其它协议只需要不到二十行代码就可以实现。智能合约-包含价值而且只有满足某些条件才能打开的加密箱子-也能在我们的平台上创建,并且因为图灵完备性、价值知晓(value-awareness)、区块链知晓(blockchain-awareness)和多状态所增加的力量而比比特币脚本所能提供的智能合约强大得多。 - -### 以太坊账户 - -在以太坊系统中,状态是由被称为“账户”(每个账户由一个20字节的地址)的对象和在两个账户之间转移价值和信息的状态转换构成的。以太坊的账户包含四个部分: - -* 随机数,用于确定每笔交易只能被处理一次的计数器 -* 账户目前的以太币余额 -* 账户的合约代码,如果有的话 -* 账户的存储(默认为空) - -以太币(Ether)是以太坊内部的主要加密燃料,用于支付交易费用。一般而言,以太坊有两种类型的账户:外部所有的账户(由私钥控制的)和合约账户(由合约代码控制)。外部所有的账户没有代码,人们可以通过创建和签名一笔交易从一个外部账户发送消息。每当合约账户收到一条消息,合约内部的代码就会被激活,允许它对内部存储进行读取和写入,和发送其它消息或者创建合约。 - -### 消息和交易 - -以太坊的消息在某种程度上类似于比特币的交易,但是两者之间存在三点重要的不同。第一,以太坊的消息可以由外部实体或者合约创建,然而比特币的交易只能从外部创建。第二,以太坊消息可以选择包含数据。第三,如果以太坊消息的接受者是合约账户,可以选择进行回应,这意味着以太坊消息也包含函数概念。 - -以太坊中“交易”是指存储从外部账户发出的消息的签名数据包。交易包含消息的接收者、用于确认发送者的签名、以太币账户余额、要发送的数据和两个被称为STARTGAS和GASPRICE的数值。为了防止代码的指数型爆炸和无限循环,每笔交易需要对执行代码所引发的计算步骤-包括初始消息和所有执行中引发的消息-做出限制。STARTGAS就是限制,GASPRICE是每一计算步骤需要支付矿工的费用。如果执行交易的过程中,“用完了瓦斯”,所有的状态改变恢复原状态,但是已经支付的交易费用不可收回了。如果执行交易中止时还剩余瓦斯,那么这些瓦斯将退还给发送者。创建合约有单独的交易类型和相应的消息类型;合约的地址是基于账号随机数和交易数据的哈希计算出来的。 - -消息机制的一个重要后果是以太坊的“头等公民”财产-合约与外部账户拥有同样权利,包括发送消息和创建其它合约的权利。这使得合约可以同时充当多个不同的角色,例如,用户可以使去中心化组织(一个合约)的一个成员成为一个中介账户(另一个合约),为一个偏执的使用定制的基于量子证明的兰波特签名(第三个合约)的个人和一个自身使用由五个私钥保证安全的账户(第四个合约)的共同签名实体提供居间服务。以太坊平台的强大之处在于去中心化的组织和代理合约不需要关心合约的每一参与方是什么类型的账户。 - -### 以太坊状态转换函数 - -![以太坊交易.png](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/ethertransition.png) - -以太坊的状态转换函数:`APPLY(S,TX) -> S'`,可以定义如下: - -1. 检查交易的格式是否正确(即有正确数值)、签名是否有效和随机数是否与发送者账户的随机数匹配。如否,返回错误。 -2. 计算交易费用:`fee=STARTGAS * GASPRICE`,并从签名中确定发送者的地址。从发送者的账户中减去交易费用和增加发送者的随机数。如果账户余额不足,返回错误。 -3. 设定初值`GAS = STARTGAS`,并根据交易中的字节数减去一定量的瓦斯值。 -4. 从发送者的账户转移价值到接收者账户。如果接收账户还不存在,创建此账户。如果接收账户是一个合约,运行合约的代码,直到代码运行结束或者瓦斯用完。 -5. 如果因为发送者账户没有足够的钱或者代码执行耗尽瓦斯导致价值转移失败,恢复原来的状态,但是还需要支付交易费用,交易费用加至矿工账户。 -6. 否则,将所有剩余的瓦斯归还给发送者,消耗掉的瓦斯作为交易费用发送给矿工。 -例如,假设合约的代码如下: - -```python -if !self.storage[calldataload(0)]: - self.storage[calldataload(0)] = calldataload(32) -``` - -需要注意的是,在现实中合约代码是用底层以太坊虚拟机(EVM)代码写成的。上面的合约是用我们的高级语言Serpent语言写成的,它可以被编译成EVM代码。假设合约存储器开始时是空的,一个值为10以太,瓦斯为2000,瓦斯价格为0.001以太并且64字节数据,第一个三十二字节的块代表号码2和第二个代表词`CHARLIE`。的交易发送后,状态转换函数的处理过程如下: - -1. 检查交易是否有效、格式是否正确。 -2. 检查交易发送者至少有2000*0.001=2个以太币。如果有,从发送者账户中减去2个以太币。 -3. 初始设定gas=2000,假设交易长为170字节,每字节的费用是5,减去850,所以还剩1150。 -4. 从发送者账户减去10个以太币,为合约账户增加10个以太币。 -5. 运行代码。在这个合约中,运行代码很简单:它检查合约存储器索引为2处是否已使用,注意到它未被使用,然后将其值置为CHARLIE。假设这消耗了187单位的瓦斯,于是剩余的瓦斯为1150 - 187 = 963。 -6. 向发送者的账户增加963*0.001=0.963个以太币,返回最终状态。 -如果没有合约接收交易,那么所有的交易费用就等于GASPRICE乘以交易的字节长度,交易的数据就与交易费用无关了。另外,需要注意的是,合约发起的消息可以对它们产生的计算分配瓦斯限额,如果子计算的瓦斯用完了,它只恢复到消息发出时的状态。因此,就像交易一样,合约也可以通过对它产生的子计算设置严格的限制,保护它们的计算资源。 - -### 代码执行 - -以太坊合约的代码是使用低级的基于堆栈的字节码的语言写成的,被称为“以太坊虚拟机代码”或者“EVM代码”。代码由一系列字节构成,每一个字节代表一种操作。一般而言,代码执行是无限循环,程序计数器每增加一(初始值为零)就执行一次操作,直到代码执行完毕或者遇到错误,`STOP`或者`RETURN`指令。操作可以访问三种存储数据的空间: - -* **堆栈**,一种后进先出的数据存储,32字节的数值可以入栈,出栈。 -* **内存**,可无限扩展的字节队列。 -* **合约的长期存储**,一个秘钥/数值的存储,其中秘钥和数值都是32字节大小,与计算结束即重置的堆栈和内存不同,存储内容将长期保持。 - -代码可以象访问区块头数据一样访问数值,发送者和接受到的消息中的数据,代码还可以返回数据的字节队列作为输出。 - -EVM代码的正式执行模型令人惊讶地简单。当以太坊虚拟机运行时,它的完整的计算状态可以由元组`(block_state, transaction, message, code, memory, stack, pc, gas)`来定义,这里`block_state`是包含所有账户余额和存储的全局状态。每轮执行时,通过调出代码的第`pc`(程序计数器)个字节,当前指令被找到,每个指令都有定义自己如何影响元组。例如,`ADD`将两个元素出栈并将它们的和入栈,将`gas`(瓦斯)减一并将`pc`加一,`SSTORE`将顶部的两个元素出栈并将第二个元素插入到由第一个元素定义的合约存储位置,同样减少最多200的gas值并将`pc`加一,虽然有许多方法通过即时编译去优化以太坊,但以太坊的基础性的实施可以用几百行代码实现。 - -### 区块链和挖矿 - -虽然有一些不同,但以太坊的区块链在很多方面类似于比特币区块链。它们的区块链架构的不同在于,以太坊区块不仅包含交易记录和最近的状态,还包含区块序号和难度值。以太坊中的区块确认算法如下: - -1. 检查区块引用的上一个区块是否存在和有效。 -2. 检查区块的时间戳是否比引用的上一个区块大,而且小于15分钟。 -3. 检查区块序号、难度值、 交易根,叔根和瓦斯限额(许多以太坊特有的底层概念)是否有效。 -4. 检查区块的工作量证明是否有效。 -5. 将`S[0]`赋值为上一个区块的`STATE_ROOT`。 -6. 将`TX`赋值为区块的交易列表,一共有`n`笔交易。对于属于`0……n-1`的`i`,进行状态转换`S[i+1] = APPLY(S[i],TX[i])`。如果任何一个转换发生错误,或者程序执行到此处所花费的瓦斯(gas)超过了`GASLIMIT`,返回错误。 -7. 用`S[n]`给`S_FINAL`赋值, 向矿工支付区块奖励。 -8. 检查`S-FINAL`是否与`STATE_ROOT`相同。如果相同,区块是有效的。否则,区块是无效的。 - -这一确认方法乍看起来似乎效率很低,因为它需要存储每个区块的所有状态,但是事实上以太坊的确认效率可以与比特币相提并论。原因是状态存储在树结构中(tree structure),每增加一个区块只需要改变树结构的一小部分。因此,一般而言,两个相邻的区块的树结构的大部分应该是相同的,因此存储一次数据,可以利用指针(即子树哈希)引用两次。一种被称为“帕特里夏树”(“Patricia Tree”)的树结构可以实现这一点,其中包括了对默克尔树概念的修改,不仅允许改变节点,而且还可以插入和删除节点。另外,因为所有的状态信息是最后一个区块的一部分,所以没有必要存储全部的区块历史-这一方法如果能够可以应用到比特币系统中,经计算可以对存储空间有10-20倍的节省。 - -## 应用 - -一般来讲,以太坊之上有三种应用。第一类是金融应用,为用户提供更强大的用他们的钱管理和参与合约的方法。包括子货币,金融衍生品,对冲合约,储蓄钱包,遗嘱,甚至一些种类的全面的雇佣合约。第二类是半金融应用,这里有钱的存在但也有很重的非金钱的方面,一个完美的例子是为解决计算问题而设的自我强制悬赏。最后,还有在线投票和去中心化治理这样的完全的非金融应用。 - -### 令牌系统 - -链上令牌系统有很多应用,从代表如美元或黄金等资产的子货币到公司股票,单独的令牌代表智能资产,安全的不可伪造的优惠券,甚至与传统价值完全没有联系的用来进行积分奖励的令牌系统。在以太坊中实施令牌系统容易得让人吃惊。关键的一点是理解,所有的货币或者令牌系统,从根本上来说是一个带有如下操作的数据库:从A中减去X单位并把X单位加到B上,前提条件是(1)A在交易之前有至少X单位以及(2)交易被A批准。实施一个令牌系统就是把这样一个逻辑实施到一个合约中去。 - -用Serpent语言实施一个令牌系统的基本代码如下: - -```python -def send(to, value): - if self.storage[from] >= value: - self.storage[from] = self.storage[from] value - self.storage[to] = self.storage[to] + value -``` - -这从本质上来说是本文将要进一步描述的“银行系统”状态转变功能的一个最小化实施。需要增加一些额外的代码以提供在初始和其它一些边缘情况下分发货币的功能,理想情况下会增加一个函数让其它合约来查询一个地址的余额。就足够了。理论上,基于以太坊的充当子货币的令牌系统可能包括一个基于比特币的链上元币所缺乏的重要功能:直接用这种货币支付交易费的能力。实现这种能力的方法是在合约里维护一个以太币账户以用来为发送者支付交易费,通过收集被用来充当交易费用的内部货币并把它们在一个不断运行的拍卖中拍卖掉,合约不断为该以太币账户注资。这样用户需要用以太币“激活”他们的账户,但一旦账户中有以太币它将会被重复使用因为每次合约都会为其充值。 - -### 金融衍生品和价值稳定的货币 - -金融衍生品是“智能合约”的最普遍的应用,也是最易于用代码实现的之一。实现金融合约的主要挑战是它们中的大部分需要参照一个外部的价格发布器;例如,一个需求非常大的应用是一个用来对冲以太币(或其它密码学货币)相对美元价格波动的智能合约,但该合约需要知道以太币相对美元的价格。最简单地方法是通过由某特定机构(例如纳斯达克)维护的“数据提供“合约进行,该合约的设计使得该机构能够根据需要更新合约,并提供一个接口使得其它合约能够通过发送一个消息给该合约以获取包含价格信息的回复。 - -当这些关键要素都齐备,对冲合约看起来会是下面的样子: - -1. 等待A输入1000以太币。. -2. 等待B 输入1000以太币。 -3. 通过查询数据提供合约,将1000以太币的美元价值,例如,x美元,记录至存储器。 -4. 30天后,允许A或B“重新激活“合约以发送价值x美元的以太币(重新查询数据提供合约以获取新价格并计算)给A并将剩余的以太币发送给B。 -这样的合约在密码学商务中有非同寻常的潜力。密码学货币经常被诟病的一个问题就是其价格的波动性;虽然大量的用户和商家可能需要密码学资产所带来的安全和便利,可他们不太会乐意面对一天中资产跌去23%价值的情形。直到现在,最为常见的推荐方案是发行者背书资产;思想是发行者创建一种子货币,对此种子货币他们有权发行和赎回,给予(线下)提供给他们一个单位特定相关资产(例如黄金,美元)的人一个单位子货币。发行者承诺当任何人送还一个单位密码学资产时。发还一个单位的相关资产。这种机制能够使任何非密码学资产被“升级“为密码学资产,如果发行者值得信任的话。 -然而实践中发行者并非总是值得信任的,并且一些情况下银行体系太脆弱,或者不够诚实守信从而使这样的服务无法存在。金融衍生品提供了一种替代方案。这里将不再有提供储备以支撑一种资产的单独的发行者,取而代之的是一个由赌一种密码学资产的价格会上升的投机者构成的去中心化市场。与发行者不同,投机者一方没有讨价还价的权利,因为对冲合约把他们的储备冻结在了契约中。注意这种方法并非是完全去中心化的,因为依然需要一个可信任的提供价格信息的数据源,尽管依然有争议这依然是在降低基础设施需求(与发行者不同,一个价格发布器不需要牌照并且似乎可归为自由言论一类)和降低潜在欺诈风险方面的一个巨大的进步。 - -### 身份和信誉系统 - -最早的替代币,域名币,尝试使用一个类比特币块链来提供一个名称注册系统,在那里用户可以将他们的名称和其它数据一起在一个公共数据库注册。最常用的应用案例把象“bitcoin.org“(或者再域名币中,”bitcoin.bit“)一样的域名与一个IP地址对应的域名系统。其它的应用案例包括电子邮件验证系统和潜在的更先进的信誉系统。这里是以太坊中提供与域名币类似的的名称注册系统的基础合约: - -```python -def register(name, value): - if !self.storage[name]: - self.storage[name] = value -``` - -合约非常简单;就是一个以太坊网络中的可以被添加但不能被修改或移除的数据库。任何人都可以把一个名称注册为一个值并永远不变。一个更复杂的名称注册合约将包含允许其他合约查询的“功能条款“,以及一个让一个名称的”拥有者“(即第一个注册者)修改数据或者转让所有权的机制。甚至可以在其上添加信誉和信任网络功能。 - -### 去中心化存储 - -在过去的几年里出现了一些大众化的在线文件存储初创公司,最突出的是Dropbox,它寻求允许用户上传他们的硬盘备份,提供备份存储服务并允许用户访问从而按月向用户收取费用。然而,在这一点上这个文件存储市场有时相对低效;对现存服务的粗略观察表明,特别地在“神秘谷“20-200GB这一既没有免费空间也没有企业级用户折扣的水平上,主流文件存储成本每月的价格意味着支付在一个月里支付整个硬盘的成本。以太坊合约允许去中心化存储生态的开发,这样用户通过将他们自己的硬盘或未用的网络空间租出去以获得少量收益,从而降低了文件存储的成本。 - -这样的设施的基础性构件就是我们所谓的“去中心化Dropbox合约“。这个合约工作原理如下。首先,某人将需要上传的数据分成块,对每一块数据加密以保护隐私,并且以此构建一个默克尔树。然后创建一个含以下规则的合约,每N个块,合约将从默克尔树中抽取一个随机索引(使用能够被合约代码访问的上一个块的哈希来提供随机性), 然后给第一个实体X以太以支撑一个带有类似简化验证支付(SPV)的在树中特定索引处的块的所有权证明。当一个用户想重新下载他的文件,他可以使用微支付通道协议(例如每32k字节支付1萨博)恢复文件;从费用上讲最高效的方法是支付者不到最后不发布交易,而是用一个略微更合算的带有同样随机数的交易在每32k字节之后来代替原交易。 - -这个协议的一个重要特征是,虽然看起来象是一个人信任许多不准备丢失文件的随机节点,但是他可以通过秘密分享把文件分成许多小块,然后通过监视合同得知每个小块都还被某个节点的保存着。如果一个合约依然在付款,那么就提供了某个人依然在保存文件的证据。 - -### 去中心化自治组织 - -通常意义上“去中心化自治组织(DAO, decentralized autonomous organization)”的概念指的是一个拥有一定数量成员或股东的虚拟实体,依靠比如67%多数来决定花钱以及修改代码。成员会集体决定组织如何分配资金。分配资金的方法可能是悬赏,工资或者更有吸引力的机制比如用内部货币奖励工作。这仅仅使用密码学块链技术就从根本上复制了传统公司或者非营利组织的法律意义以实现强制执行。至此许多围绕DAO的讨论都是围绕一个带有接受分红的股东和可交易的股份的“去中心化自治公司(DAC,decentralized autonomous corporation)”的“资本家”模式;作为替代者,一个被描述为“去中心化自治社区(decentralized autonomous community)”的实体将使所有成员都在决策上拥有同等的权利并且在增减成员时要求67%多数同意。每个人都只能拥有一个成员资格这一规则需要被群体强制实施。 - -下面是一个如何用代码实现DO的纲要。最简单地设计就是一段如果三分之二成员同意就可以自我修改的代码。虽然理论上代码是不可更改的,然而通过把代码主干放在一个单独的合约内并且把合约调用的地址指向一个可更改的存储依然可以容易地绕开障碍而使代码变得可修改,在一个这样的DAO合约的简单实现中有三种交易类型,由交易提供的数据区分: - -* `[0,i,K,V]` 注册索引为i 的对存储地址索引为K 至 v 的内容的更改建议。 -* `[0,i]` 注册对建议i 的投票。 -* `[2,i]` 如有足够投票则确认建议i。 - -然后合约对每一项都有具体的条款。它将维护一个所有开放存储的更改记录以及一个谁投票表决的表。还有一个所有成员的表。当任何存储内容的更改获得了三分之二多数同意,一个最终的交易将执行这项更改。一个更加复杂的框架会增加内置的选举功能以实现如发送交易,增减成员,甚至提供委任制民主一类的投票代表(即任何人都可以委托另外一个人来代表自己投票,而且这种委托关系是可以传递的,所以如果A委托了B然后B委托了C那么C将决定A的投票)。这种设计将使DAO作为一个去中心化社区有机地成长, 使人们最终能够把挑选合适人选的任务交给专家,与当前系统不同,随着社区成员不断改变他们的站队假以时日专家会容易地出现和消失。 -一个替代的模式是去中心化公司,那里任何账户可以拥有0到更多的股份,决策需要三分之二多数的股份同意。一个完整的框架将包括资产管理功能-可以提交买卖股份的订单以及接受这种订单的功能(前提是合约里有订单匹配机制)。代表依然以委任制民主的方式存在,产生了“董事会”的概念。 - -更先进的组织治理机制可能会在将来实现;现在一个去中心化组织(DO)可以从去中心化自治组织(DAO)开始描述。DO和DAO的区别是模糊的,一个大致的分割线是治理是否可以通过一个类似政治的过程或者一个“自动”过程实现,一个不错的直觉测试是“无通用语言”标准:如果两个成员不说同样的语言组织还能正常运行吗?显然,一个简单的传统的持股式公司会失败,而象比特币协议这样的却很可能成功,罗宾·汉森的“futarchy”,一个通过预测市场实现组织化治理的机制是一个真正的说明“自治”式治理可能是什么样子的好例子。注意一个人无需假设所有DAO比所有DO优越;自治只是一个在一些特定场景下有很大优势的,但在其它地方未必可行的范式,许多半DAO可能存在。 - -### 进一步的应用 - -1. **储蓄钱包**。 假设Alice想确保她的资金安全,但她担心丢失或者被黑客盗走私钥。她把以太币放到和Bob签订的一个合约里,如下所示,这合同是一个银行: - * Alice单独每天最多可提取1%的资金。 - * Bob单独每天最多可提取1%的资金,但Alice可以用她的私钥创建一个交易取消Bob的提现权限。 - * Alice 和 Bob 一起可以任意提取资金。 -一般来讲,每天1%对Alice足够了,如果Alice想提现更多她可以联系Bob寻求帮助。如果Alice的私钥被盗,她可以立即找到Bob把她的资金转移到一个新合同里。如果她弄丢了她的私钥,Bob可以慢慢地把钱提出。如果Bob表现出了恶意,她可以关掉他的提现权限。 - -2. **作物保险**。一个人可以很容易地以天气情况而不是任何价格指数作为数据输入来创建一个金融衍生品合约。如果一个爱荷华的农民购买了一个基于爱荷华的降雨情况进行反向赔付的金融衍生品,那么如果遇到干旱,该农民将自动地收到赔付资金而如果有足量的降雨他会很开心因为他的作物收成会很好。 - -3. **一个去中心化的数据发布器**。 对于基于差异的金融合约,事实上通过过“谢林点”协议将数据发布器去中心化是可能的。谢林点的工作原理如下:N方为某个指定的数据提供输入值到系统(例如ETH/USD价格),所有的值被排序,每个提供25%到75%之间的值的节点都会获得奖励,每个人都有激励去提供他人将提供的答案,大量玩家可以真正同意的答案明显默认就是正确答案,这构造了一个可以在理论上提供很多数值,包括ETH/USD价格,柏林的温度甚至某个特别困难的计算的结果的去中心化协议。 - -5.**云计算**。EVM技术还可被用来创建一个可验证的计算环境,允许用户邀请他人进行计算然后选择性地要求提供在一定的随机选择的检查点上计算被正确完成的证据。这使得创建一个任何用户都可以用他们的台式机,笔记本电脑或者专用服务器参与的云计算市场成为可能,现场检查和安全保证金可以被用来确保系统是值得信任的(即没有节点可以因欺骗获利)。虽然这样一个系统可能并不适用所有任务;例如,需要高级进程间通信的任务就不易在一个大的节点云上完成。然而一些其它的任务就很容易实现并行;SETI@home, folding@home和基因算法这样的项目就很容易在这样的平台上进行。 - -6.**点对点赌博**。任意数量的点对点赌博协议都可以搬到以太坊的区块链上,例如Frank Stajano和Richard Clayton的Cyberdice。 最简单的赌博协议事实上是这样一个简单的合约,它用来赌下一个区块的哈稀值与猜测值之间的差额, 据此可以创建更复杂的赌博协议,以实现近乎零费用和无欺骗的赌博服务。 - -7.**预测市场**。 不管是有神谕还是有谢林币,预测市场都会很容易实现,带有谢林币的预测市场可能会被证明是第一个主流的作为去中心化组织管理协议的“futarchy”应用。 - -8.链上去中心化市场,以身份和信誉系统为基础。 - -## 杂项和关注 - -### 改进版幽灵协议的实施 - - “幽灵“协议("Greedy Heaviest Observed Subtree" (GHOST) protocol)是由Yonatan Sompolinsky 和 Aviv Zohar在2013年12月引入的创新。幽灵协议提出的动机是当前快速确认的块链因为区块的高作废率而受到低安全性困扰;因为区块需要花一定时间(设为t)扩散至全网,如果矿工A挖出了一个区块然后矿工B碰巧在A的区块扩散至B之前挖出了另外一个区块,矿工B的区块就会作废并且没有对网络安全作出贡献。此外,这里还有中心化问题:如果A是一个拥有全网30%算力的矿池而B拥有10%的算力,A将面临70%的时间都在产生作废区块的风险而B在90%的时间里都在产生作废区块。因此,如果作废率高,A将简单地因为更高的算力份额而更有效率,综合这两个因素,区块产生速度快的块链很可能导致一个矿池拥有实际上能够控制挖矿过程的算力份额。 - -正如Sompolinsky 和 Zohar所描述的,通过在计算哪条链“最长”的时候把废区块也包含进来,幽灵协议解决了降低网络安全性的第一个问题;这就是说,不仅一个区块的父区块和更早的祖先块,祖先块的作废的后代区块(以太坊术语中称之为“叔区块”)也被加进来以计算哪一个区块拥有支持其的最大工作量证明。我们超越了Sompolinsky 和 Zohar所描述的协议以解决第二个问题 – 中心化倾向,以太坊付给以“叔区块”身份为新块确认作出贡献的废区块87.5%的奖励,把它们纳入计算的“侄子区块”将获得奖励的12.5%,不过,交易费用不奖励给叔区块。 -以太坊实施了一个只下探到第五层的简化版本的幽灵协议。其特点是,废区块只能以叔区块的身份被其父母的第二代至第五代后辈区块,而不是更远关系的后辈区块(例如父母区块的第六代后辈区块,或祖父区块的第三代后辈区块)纳入计算。这样做有几个原因。首先,无条件的幽灵协议将给计算给定区块的哪一个叔区块合法带来过多的复杂性。其次,带有以太坊所使用的补偿的无条件的幽灵协议剥夺了矿工在主链而不是一个公开攻击者的链上挖矿的激励。最后,计算表明带有激励的五层幽灵协议即使在出块时间为15s的情况下也实现了了95%以上的效率,而拥有25%算力的矿工从中心化得到的益处小于3%。 - -### 费用 - -因为每个发布的到区块链的交易都占用了下载和验证的成本,需要有一个包括交易费的规范机制来防范滥发交易。比特币使用的默认方法是纯自愿的交易费用,依靠矿工担当守门人并设定动态的最低费用。因为这种方法是“基于市场的”,使得矿工和交易发送者能够按供需来决定价格,所以这种方法在比特币社区被很顺利地接受了。然而,这个逻辑的问题在于,交易处理并非一个市场;虽然根据直觉把交易处理解释成矿工给发送者提供的服务是很有吸引力的,但事实上一个矿工收录的交易是需要网络中每个节点处理的,所以交易处理中最大部分的成本是由第三方而不是决定是否收录交易的矿工承担的。于是,非常有可能发生公地悲剧。 - -然而,当给出一个特殊的不够精确的简化假设时,这个基于市场的机制的漏洞很神奇地消除了自己的影响。论证如下。假设: - -1. 一个交易带来 k 步操作, 提供奖励 kR给任何收录该交易的矿工,这里 R 由交易发布者设定, k 和 R 对于矿工都是事先(大致上)可见的。 -2. 每个节点处理每步操作的成本都是 C (即所有节点的效率一致)。 -3. 有 N 个挖矿节点,每个算力一致(即全网算力的1/N)。 -4. 没有不挖矿的全节点。 - -当预期奖励大于成本时,矿工愿意挖矿。这样,因为矿工有1/N 的机会处理下一个区块,所以预期的收益是 kR/N , 矿工的处理成本简单为 kC. 这样当 kR/N > kC, 即 R > NC时。矿工愿意收录交易。注意 R 是由交易发送者提供的每步费用,是矿工从处理交易中获益的下限。 NC 是全网处理一个操作的成本。所以,矿工仅有动机去收录那些收益大于成本的交易。 -然而,这些假设与实际情况有几点重要的偏离: - -1. 因为额外的验证时间延迟了块的广播因而增加了块成为废块的机会,处理交易的矿工比其它的验证节点付出了更高的成本。 -2. 不挖矿的全节点是存在的。 -3. 实践中算力分布可能最后是极端不平均的。 -4. 以破坏网络为己任的投机者,政敌和疯子确实存在,并且他们能够聪明地设置合同使得他们的成本比其它验证节点低得多。 -上面第1点驱使矿工收录更少的交易,第2点增加了 NC; 因此这两点的影响至少部分互相抵消了. 第3点和第4点是主要问题;作为解决方案我们简单地建立了一个浮动的上限:没有区块能够包含比BLK_LIMIT_FACTOR 倍长期指数移动平均值更多的操作数。具体地: - -`blk.oplimit = floor((blk.parent.oplimit * (EMAFACTOR - 1) + floor(parent.opcount * BLK_LIMIT_FACTOR)) /EMA_FACTOR)` - -BLK_LIMIT_FACTOR 和 EMA_FACTOR 是暂且被设为 65536 和 1.5 的常数,但可能会在更深入的分析后调整。 -回复 - -### 计算和图灵完备 - -需要强调的是以太坊虚拟机是图灵完备的; 这意味着EVM代码可以实现任何可以想象的计算,包括无限循环。EVM代码有两种方式实现循环。首先, JUMP 指令可以让程序跳回至代码前面某处,还有允许如 `while x < 27: x = x * 2 ` 一样的条件语句的JUMPI 指令实现条件跳转。其次,合约可以调用其它合约,有通过递归实现循环的潜力。这很自然地导致了一个问题:恶意用户能够通过迫使矿工和全节点进入无限循环而不得不关机吗? 这问题出现是因为计算机科学中一个叫停机问题的问题:一般意义上没有办法知道,一个给定的程序是否能在有限的时间内结束运行。 - -正如在状态转换章节所述,我们的方案通过为每一个交易设定运行执行的最大计算步数来解决问题,如果超过则计算被恢复原状但依然要支付费用。消息以同样的方式工作。为显示这一方案背后的动机,请考虑下面的例子: - -* 一个攻击者创建了一个运行无限循环的合约,然后发送了一个激活循环的交易给矿工,矿工将处理交易,运行无限循环直到瓦斯耗尽。即使瓦斯耗尽交易半途停止,交易依然正确(回到原处)并且矿工依然从攻击者哪里挣到了每一步计算的费用。 -* 一个攻击者创建一个非常长的无限循环意图迫使矿工长时间内一直计算致使在计算结束前若干区块已经产生于是矿工无法收录交易以赚取费 用。然而,攻击者需要发布一个 STARTGAS 值以限制可执行步数,因而矿工将提前知道计算将耗费过多的步数。 -* 一个攻击者看到一个包含诸如 send(A,self.storage); self.storage = 0格式的合约然后发送带有只够执行第一步的费用的而不够执行第二步的交易(即提现但不减少账户余额)。合约作者无需担心防卫类似攻击,因为如果执行中途停止则所有变更都被回复。 -* 一个金融合约靠提取九个专用数据发布器的中值来工作以最小化风险,一个攻击者接管了其中一个数据提供器,然后把这个按DAO章节所述的可变地址调用机制设计成可更改的数据提供器转为运行一个无限循环,以求尝试逼迫任何从此金融合约索要资金的尝试都会因瓦斯耗尽而中止。然而,该金融合约可以在消息里设置瓦斯限制以防范此类问题。 -图灵完备的替代是图灵不完备,这里 JUMP 和 JUMPI 指令不存在并且在某个给定时间每个合约只允许有一个拷贝存在于调用堆栈内。在这样的系统里,上述的费用系统和围绕我们的方案的效率的不确定性可能都是不需要的,因为执行一个合约的成本将被它的大小决定。此外,图灵不完备甚至不是一个大的限制,在我们内部设想的所有合约例子中,至今只有一个需要循环,而且即使这循环也可以被26个单行代码段的重复所代替。考虑到图灵完备带来的严重的麻烦和有限的益处,为什么不简单地使用一种图灵不完备语言呢?事实上图灵不完备远非一个简洁的解决方案。为什么?请考虑下面的合约: - -```python -C0: call(C1); call(C1); -C1: call(C2); call(C2); -C2: call(C3); call(C3); -... -C49: call(C50); call(C50); -C50: (作一个图灵机的步计算和记录结果在合约的长期存储) -``` - -现在,发送一个这样的交易给A,这样,在51个交易中,我们有了一个需要花费2^50 步计算的合约,矿工可能尝试通过为每一个合约维护一个最高可执行步数并且对于递归调用其它合约的合约计算可能执行步数从而预先检测这样的逻辑炸弹,但是这会使矿工禁止创建其它合约的合约(因为上面26个合约的创建和执行可以很容易地放入一个单独合约内)。另外一个问题点是一个消息的地址字段是一个变量,所以通常来讲可能甚至无法预先知道一个合约将要调用的另外一个合约是哪一个。于是,最终我们有了一个惊人的结论:图灵完备的管理惊人地容易,而在缺乏同样的控制时图灵不完备的管理惊人地困难- 那为什么不让协议图灵完备呢? - -### 货币和发行 - -以太坊网络包含自身的内置货币以太币,以太币扮演双重角色,为各种数字资产交易提供主要的流动性,更重要的是提供了了支付交易费用的一种机制。为便利及避免将来的争议期间(参见当前的mBTC/uBTC/聪的争论),不同面值的名称将被提前设置: - -* 1: 伟 -* 10^12: 萨博 -* 10^15: 芬尼 -* 10^18: 以太 - -这应该被当作是“元”和“分”或者“比特币”和“聪”的概念的扩展版,在不远的将来,我们期望“以太”被用作普通交易,“芬尼”用来进行微交易,“萨博”和“伟”用来进行关于费用和协议实施的讨论。 - -发行模式如下: - -* 通过发售活动,以太币将以每BTC 1337-2000以太的价格发售,一个旨在为以太坊组织筹资并且为开发者支付报酬的机制已经在其它一些密码学货币平台上成功使用。早期购买者会享受较大的折扣,发售所得的BTC将完全用来支付开发者和研究者的工资和悬赏,以及投入密码学货币生态系统的项目。 -* 0.099x (x为发售总量)将被分配给BTC融资或其它的确定性融资成功之前参与开发的早期贡献者,另外一个0.099x将分配给长期研究项目。 -* 自上线时起每年都将有0.26x(x为发售总量)被矿工挖出。 - -### 发行分解 -永久线性增长模型降低了在比特币中出现的财富过于集中的风险,并且给予了活在当下和将来的人公平的机会去获取货币,同时保持了对获取和持有以太币的激励,因为长期来看“货币供应增长率”是趋于零的。我们还推断,随着时间流逝总会发生因为粗心和死亡等原因带来的币的遗失,假设币的遗失是每年货币供应量的一个固定比例,则最终总的流通中的货币供应量会稳定在一个等于年货币发行量除以遗失率的值上(例如,当遗失率为1%时,当供应量达到30x时,每年有0.3x被挖出同时有0.3x丢失,达到一个均衡)。 - -![](http://bitcoin8btc.qiniudn.com/wp-content/uploads/2014/10/table.png) -除了线性的发行方式外,和比特币一样以太币的的供应量增长率长期来看也趋于零。 - -![](http://bitcoin8btc.qiniudn.com/wp-content/uploads/2014/10/supply.png) - -### 挖矿的中心化 - -比特币挖矿算法基本上是让矿工千万次地轻微改动区块头,直到最终某个节点的改动版本的哈希小于目标值(目前是大约2190)。然而,这种挖矿算法容易被两种形式的中心化攻击。第一种,挖矿生态系统被专门设计的因而在比特币挖矿这一特殊任务上效率提高上千倍的ASICs(专用集成电路)和电脑芯片控制。这意味着比特币挖矿不再是高度去中心化的和追求平等主义的,而是需要巨额资本的有效参与。第二种,大部分比特币矿工事实上不再在本地完成区块验证;而是依赖中心化的矿池提供区块头。这个问题可以说很严重:在本文写作时,最大的两个矿池间接地控制了大约全网50%的算力,虽然当一个矿池或联合体尝试51%攻击时矿工可以转换到其它矿池这一事实减轻了问题的严重性。 - -以太坊现在的目的是使用一个基于为每1000个随机数随机产生唯一哈希的函数的挖矿算法,用足够宽的计算域,去除专用硬件的优势。这样的策略当然不会使中心化的收益减少为零,但是也不需要。注意每单个用户使用他们的私人笔记本电脑或台式机就可以几乎免费地完成一定量的挖矿活动,但当到了100%的CPU使用率之后更多地挖矿就会需要他们支付电力和硬件成本。ASIC挖矿公司需要从第一个哈希开始就为电力和硬件支付成本。所以,如果中心化收益能够保持在(E + H) /E 以下,那么即使ASICs被制造出来普通矿工依然有生存空间。另外,我们计划将挖矿算法设计成挖矿需要访问整个区块链,迫使矿工存储完成的区块链或者至少能够验证每笔交易。这去除了对中心化矿池的需要;虽然矿池依然可以扮演平滑收益分配的随机性的角色,但这功能可以被没有中心化控制的P2P矿池完成地同样好。这样即使大部分普通用户依然倾向选择轻客户端,通过增加网络中的全节点数量也有助于抵御中心化。 - -### 扩展性 - -扩展性问题是以太坊常被关注的地方,与比特币一样,以太坊也遭受着每个交易都需要网络中的每个节点处理这一困境的折磨。比特币的当前区块链大小约为20GB,以每小时1MB的速度增长。如果比特币网络处理Visa级的2000tps的交易,它将以每三秒1MB的速度增长(1GB每小时,8TB每年)。以太坊可能也会经历相似的甚至更糟的增长模式,因为在以太坊区块链之上还有很多应用,而不是像比特币只是简单的货币,但以太坊全节点只需存储状态而不是完整的区块链历史这一事实让情况得到了改善。 - -大区块链的问题是中心化风险。如果块链大小增加至比如100TB,可能的场景将是只有非常小数目的大商家会运行全节点,而常规用户使用轻的SPV节点。这会增加对全节点合伙欺诈牟利(例如更改区块奖励,给他们自己BTC)的风险的担忧。轻节点将没有办法立刻检测到这种欺诈。当然,至少可能存在一个诚实的全节点,并且几个小时之后有关诈骗的信息会通过Reddit这样的渠道泄露,但这时已经太晚:任凭普通用户做出怎样的努力去废除已经产生的区块,他们都会遇到与发动一次成功的51%攻击同等规模的巨大的不可行的协调问题。在比特币这里,现在这是一个问题,但Peter Todd建议的一个改动可以缓解这个问题。 - -近期,以太坊会使用两个附加的策略以应对此问题。首先,因为基于区块链的挖矿算法,至少每个矿工会被迫成为一个全节点,这保证了一定数量的全节点。其次,更重要的是,处理完每笔交易后,我们会把一个中间状态树的根包含进区块链。即使区块验证是中心化的,只要有一个诚实的验证节点存在,中心化的问题就可以通过一个验证协议避免。如果一个矿工发布了一个不正确的区块,这区块要么是格式错,要么状态S[n]是错的。因为S[0]是正确的,必然有第一个错误状态S[i]但S[i-1]是正确的,验证节点将提供索引i,一起提供的还有处理APPLY(S[i-1],TX[i]) -> S[i]所需的帕特里夏树节点的子集。这些节点将受命进行这部分计算,看产生的S[i]与先前提供的值是否一致。 - -另外,更复杂的是恶意矿工发布不完整区块进行攻击,造成没有足够的信息去确定区块是否正确。解决方案是质疑-回应协议:验证节点对目标交易索引发起质疑,接受到质疑信息的轻节点会对相应的区块取消信任,直到另外一个矿工或者验证者提供一个帕特里夏节点子集作为正确的证据。 - -## 综述:去中心化应用 - - - -上述合约机制使得任何一个人能够在一个虚拟机上建立通过全网共识来运行命令行应用(从根本上来说是),它能够更改一个全网可访问的状态作为它的“硬盘”。然而,对于多数人来说,用作交易发送机制的命令行接口缺乏足够的用户友好使得去中心化成为有吸引力的替代方案。最后,一个完整的“去中心化应用”应该包括底层的商业逻辑组件【无论是否在以太坊完整实施,使用以太坊和其它系统组合(如一个P2P消息层,其中一个正在计划放入以太坊客户端)或者仅有其它系统的方式】和上层的图形用户接口组件。以太坊客户端被设计成一个网络浏览器,但包括对“eth” Javascript API对象的支持,可被客户端里看到的特定的网页用来与以太坊区块链交互。从“传统”网页的角度看来,这些网页是完全静态的内容,因为区块链和其它去中心化协议将完全代替服务器来处理用户发起的请求。最后,去中心化协议有希望自己利用某种方式使用以太坊来存储网页。 - -## 结论 - - - -以太坊协议最初是作为一个通过高度通用的语言提供如链上契约,提现限制和金融合约,赌博市场等高级功能的升级版密码学货币来构思的。以太坊协议将不直接“支持”任何应用,但图灵完备编程语言的存在意味着理论上任意的合约都可以为任何交易类型和应用创建出来。然而关于以太坊更有趣的是,以太坊协议比单纯的货币走得更远,围绕去中心化存储,去中心化计算和去中心化预测市场以及数十个类似概念建立的协议和去中心化应用,有潜力从根本上提升计算行业的效率,并通过首次添加经济层为其它的P2P协议提供有力支撑,最终,同样会有大批与金钱毫无关系的应用出现。 - -以太坊协议实现的任意状态转换概念提供了一个具有独特潜力的平台;与封闭式的,为诸如数据存储,赌博或金融等单一目的设计的协议不同,以太坊从设计上是开放式的,并且我们相信它极其适合作为基础层服务于在将来的年份里出现的极其大量的金融和非金融协议。 - -## 注解与进阶阅读 - -### 注解 - -1.一个有经验的读者会注意到事实上比特币地址是椭圆曲线公钥的哈希,而非公钥本身,然而事实上从密码学术语角度把公钥哈希称为公钥完全合理。这是因为比特币密码学可以被认为是一个定制的数字签名算法,公钥由椭圆曲线公钥的哈希组成,签名由椭圆曲线签名连接的椭圆曲线公钥组成,而验证算法包括用作为公钥提供的椭圆曲线公钥哈希来检查椭圆曲线公钥,以及之后的用椭圆曲线公钥来验证椭圆曲线签名。 - -2.技术上来说,前11个区块的中值。 - -3.在内部,2和“CHARLIE”都是数字,后一个有巨大的base256编码格式,数字可以从0到2^256-1。 - -### 进阶阅读 - -1. Intrinsic value: https://tinyurl.com/BitcoinMag-IntrinsicValue - -2. Smart property: https://en.bitcoin.it/wiki/Smart_Property - -3. Smart contracts: https://en.bitcoin.it/wiki/Contracts - -4. B-money: http://www.weidai.com/bmoney.txt - -5. Reusable proofs of work: http://www.finney.org/~hal/rpow/ - -6. Secure property titles with owner authority: http://szabo.best.vwh.net/securetitle.html - -7. Bitcoin whitepaper: http://bitcoin.org/bitcoin.pdf - -8. Namecoin: https://namecoin.org/ - -9. Zooko’s triangle: http://en.wikipedia.org/wiki/Zooko’s_triangle - -10. Colored coins whitepaper: https://tinyurl.com/coloredcoin-whitepaper - -11. Mastercoin whitepaper: https://github.com/mastercoin-MSC/spec - -12. Decentralized autonomous corporations, Bitcoin Magazine: https://tinyurl.com/Bootstrapping-DACs - -13. Simplified payment verification:https://en.bitcoin.it/wiki/Scalability#Simplifiedpaymentverification - -14. Merkle trees: http://en.wikipedia.org/wiki/Merkle_tree - -15. Patricia trees: http://en.wikipedia.org/wiki/Patricia_tree - -16. GHOST: http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf - -17. StorJ and Autonomous Agents, Jeff Garzik: https://tinyurl.com/storj-agents - -18. Mike Hearn on Smart Property at Turing Festival: http://www.youtube.com/watch?v=Pu4PAMFPo5Y - -19. Ethereum RLP: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP - -20. Ethereum Merkle Patricia trees: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree - -21. Peter Todd on Merkle sum trees:http://sourceforge.net/p/bitcoin/mailman/message/31709140/ diff --git "a/pages/other-languages/[\344\270\255\346\226\207]-\346\254\212\347\233\212\350\255\211\346\230\216\346\251\237\345\210\266FAQ.md" "b/pages/other-languages/[\344\270\255\346\226\207]-\346\254\212\347\233\212\350\255\211\346\230\216\346\251\237\345\210\266FAQ.md" deleted file mode 100644 index d8fbcacfc..000000000 --- "a/pages/other-languages/[\344\270\255\346\226\207]-\346\254\212\347\233\212\350\255\211\346\230\216\346\251\237\345\210\266FAQ.md" +++ /dev/null @@ -1,239 +0,0 @@ -### 什麼是Proof of Stake(權益證明機制) - -權益證明機制是公有鏈共識演算法的一類,乙太坊接下來的 Casper 演算法是其中之一。它和比特幣、目前的以太坊及許多其他區塊鏈背後的Proof of Work有著相似的作用,但在安全性及能源使用效率上有著顯著的優點。 - -總的來說,權益證明機制演算法大致如下。區塊鏈記錄著一組 **validator** (驗證者),所有持有該區塊鏈數位貨幣的使用者(即以太坊的以太幣)都可藉由一個特殊交易將他們的數位貨幣鎖進一個存庫來成為驗證者。創造一個新的區塊的過程則藉由一個驗證者參與的共識演算法來進行。 - -目前有許多種的共識演算法及許多種獎賞驗證者的方式,因此有許多不同種類的權益證明機制。從一個演算法的角度,主要分為兩種: 鏈型態的權益證明機制 及 Byzantine Fault Tolerance( BFT,拜占庭容錯)相似的權益證明機制。 - -在鏈型態的權益證明機制中,演算法在每個時間區間(例如每十秒為一區間)裡以偽隨機的方式選擇驗證者,並賦予其創造一個區塊的權利。而這個區塊如同區塊鏈,必須指向之前的區塊(通常是指向最長鏈的最新區塊),並隨時間拉長,成為單一條持續增長的鏈。 - -在拜占庭容錯相似的權益證明機制中,某個驗證者被隨機指派來_提議_(propose)新的區塊,每一輪每個驗證者將票(vote)投給特定的區塊,經過多輪投票來決定區塊是否有效。在過程結束之後,該區塊是否合法會達成永久的共識,即不會再改變。 - -### 權益證明機制在和工作量證明機制相比下有哪些優點? - -詳細說明可見:[A Proof of Stake Design Philosophy](https://medium.com/@VitalikButerin/a-proof-of-stake-design-philosophy-506585978d51)裡有更完整的論述。 - -簡短來說: -* 不需要為了達成鏈的安全而**消耗大量電力**,(估計以太坊和比特幣每天都會各消耗一百萬美元在電力及硬體成本上)。 -* 因為不需要消耗大量電力,所以**沒有發行等量的貨幣的需要**來提供加入網路的動機。理論上甚至可以有淨量為負值的發行量--透過銷毀一部分的交易手續費的方式來達成。 -* 權益證明機制提供了更多賽局理論的發揮空間,來**降低中心化組織的形成**,以及在組織已形成的情況下,可能的方法來防止他們進一步傷害網路(例如工作量證明機制中的[selfish mining](https://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf))。 -* **減少中心化造成的風險**。因為採用權益證明機制後,礦工(驗證者)要擴展規模將不會是個問題。在工作量證明機制中,當你資本多到一定程度,你可以負擔更好的規模生產設備,拉大和其他人的差距(投入一千萬的成本所獲得的收益不只是投入一百萬的十倍)。而在權益證明機制中,相比於一百萬貨幣,持有一千萬的貨幣會保證讓你獲得十倍的報酬,而且是以公平的方式。 -* 可以利用經濟上的懲罰來**大大地提高不同51%攻擊方式在權益證明機制中所需要的成本**,引用 Vlad Zamfir 所述--"想像一參與51%攻擊你的ASIC工廠就會被燒毀"。 - -### 權益證明機制和傳統的拜占庭容錯研究怎麼結合? - -拜占庭容錯研究中有一些重要的結論是適用到各種共識演算法中的,包含傳統的演算法如PBFT,同時也可用在任何權益證明機制中。如果搭配恰當的數學模型,甚至可以用在工作量證明機制中。 - -這些重要的結論包含: - -* [**CAP 理論**](https://en.wikipedia.org/wiki/CAP_theorem) - "如果網路發生阻斷(partition)時,你只能選擇資料的一致性(consistency)或可用性(availability),無法兩者兼得"。論點很直覺:如果網路因阻斷而分隔為二,在其中一邊我送出一筆交易:"將我的十元給A";在另一半我送出另一筆交易:"將我的十元給B"。則此時系統要不是 (1)無可用性,即這兩筆交易至少會有一筆交易不會被接受;要不就是 (2)無一致性,一半看到的是A多了十元而另一半則看到B多了十元。要注意的是,CAP理論和擴展性(scalability)是無關的,他在分片(sharded)或非分片的系統皆適用。 - -* [**FLP impossibility**](http://the-paper-trail.org/blog/a-brief-tour-of-flp-impossibility/) - 在非同步(asynchronous)的環境中(即兩個正常運作的節點間,網路延遲沒有上限),只要有一個惡意的節點存在,就沒有演算法能在有限的時間內達成共識。但值得注意的是,["Las Vegas" algorithms](https://en.wikipedia.org/wiki/Las_Vegas_algorithm)在每一輪皆有一定機率達成共識,隨著時間增加,機率會越趨近於1。而這也是許多成功的共識演算法會採用的解決辦法。 - -* 容錯的上限 - 由[ DLS 論文](http://groups.csail.mit.edu/tds/papers/Lynch/jacm88.pdf) 我們可以得到以下結論: (1)在部分非同步(partially synchronous)的網路環境中(即網路延遲有一定的上限,但我們無法事先知道上限是多少),協議可以容忍最多 1/3 的拜占庭故障(Byzantine fault)。 (2)在非同步(asynchronous)的網路環境中,具 deterministic 性質的協議無法容忍任何錯誤,但這篇論文並沒有提及[ randomized algorithms](http://link.springer.com/chapter/10.1007%2F978-3-540-77444-0_7) 在這種情況可以容忍最多1/3的拜占庭故障。 (3)在同步(synchronous)的網路環境中(即網路延遲有上限且上限是已知的),協議可以容忍 100% 的拜占庭故障,但當超過 1/2 的節點為惡意節點時,會有一些限制條件。要注意的是,我們考慮的是"具認證特性的拜占庭模型(authenticated Byzantine)",而不是"一般的拜占庭模型";具認證特性指的是將如今已經過大量研究且成本低廉的**公私鑰加密機制**應用在我們的演算法中。 - -工作量證明機制 [已被 Andrew Miller 及其他人分析過](https://socrates1024.s3.amazonaws.com/consensus.pdf),是一個仰賴同步的網路環境的模型。我們可以將網路設定為有接近無窮數量的節點,而每一個節點擁有非常小的算力,且在一定時間內有非常小的機率可以產生區塊。在這個設定中,假如沒有網路延遲存在,則此協議有 50% 的容錯率。經過觀察,以太坊有約 46% 而比特幣擁有約 49.5% 的容錯率,但如果網路延遲和產生區塊時間相當時,容錯率會降低至 33% ,若網路延遲趨近無限,則容錯率趨近零。 - -權益證明機制則是包含在拜占庭容錯共識模型中,因為所有驗證者皆是已知且系統會記錄驗證者的數量。權益證明機制的研究一般可分為兩個路線,一個是同步的網路環境模型,一個是部分同步的網路環境模型。鏈型態的權益證明機制演算法幾乎都仰賴同步的網路環境模型,而它們的安全性分析也都可用這些模型以相似於 [工作量證明機制](http://nakamotoinstitute.org/static/docs/anonymous-byzantine-consensus.pdf) 的方式來分析證明。另一個路線將部分同步網路環境中的傳統拜占庭容錯演算法和權益證明機制做連結,但解釋比較複雜,在後面的章節會有更深入的探討。 - -工作量證明機制演算法和鏈型態的權益證明機制演算法都偏好資料的**可用性**而非資料的**一致性**,但拜占庭容錯類的共識演算法更傾向於選擇資料的**一致性**,[Tendermint](https://github.com/tendermint/tendermint) 明確地選擇資料一致性的特質。而 Casper 則採用混合的模型,此模型偏好資料的可用性,但盡可能的確保資料的一致性,它讓鏈上的應用和使用者在任何時間都能知道當前資料的一致性有多大的保證。 - -Ittay Eyal 和 Emin Gun Sirer 的 [selfish mining 研究](https://bitcoinmagazine.com/articles/selfish-mining-a-25-attack-against-the-bitcoin-network-1383578440) 結論 - 在不同網路環境的模型中,比特幣挖礦的激勵兼容性(incentive compatibility)分別受到 25% 及 33% 的限制,即只有在 25% 或 33% 的礦工同謀不可能發生的前提下,挖礦的機制才是激勵兼容的(即礦工按照正常的方式挖礦:有多少算力獲得多少報酬)。這個結論和傳統的共識演算法的結論無關,因為傳統共識演算法的結論並沒有牽涉到激勵兼容性。 - -### 什麼是"無成本風險"問題及該如何解決這個問題? - -在許多之前(鏈型態)的權益證明機制演算法,包含 Peercoin,只有對產生區塊給予相對應的獎賞但並沒有懲罰。這在出現多條相競爭的鏈(即分叉)的情況時,會有非預期的影響,因為每個驗證者皆有動機在每一條相互競爭中的鏈上產生區塊(以下將下注和產生區塊視為相同意思)來確保他們會獲得獎賞,如下: - -![](https://raw.githubusercontent.com/vbuterin/diagrams/master/possec.png) - -在工作量證明機制中,這麼做會導致礦工的算力被分散,導致獲利下降: - -![](https://github.com/vbuterin/diagrams/blob/master/工作量證明機制sec.png?raw=true) - -當給予區塊獎賞的同時卻沒有懲罰,結果就會造成 - 如果每個驗證者都是狹義上(narrowly)經濟理性的話,則即便在沒有任何攻擊者的情況下,區塊鏈本身也沒辦法達成共識。因為每個驗證者都在每條鏈上下注。如果有攻擊者,攻擊者只需要贏過那些執行利他行為(altruistic,即只會在單一條鏈下注)的節點即可,不需要贏過那些經濟理性的節點。相反的在工作量證明機制中,攻擊者必須要同時贏過利他節點和經濟理性節點(但這確實是可行的攻擊:參考 SchellingCoin 的 [P + epsilon 攻擊](https://blog.ethereum.org/2015/01/28/p-epsilon-attack/))。 - -有些人會認為下注者有動機按照規則來下注且只下注在最長的鏈上,好讓他們的投資能夠保值。然而這個論點忽略了這個動機受制於公地悲劇理論([tragedy of the commons](https://en.wikipedia.org/wiki/Tragedy_of_the_commons)):每個下注者可能只會有 1% 的機會成為關鍵(pivotal)的角色(即他的決定會影響一個攻擊的成敗),所以用來買通他們的賄絡金額只需要是他們總賭注金額的 1% 。因此,全部的賄賂金額只需要是下注總額的 0.5-1% 。此外,本段開頭的論點同時暗示著任何"不可能失敗"的情況都不是一個穩定的平衡,因為不可能失敗的情況代表每個下注者成為關鍵角色的機會是零,即只要賄賂金額超過 0% 都能讓下注者有動機參與攻擊。 - -有兩種方式可以解決這個問題。第一個為 "Slasher",在[這篇文章](https://blog.ethereum.org/2014/01/15/slasher-a-punitive-proof-of-stake-algorithm/)有大略地描述,並進一步由 [Iddo Bentov ](https://arxiv.org/pdf/1406.5694.pdf)開發。當驗證者同時在不同條分叉的鏈上下注(產生區塊)的情況發生時,將證據紀錄進區塊鏈中並以此銷毀驗證者的下注資本。這讓動機結構改變如下: - -![](https://github.com/vbuterin/diagrams/blob/master/slasher1sec.png?raw=true) - -注意,這個演算法要能執行,**驗證者是哪些人**需要事先就知道。否則驗證者可以任意選擇要下注的鏈:即當A鏈可下注就下注A鏈,當B鏈可下注就下注B鏈,當兩條都可以下注就下注最長的鏈。所以事先確定驗證者的名單可以避免這種情況發生。但這也有缺點存在,包括要求節點需要頻繁地上線來獲得安全可信的鏈的狀態(即確認區塊是不是由合格的驗證者所產生),並且讓 medium-range 的驗證者共謀攻擊有可能發生(例如連續三十個驗證者中有25個預謀發起攻擊來回復過去19個區塊),因為驗證者事先知道什麼時候會輪到他產生區塊。如果這些風險是可接受的那就沒太大問題。 - -第二個方式單純地懲罰在錯的鏈產生區塊的驗證者。也就是當有兩個互相競爭的A和B鏈,如果有一個驗證者在B上面產生區塊,則他可在B鏈上獲得 R 的獎賞,但這個區塊的標頭(header)資料會被記錄在A鏈上(在 Casper 中叫做 "dunkle" )且他在A鏈上會受到 F 的罰金( F 可能等於 R )。這會將結構改變成: - -![](https://github.com/vbuterin/diagrams/blob/master/slasher2sec.png?raw=true) - -直覺來說,我們可以把工作量證明機制的經濟模型複製到這來用。在工作量證明機制中,在錯的鏈上產生區塊同樣有懲罰,但這個懲罰並不顯而易見:礦工額外的電力或硬體成本花費(因為要同時在兩條鏈上花費運算)。第二個方式的一個缺點是,它將些微的風險加注到驗證者身上(因為驗證者要承擔在錯的鏈上產生區塊的成本),不過這個風險會隨者時間慢慢減退,但另一方面,它的優點是不需要事先知道驗證者有誰。 - -### 上一章節介紹鏈型態的權益證明機制如何解決"零風險成本"問題,那拜占庭容錯相似的權益證明機制又是怎麼運作的呢? - -拜占庭容錯類型(部分同步的網路環境)的權益證明機制演算法允許驗證者藉由送出遵守兩類別規則的簽名訊息,來對區塊進行"投票",這兩類規則分別是: - -* **終局條件(Finality conditions)** - 規則用來決定某雜湊值是否可被視為不可更改的(finalized)。 -* **刪砍條件(Slashing condition)** - 規則用來決定是否有足夠理由懷疑某個驗證者作弊(例如同時下注多個相衝突的區塊)。 - -如果有驗證者觸發其中任何一條規則,他們的資本將全數被刪去。 - -以下舉兩個例子來說明不同刪砍條件的發生場景,下面的" 2/3 的驗證者" 代表 "全數驗證者資本總和的 2/3,而不是驗證者數量的 2/3 ",其他的比例亦相同。在這些例子中,"PREPARE" 和 "COMMIT" 可單純地理解為兩種驗證者可送的簽名訊息(`MESSAGE`)。 - -1. 如果`MESSAGE`包含:`["COMMIT", HASH1, view]` 和 `["COMMIT", HASH2, view]`,其中`view`為相同但`HASH1`和`HASH2`不同,且皆由同一個驗證者所簽名,則該驗證者的資本被刪去。即不能同時對相衝突的區塊做簽名。 -2. 如果`MESSAGE`包含:`["COMMIT", HASH, view1]`,則**除非** `view1 == -1` ,或同時存在其他包含`["PREPARE", HASH, view1, view2]`的簽名訊息(其中 `view2 < view1`)且這些訊息由至少 2/3 的驗證者所簽名,則對`"COMMIT"`簽名的驗證者的資本被刪去。即一個 `HASH` 值只有經過至少 2/3 `PREPARE` 才能被 `COMMIT`。 - -合適的刪砍條件需要有兩個重要的要求: - -* **可咎責的安全性(Accountable safety)** - 如果相互衝突的`HASH1` 和 `HASH2`(即分叉)都被認定為不可更改,則至少有 1/3 的驗證者肯定違反了某些刪砍條件。 -* **Plausible liveness** - 除非至少 1/3 的驗證者違反了某些刪砍條件,否則必定存在某些合法的訊息是 2/3 的驗證者可以簽的,且這些訊息會讓某些雜湊值變成不可更改(finalized)。即除非至少 1/3 的驗證者違規,否則一定可以讓新的雜湊值被 finalize。 - -如果我們有一組刪砍條件可以達成這兩個要求,我們便可以提供驗證者足夠的動機,並開始從 economic finality 的特性中得到成果。 - -### 一般來說,什麼是"經濟面上終局的特性"? - -經濟面上終局指的是:當區塊被認定為不可更改,或更一般來說,有一種訊息獲得足夠數量的簽名,則唯一讓鏈在未來納入另一個相衝突的區塊的方法是有一大群的人願意賠上一大筆錢。如果一個節點看到某個區塊符合經濟面上終局的特性,則他有經濟面上非常大的保證這個區塊會成為鏈的一部分歷史(且這條鏈也是大家都認可的)。 - -達成經濟面上終局有兩種方法: - -1. 如果有足夠多的驗證者對以下形式的聲明進行簽名,則一個區塊可被視為具有經濟面上的終局:"當區塊B沒有被收入則我會失去X的資本"。這讓使用者獲得了如下的保證 - (I)區塊B是鏈的一部分,或是 (II)若驗證者想騙他們,讓他們相信區塊B是有被收入的,則驗證者會損失一大筆錢。 - -2. 如果有足夠多的驗證者簽名表達支持收入區塊B,而且有方式能在驗證者違規時提出數學證明(_當不同於區塊B的某區塊B'也以同樣方式被收入_)並讓這些驗證者損失一大筆錢,則一個區塊可被視為經濟面上的不可更改。如果使用者看到這個被收入的區塊,並驗證了鏈的有效性,且藉由有效性(validity)和不可更改性(finality)他們可以在發生分叉的鏈之中做出選擇,則他們能獲得如下的保證 - (I)區塊B是鏈的一部分,或是 (II)若驗證者同時也參與了另一條互相競爭且亦符合終局條件的鏈,則驗證者會損失一大筆錢。 - -兩種達成終局(finality)的方法分別繼承自"零風險成本問題"的兩個解決方法: 藉由懲罰錯誤(如`"COMMIT"`不合法的區塊)來達成終局 及 藉由懲罰不明確性(如`"COMMIT"`兩個衝突區塊)來達成終局。第一個方法的主要優點是輕客戶端(light client)使用者也能驗證且比較直覺易懂;第二個方法的主要優點有 (I)比較容易瞭解為何誠實的驗證者不會被懲罰及 (II)干擾因素(griefing factors)對誠實的驗證者比較有利 - 相比於不誠實者干擾誠實者所要付出的成本,誠實者干擾不誠實者的成本是比較低的。 - -Casper 遵循第二種方法。不過可以透過增加鏈上的機制,讓驗證者可以自行選擇是否要對第一種方法的聲明("當區塊B沒有被收入則我會失去X的資本")簽名,此舉可讓更多輕客戶端使用者增加效率。 - -### 所以這和拜占庭容錯理論有什麼關聯? - -傳統的拜占庭容錯理論在 safety 和 liveness 上和我們有相似的要求。首先,傳統拜占庭容錯理論要求當超過 2/3 的驗證者是誠實的時候,safety必須要被達成。嚴格來說這是比較容易實現的模型,傳統的拜占庭容錯理論嘗試證明"如果共識機制無法達成safety,則我們知道至少有 1/3 的驗證者是惡意的";而我們的模型則是嘗試證明"如果共識機制無法達成safety,則我們知道至少有 1/3的驗證者是惡意的,而且我們知道是哪些驗證者,即便你在出現問題的當下不在線上"。從liveness的角度,我們的模型比較容易達成,因為我們不需要證明**共識會被達成**,我們只需要證明機制**沒有卡住**。 - -不過幸運的是,額外的"可咎責的"(accountable)特性需求其實不難實現;事實上,只要協議有正確的防禦機制(protocol armor),我們都可以將任何不管是部分同步或是非同步的傳統拜占庭容錯演算法轉換成可咎責的演算法。這個證明基本上歸結於一個事實--拜占庭故障(fault)可以被窮舉並分類,而這每一類要不是 (I)可咎責的(如果你`"COMMIT"`了這類的訊息,則你會被逮到,且我們可以為此建立一條刪砍條件的規則),要不就是 (II)無法被分辨是網路延遲還是故障(注意,即便是太早送出訊息這種故障,也沒辦法被分辨出來)。 - -### 什麼是弱主觀性(weak subjectivity)? - -首先很重要的一點是,利用存款(deposit,也就是驗證者加入的資本)來確保"風險成本不為零"的機制,改變了權益證明機制的安全模型假設(security model)。假設 (I)存款會被鎖住一個月,時間到之後可以提走, (II)有個 51% 攻擊嘗試反轉(revert)長達 10 天的交易量,則這些攻擊者產生的區塊會被寫入鏈裡當作證據且驗證者會被懲罰。然而,假設攻擊變成長達 40 天,則雖然這些攻擊產生的區塊可以再被寫入鏈裡,但驗證者早已能把錢提走而不會受到懲罰。為了要解決這個問題,我們需要一個"反轉限制(revert limit)"的規則,也就是當反轉所影響的區塊總時間長度超過存款鎖住的期限,則節點可以拒絕接受這些區塊(在上例,即拒絕影響超過一個月的反轉區塊)。這表示節點現在多了兩項要求: - -1. 當節點第一次連上並要同步鏈的資料的時候,他們必須藉由鏈外的方式來驗證最新的狀態,即透過朋友節點們或各個 Block Explorer 等等的方式。如果他們得到的都是同一條一樣的鏈,則可以確定這條是正確的。注意,只有在出現鏈分叉長度超過反轉限制時(在上例,即得到兩條在過去超過一個月的區塊皆不相同的鏈)才需要這種採用這種鏈外的交際驗證(social authentication)。 - -2. 節點每隔一段的時間("反轉限制"時間)就必須要上線同步。如果沒定時同步,則需要再透過一次鏈外的交際驗證來保證狀態的可信度。 - -如果攻擊者要利用鏈外交際這個管道來攻擊,他們必須要說服社群裡一大部分的人,讓他們相信攻擊者的鏈才是有效的;或是改為說服新加入社群的人:新加入的人可能會在下載軟體時一並收到最近一次的檢查點(checkpoint,即反轉限制的臨界點),但如果攻擊者能竄改這個檢查點的紀錄,則他們要能直接竄改整個軟體也不再是件難事,而且沒有單純的密碼經濟學的驗證方式能解決這個問題。當一個節點連接上了,只要他夠頻繁地上線,他就能以密碼經濟學上安全的模型來確保連接上正確的鏈,而不需要額外的鏈外交際驗證。 - -另外,這種交際驗證如果需要,也可以直接加入進使用者使用的過程中:如 (1)[BIP 70](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki)的交易就要求交易裡要加入最近一段時間的某個區塊的雜湊值,使用者的軟體會在交易成立前,藉此確保使用者和商家是在同一條鏈上(也可以透過其他鏈上的互動方式)。 或(2),採用Jeff Coleman的 [universal hash time](https://www.youtube.com/watch?v=phXohYF0xGo)。採用UHT的話,如果攻擊要能成功,攻擊者必須在被攻擊鏈繼續增長的**同時**,暗中產生另一條鏈(即攻擊者沒辦法事先或在事後短時間內產生一條相抗衡的鏈),代表這需要大多數的驗證者共謀了一段非常長的時間。 - -### 在權益證明機制裡可以用經濟上的方式來懲罰審查(censorship)行為嗎? - -審查行為比起交易反轉要更難去證明。區塊鏈本身無法分辨 (1)"使用者 A 嘗試送出交易 X 但被審查過濾掉了" 或是 (2)"使用者 A 送出交易 X 但因為交易費不夠而沒被收入區塊裡" 或是 (3)"使用者 A 從未送出交易 X "。但仍有一些方法可以對抗審查行為。 - -第一個是使用停機問題(halting problem)。這個方法比較弱的版本是將協議設計成圖靈完備,使得驗證者無法知道一筆交易會不會在花費他大量的運算後因為出現預期外的行為而出錯,但這同時也讓驗證者面臨潛在的 DoS 攻擊。這也是當初[ the DAO 軟分叉](http://hackingdistributed.com/2016/07/05/eth-is-more-resilient-to-censorship/)沒有實行的原因。 - -比較強的版本則是讓交易在未來中短期的時間內觸發特定的效果。使用者可以送出多筆相互關聯的交易及利用可預期的第三方的資訊來導致未來事件的發生,想要進行審查的驗證者要等到交易都被收入區塊(並確認為不可更改)才能知道發生了什麼事件,但此時要阻止交易又已經太遲。即便過濾掉所有相關的交易,審查者想阻止的事件還是會發生。審查者可以試著過濾掉每一筆交易,或是過濾掉沒有附上相關證明(證明交易不會導致任何非預期的情況發生)的交易,但這麼做會擋掉非常多不同類型的交易以至於讓整個系統失靈,審查者的存款價值也會跟著該數位貨幣的價值崩盤而下降。 - -第二個方法是([如 Adam Back 在這篇文章](https://www.reddit.com/r/Bitcoin/comments/4j7pfj/adam_backs_clever_mechanism_to_prevent_miners/d34t9xa))所介紹,要求交易都經過[timelock-encrypted](https://www.gwern.net/Self-decrypting%20files)加密。所以審查者只能在不知道交易的內容的情況下將交易收入區塊,直到之後某個時間點交易內容被揭露,但此時要過濾掉交易已經太遲。但是審查者可以選擇只收入有附上解密證明(如利用 zkSNARK 等零知識證明)的交易;這雖然會強迫使用者必須要去下載相關的使用軟體,但審查者可以直接提供所需軟體。這在賽局理論中,使用者是有動機去配合的。 - -或許在權益證明機制中比較好的做法是使用者透過軟體更新來執行硬分叉,將惡意的驗證者移除。這個方法和下載解密軟體來配合審查的方法相比,並沒有多難。總之,第二個方法雖然會降低和鏈溝通互動的速度(注意,採用這個方法必須是強制的才會有效,否則審查者只需要過濾掉經過加密的交易並收入沒加密的交易即可),卻也是比較適度且有效的。 - -第三個方法是在鏈分叉發生時,將偵測審查行為發生的機制加進分叉選擇的考量。原理很簡單,節點持續觀察著網路及交易,如果他們發現某筆交易帶有夠多的手續費卻遲遲未被收入,就給沒有收入這筆交易的鏈較低的評分。如果所有的節點都遵守這規則,則最終較弱勢的鏈也會因為收入了這個交易而讓其他誠實的節點都轉而加入這條鏈。這個方法主要的缺點是,離線的節點還是紀錄者強勢的(有審查機制的)鏈,如果在他們重新上線之前審查行為就結束了,則會造成上線的(誠實的)節點間的分歧。因此這個方法比較適合被用來當作緊急情況如硬分叉發生時的一個節點間的協調工具,如果是用在幾乎每天都會發生的鏈分叉選擇考量則不太合適。 - -### 驗證者是怎麼選出的?什麼又是stake grinding? - -在任何鏈型態的權益證明機制演算法中,都需要一個機制來隨機選出哪個驗證者可以產生下個區塊。例如,假設目前活躍中的驗證者包含 資本為 40 元的的 Alice、資本為 30 元的 Bob、資本為 20 元的 Charlie 及資本為 10 元的 David,則你希望他們各自被選出的機率分別為 40%、30%、20%及10%(當然在實際情況中,你會希望選出來的是一連串無限的候選人而不是一個,這樣當前面一位沒出現,後面一位就可以遞補,但這不影響根本的問題)。在非鏈形態的演算法中,一樣會因為不同原因而需要隨機性(randomness)。 - -"Stake grinding"是一種驗證者試圖透過一些計算或其他方式來影響隨機性的攻擊。例如: - -1. 在 [Peercoin](https://bitcointalk.org/index.php?topic=131901.0) 中,驗證者可以搜尋各種參數的組合並找到特定的參數來增加他們產生有效區塊的次數。 - -2. 在一個目前已經不使用的方式裡,第 N+1 個區塊的隨機性取決於第 N 個區塊裡的簽章。這讓驗證者可以重複產生新的簽章直到他們找到一個特別的簽章來讓他們能預測並掌握下一個區塊,以藉此控制系統。 - -3. 在 NXT 中,第 N+1 個區塊的隨機性取決於產生第 N 個區塊的驗證者。這讓驗證者可以藉由跳過一個產生區塊的機會來操縱隨機性。雖然這麼做的機會成本是損失一個區塊獎賞,但有時候新產生的隨機種子可以讓驗證者在未來數十個區塊中獲得高於平均區塊獎賞的獎勵。[這裏](http://vitalik.ca/files/randomness.html)有更詳細的分析。 - -\#1和\#2很容易解決;一般的做法是要求驗證者事先存款來避免驗證者一直改變身份(address)來找到可以影響隨機性的值,並避免使用可以輕易被操縱的訊息,例如一個區塊裡的簽章。有幾個主要的策略來解決\#3。第一個是利用 [secret sharing](https://en.wikipedia.org/wiki/Secret_sharing) 或是 [deterministic threshold signatures](https://eprint.iacr.org/2002/081.pdf) 並要求驗證者一同產生隨機值。這些方法在大多數驗證者沒有同謀的時候都足夠穩固(看各種應用不同,33%-50% 的驗證者合謀就可以干預,使得協議對維持 liveness 的機率假設剩下 67% )。 - -第二個方法是使用密碼學的方式:驗證者事先 commit 一些訊息(如公布 `sha3(x)`),接著在區塊內公佈 `x` 值,最後將 `x` 值和其他人的隨機值加在一起。理論上針對這個方法有兩種潛在的攻擊。 - -1. 在commit時操縱 `x` 值。但因為結果會將許多人的 `x` 值一起加入考量,其中只需要一個人是誠實的,隨機性的分佈就會呈常態分佈,所以這攻擊不太可行。 - -2. 選擇性地不公開區塊。這種攻擊的機會成本是損失一個區塊獎賞,而且這個方法頂多只能讓一個人看到下一個區塊的驗證者是誰,所以最多可能的獲益也是一個區塊獎賞。唯一的例外是,如果一個驗證者跳過,則遞補上來的驗證者和下一個區塊的驗證者有可能會是同樣一個驗證者。可以用懲罰的方式來抵消驗證者跳過的動機。 - -第三個方法是使用 [Iddo Bentov 的 "majority beacon"](https://arxiv.org/pdf/1406.5694.pdf),藉由之前產生的(也用 beacon 方式產生的) N 個隨機數字中的每個 bit 值的多數決來產生新的隨機數字(即,如果大多數數字的第一個 bit 為 1 ,則新的數字的第一個 bit 為 1 ,否則為 0 )。攻擊的成本會是 `~C * sqrt(N)` ,其中 C 是攻擊其他 beacon 產生的隨機數字的成本。總之,有許多 stake grinding 的解決方法存在,這個問題比較像是 [differential cryptanalysis](https://en.wikipedia.org/wiki/Differential_cryptanalysis) 而不是 [halting problem](https://en.wikipedia.org/wiki/Halting_problem) - 權益證明機制的設計者最終會明瞭且會知道如何克服,不是很根本且無法彌補的缺陷。 - -### 針對 Casper 的 51% 算力攻擊會是怎麼樣的攻擊? - -51% 攻擊最基本的形式就是 **finality reversion**:驗證者確立區塊 A 的紀錄為不可更改後又將另一個區塊 A' 也列為不可更改,打破區塊不可更改特性的保證。在這個情況中並存著兩個彼此不相容的歷史紀錄,導致鏈產生分叉。這需要仰賴社群以鏈外的方式進行協調來決定應該選擇哪條鏈,而哪條該被捨棄。 - -協調的管道有很多種,如社群媒體、block explorer 及交易所間的溝通、線上論壇等等。決定該選哪條鏈的原則是 "哪條先出現就選哪條" 。另一個方式是讓市場機制去決定:在很短的時間裡,兩條分叉都可以在交易所中交易,直到其中一條因為價值更高而勝出。在這種情況中,"哪條先出現就選哪條" 的原則會是市場機制的 [Schelling point](https://zh.wikipedia.org/wiki/谢林点),即參與者會因為覺得其他人也會選擇先出現的那條鏈而傾向選擇先出現的那條,所有人在沒有溝通的情況下按照這個傾向選擇了先出現的那條鏈。所以實際中,這兩種方式並用是非常有可能的。 - -當該選擇哪條鏈的共識達成時,使用者(即驗證者、light node 及 full node)就可以手動地將勝出區塊的雜湊值藉由特殊的選項寫入軟體中,之後他們的節點就會忽略其他不包含該雜湊值的鏈。之後不管是哪條鏈被選擇,都有證據可以用來懲罰至少 1/3 的違規驗證者。 - -另外一種攻擊是阻斷 liveness:一個由超過 34% 驗證者組成的集團可以拒絕和其餘的驗證者合作。在這種情況下,將沒有區塊能被變成不可更動。Casper 採用混合(鏈 + 拜占庭容錯)型態的共識,因此鏈還是會持續增長,但安全性會大大降低(因為一直沒有新的區塊可以被視為不可更改)。如果很長一段時間(例如一天)都沒有區塊變成不可更改,則有以下幾種選項: - -1. 可以採用一個自動化的功能來輪轉驗證者名單,瓦解集團的佔比。在新的驗證者名單中區塊有機會被變為不可更改,但使用者會收到提醒告訴他們這些不可更改的區塊還是不能全信的,因為很有可能舊的一組驗證者會重新奪回控制權並改為將其他的區塊變為不可更改。使用者如果確信舊的一組驗證者不會再上線,就可以忽略這些警告。在這種情況發生時,所有舊的驗證者如果沒有再繼續參與共識過程,則他們會受到相當大筆的罰款。 - -2. 採用硬分叉的方式移除集團驗證者的存款,並增加新的驗證者。 - -在第二種方法中,分叉還是一樣要由鏈外的共識來協調,且可能會由市場機制的方式(即兩條擁有不一樣驗證者組成的鏈短暫的並存於交易市場上)。如果是藉由市場共識的方式,有個有力的論點是:市場會傾向選擇 "好人勝出" 的鏈,這條鏈的驗證者展現了他們的誠意(或至少他們和使用者的利益是並存的),因此也是一條對應用開發者較有用的鏈。 - -選擇攻擊應對的策略如社交協調或機制內自動化,兩者之間其實有如一道光譜,並不是非黑即白。通常設計越往自動化的解法越理想,因為這可以降低當 51% 攻擊和社交層面(包含市場共識如交易所)的攻擊同時發生時的風險。可以想像一個採用 \#1 的措施:節點在超過一定時間都沒有區塊變為不可更改時自動更換驗證者名單,這會降低交際協調的需要,但節點也因此要更頻繁地保持上線。但不管是哪種方式,攻擊者都會損失一大筆的錢。 - -另外一種比較不容易發覺的攻擊是審查攻擊:超過 34% 的驗證者拒絕將含有某些特定交易的區塊變為不可更改,除此之外鏈的運作都正常。攻擊的範圍從輕微的,干擾特定應用的攻擊(如過濾 Raiden 或閃電網路的交易是較簡單偷錢的方式)到阻擋所有交易的大範圍攻擊。 - -其中又分成兩種情況,第一個是攻擊者佔 34%-67%。在這種情況中,正常的驗證者可以拒絕將他們主觀認定為正在過濾交易的區塊(即攻擊者產生的區塊)變成不可更改或接在後面,這讓這種攻擊變為一個標準的針對 liveness 的攻擊。比較危險的情況是當攻擊者佔超過 67%,攻擊者可以任意的阻擋他們不喜歡的交易並拒絕接在包含這些交易的區塊後面。 - -面對這個攻擊有兩道防線。第一,以太坊具有圖靈完備特性,[在本質上就具有抵抗審查的能力](http://hackingdistributed.com/2016/07/05/eth-is-more-resilient-to-censorship/),因為審查交易的過程在某種程度上相似於解決停機問題(halting problem)。但因為區塊有 gas 限制,所以審查並不是不可能,不過用"簡單"的方式來審查反而會讓攻擊者自己有被 DoS 的風險。 - -單純具有這個抵抗能力[還不夠好](https://pdaian.com/blog/on-soft-fork-security/),還有其他方式可以加強抵抗審查的能力。最有趣的方式是增加一個機制內的功能:讓交易能自動規劃未來的事件,因為預測一個事件的執行結果或是連鎖事件是很難的。驗證者可以藉由混淆事件規劃的順序來加入成為驗證者,藉此稀釋攻擊者的佔比到低於 33% 。 - -第二,引進 "active fork choice rule" 的概念:當面臨鏈分叉,其中一個選擇鏈的考量是和鏈進行互動並藉此驗證該鏈是否有在過濾你的交易。最有效的方式是節點重複地送出一筆交易來規劃下注並在最後一刻取消。如果節點偵測到審查機制,就不取消交易並暫時加入成為驗證者之一,將攻擊者的佔比稀釋到 33% 。如果集團過濾掉他們的交易,則採用這個 "active fork choice rule" 的節點就不會選擇這條鏈。這會讓審查攻擊轉變為 liveness 攻擊,此時就可以藉由解決 liveness 攻擊的方式來處理。 - -### 聽起來似乎很仰賴鏈外的社交協調,這樣難道不危險嗎? - -攻擊 Casper 代價非常高。以下我們將會講到,攻擊 Casper 的代價至少和買礦機持續不斷的對採用工作量證明機制的鏈發動 51% 攻擊直到無效果為止的代價一樣。因此,上面段落所描述的復原方法只有在非常極端的情形才會用到。事實上,工作量證明機制的提倡者亦表達在某些相似情況採用社交協調的意願,例如[改變工作量證明機制的算法](https://news.bitcoin.com/bitcoin-developers-changing-proof-work-algorithm/)。所以權益證明機制需要的社交協調是否會比工作量證明機制所需要的社交協調還多還無明確的結果。 - -在現實中,我們預期用到社交協調的方式的次數會接近零次,因為攻擊者會瞭解到單純為了讓區塊鏈停擺一兩天要花費這麼大筆的錢是不符利益的。 - -### 邊際成本趨近邊際收益不就表示所有具有一定高度安全層級的共識演算法都一樣有效(或一樣地浪費)? - -許多人都提出過這個論點,而解釋最清楚的就屬[Paul Sztorc 的這篇文章](http://www.truthcoin.info/blog/工作量證明機制-cheapest/)。其中的重點大概是:如果你創造一個有 100 元獎賞的機會,則大家為了得到它會願意花費最高到 99.9 元(包含自己付出的勞力),此時邊際成本趨近邊際效益。因此,這個理論說:任何提供區塊獎賞的演算法(不管是權益證明機制或工作量證明機制),其中為了獲取獎賞而進行對社會無效益的活動的數量都是一樣的,即它們都一樣地浪費資源。 - -這個理論有三個盲點: - -1. **單純地說邊際成本趨近邊際效益是不夠的,必須還要假設一個真的有人可以花費那些成本的機制存在。** 例如,假設我明天宣布未來每一天我都會隨機從一個十人名單中挑出一個人並給予他 100 元,然而沒有人有辦法花費 99 元來取得其中的隨機值。他們要不是不在名單中拿不到獎賞,要不就是在名單中但沒有任何有效的方法取得我的隨機值,只能獲得期望值為平均每天 10 元的獎賞。 - -2. **邊際成本趨近邊際效益不表示總成本趨近總收益。** 例如,假設存在一個演算法利用偽隨機(pseudo-randomly)的方式從一大群驗證者中選擇 1000 位驗證者(一個驗證者獲得 1 元獎賞)。如果你資本佔總資本的 10% 則你平均會獲得 100 元。假設你可以花費 1 元來(無限次地)重設隨機值,因為 [central limit theorem](https://en.wikipedia.org/wiki/Central_limit_theorem),你可獲得的獎賞的標準差是 10 元,又因為[其他已知的數學結論](http://math.stackexchange.com/questions/89030/expectation-of-the-maximum-of-gaussian-random-variables), N 個隨機抽樣中最大的期望值約略小於 ` M + S * sqrt(2 * log(N))` ,其中 M 是中間值且 S 是標準差。因此增加重設隨機值的次數(即增加 N )所獲得的獎賞會快速地下降,例如如果完全不嘗試重設隨機值你的期望獲利是 100 元,嘗試一次是 105.5 元,兩次是 108.5 元,三次是 110.3 元,四次是 111.6 元,五次是 112.6 元,六次是 113.5元(只增加 0.9 元的獲利)。因此嘗試超過五次之後就不值得再繼續嘗試。所以一個由經濟因素所驅動的攻擊者,如果他總資本佔 10% ,則他會花費 5 元嘗試重設隨機值來獲得額外的 13 元的獲利,雖然這麼做很沒效率。如果一個機制可被有心人士利用,但被利用的機率不高,則損失不會多。但這不適用於在工作量證明機制中因為出現一個漏洞而導致全部資源投入而造成浪費的情況。而這點也和下一章節要介紹的 capital lockup costs 非常相關。 - -3. **權益證明機制要變得安全穩固所需要的獎賞比起工作量證明機制的獎賞少的非常多。** - -### 什麼又是 capital lockup costs? - -將 X 數量的 ether 鎖進存庫是有代價的,例如犧牲選擇其他選項的機會。如果我有 1000 ether,我想怎麼使用就怎麼使用,但如果我將它鎖在存庫裡數個月,而且沒有保險來支付可能的意外支出的時候該怎麼辦?在這段時間我同時也失去將 ether 轉換成其他代幣的自由。我可以透過賣空相等數量 ether 的方式來模擬賣掉我的 ether,但會有交易手費續和利息的成本。有些人可能會認為: captital lockup 造成的經濟上的不便和工作量證明機制造成的經濟層面上無效率的程度是一樣的。但答案是否定的,如同上一章節的理由\#2和理由\#3。 - -我們先從理由\#3開始講起。考慮一種模型:權益證明機制存款是無限期的、ASICs可以永久持續運作、ASIC技術固定(即不適用摩爾定律)而且電力花費是零,並假設穩定的利率是每年 5%。在工作量證明機制裡,我花 1000 元買了礦機,礦機每年給我 50 元的利潤直到永遠。在權益證明機制中,我存 1000 元(因為存款是無限期的所以這筆錢當作花掉)並獲得每年 50 元的利潤直到永遠。到目前為止,兩種情況看起來是等價的(雖然技術上來說,在權益證明機制中當我的存款因違規被銷毀時,會間接造成其他人的存款價值升高,但這邊我們先不討論)。在這個假設下,不管是權益證明機制或工作量證明機制,任何人要發動 "Maginot-line" 51% 攻擊(即硬體買得比網路其他人加起來還多)的成本都會因為我的加入而再多上 1000 元。 - -現在假設模型依序做以下的變更: - -1. 摩爾定律適用,ASICs 每 2.772 年貶值 50%(為方便計算,假設其價值每年持續降低 25%)。如果我要繼續保持 "付一次,永遠都能持續拿回錢" 的模式,我可以將 1000 變成一筆資金,其中167用來買 ASICs ,833 元花在 5% 報酬率的投資。833元的投資產生每年 41.67 元的利潤剛好足夠花在更新 ASICs 設備上(為方便計算,假設技術發展是穩定連續的)。這時挖礦的利潤會降低至 167 * 0.05 = 每年 8.33 元,因此 83.3% 的礦工會退出競爭,直到回到每年 50 元利潤的穩定狀態,所以這時發動 Maginot-line 51% 攻擊的成本會縮小至少六倍。 - -2. 電力加上硬體維護組成大約 1/3 的挖礦成本。1/3 是從最近的數據估計而來的:Bitfury 的新資料中心 [每 gigahash 電力消耗為 0.06 焦耳 ](http://www.coindesk.com/bitfury-details-100-million-georgia-data-center/),或 每 terahash 60 焦耳、每terahash 0.000017千瓦小時。如果假設比特幣網路的平均消耗皆如此的話,以[比特幣總共算力約 1.67 million TH/s](http://bitcoinwatch.com/) 來算,每秒約消耗 27.9 千瓦小時。中國電力成本為[每千瓦小時 0.11 元 ](http://www.statista.com/statistics/477995/global-prices-of-electricity-by-select-country/),約為每秒 3 元或每天 26 萬元。比特幣區塊獎賞加上手續費為 600 * 13 * 144 = 一天 112 萬元。因此電力組成約 23% 的成本,另外我們可以用簡單的計算預估硬體維護成本為 10% 。這表示你的 1000 元資金裡,只有 111 元要拿來買 ASICs,55 元要拿來付持續性的花費如電力和維護等,而 833 元會花在投資上,因此現在要發動 Maginot-line 51% 攻擊的成本已經是一開始的至少九倍小了。 - -3. 事實上存款是短暫而非永遠(被視為拿不回來)的,當然你自願永遠存著的話也行。這讓我多了一些空間選項,我可以在任何時間內結束並等待一段時間(如四個月)。這表示我願意花更多的錢來獲得更多的利潤(因為投資不會再被當作拿不回來的錢),或許是 3000 元。因此,在權益證明機制裡發動 Maginot line 51% 攻擊的成本增加為原本的三倍,和工作量證明機制比起來是 27 倍的安全性。 - -以上包含了很多簡化過的計算,但它的目的是為了指出經過許多因素考量,都顯示出權益證明機制有更高的安全性。而這個[看似可疑的多重因素論點](http://lesswrong.com/lw/kpj/multiple_factor_explanations_should_not_appear/)為何這麼強烈凸顯權益證明機制的優點的主要理由是:在工作量證明機制中,我們操作並利用物理特性;而在權益證明機制中,我們可以設計出一套準確具有理想特性的機制 - 簡而言之,我們可以用我們的方式來優化 "物理特性"。在安全模型上的改變,特別是弱主觀性(weak subjectivity)這個性質的出現,讓我們能得到以下結論 - **權益證明機制要變得安全穩固所需要的獎賞比起工作量證明機制的獎賞少的非常多。**。 - -接者我們可以討論 邊際成本/效益 和 總成本/效益 的不同。在 capital lockup costs 的情況中這非常重要。例如假設一個情況,你有價值 100000 的 ether。鎖住其中的 50000 應該不會有什麼問題,鎖住 80000 可能會有一點不方便雖然 20000 還是夠充足,鎖住 90000 就有點問題了,99000 問題就大了,全鎖住那你可能是瘋了,因為你會連交易費都出不起。因此你的邊際成本快速的增加,我們可以用以下方式比較權益證明機制情況和工作量證明機制情況的不同: - -![](https://blog.ethereum.org/wp-content/uploads/2014/07/liquidity.png) - -可以看到在權益證明機制的總成本是遠小於存入 1 ether 的邊際成本乘上現有所有的存款總量。 - -注意,這部分的論點可惜地並沒有完全解釋到 "貨幣的安全發行量(safe level of issuance)"。但其顯示出即使我們將貨幣發行量控制地很低,我們還是能獲得可觀的 權益證明機制參與人數,雖然這也代表很大一部分的發行量會被用來獎賞驗證者。 - -### 在權益證明機制的礦池會有類似工作量證明機制礦池中心化的風險嗎? - -從 [Bitcoin](https://blockchain.info/pools) 和 [Ethereum](https://etherscan.io/stats/miner?range=7&blocktype=blocks) 來看,大約需要三個礦池聯合才能發動 51% 攻擊( 在寫這篇文章的時候,Bitcoin 約需四個、Ethereum 約需三個)。假設在權益證明機制中,包含所有礦池、交易所一共有 30% 的參與率,則 [三個礦池或交易所](https://etherscan.io/accounts) 就足夠發動 51% 攻擊;如果參與率提高到 40% 則需要八個。另外礦池、交易所也不能將所有資本投入攻擊中,因為他們需要保留部分金錢來應付客戶。 - -再加上在權益證明機制中,組成的礦池的動機是較低的,因為這會需要較高的信任成本 - 雖然礦池不偷錢,但是可以假裝被駭去觸發刪砍條件而導致資本全被沒收,同時扮成檢舉者領檢舉獎金。不過另一方面,即便需要信任對方,不需要自己跑一個 full node 就能用自己的錢賺利潤仍是很有吸引力的。總之,中心化和去中心化間的平衡需要經驗累積,也只有等到系統真的上線一段時間了才有辦法得到答案。但配上 sharding 之後,我們預計會更進一步降低中心化,因為 (i)需要考量的變化更少且 (ii)在 sharding 模型中,驗證交易的負擔和所投入的資本成正比,所以並不會因為組成礦池而節省成本支出。 - -最後一點是,中心化在權益證明機制中比其在工作量證明機制中的負面影響更小,因為從 51% 攻擊中復原容易且便宜多了,也不需要換新的挖礦演算法。 - -### 權益證明機制 能被用在私有鏈或聯盟鏈嗎? - -一般來說是可以的。任何權益證明機制演算法都可以被私有鏈或聯盟鏈用做一個共識演算法。唯一不同是成為驗證者的方式:一開始會由一群大家同意且信任的使用者成為驗證者,接著再由這群驗證者透過投票去加入新的驗證者。 \ No newline at end of file diff --git "a/pages/other-languages/[\344\270\255\346\226\207]-\347\275\221\347\273\234\347\212\266\346\200\201.md" "b/pages/other-languages/[\344\270\255\346\226\207]-\347\275\221\347\273\234\347\212\266\346\200\201.md" deleted file mode 100644 index 15cf5f2d5..000000000 --- "a/pages/other-languages/[\344\270\255\346\226\207]-\347\275\221\347\273\234\347\212\266\346\200\201.md" +++ /dev/null @@ -1,93 +0,0 @@ ---- -name: Network Status -category: ---- - -Special thanks to Kyle Chen for translation. - -# 网络状态监控 - -以太坊(中心化的)网络状态监控器 (有时被称为“eth-netstats”),是一个基于网页的应用程序,通过一组节点去监控测试链或者主链的健康状态。 - -### 登记你的节点 - -要登记你的节点,你必须安装客户端的信息中继器,这是一个节点模块。这里给出的指示可以在Ubuntu Linux上使用(Mac OS X使用同样的指示,不过sudo指令可能不是必须的)。其他平台会有所变化(请确保nodejs-legacy也安装了,不然一些模块可能会失效。) - -用Git clone指令复制程序库,然后用install指令安装PM2 - - git clone https://github.com/cubedro/eth-net-intelligence-api - cd eth-net-intelligence-api - npm install - sudo npm install -g pm2 - -然后编辑里面的app.json文件去配置你的节点:\ - -* 修改LISTENING_PORT选项右边的数值,将其改成以太坊的监听端口(默认:30303) -* 修改 INSTANCE_NAME选项右边的数值,改成你想给节点起的名字; -* 如果你想修改联系信息,将CONTACT_DETAILS选项右边的值改动 -* 修改RPC_PORT选项右边的数值,改成你的节点的RPC端口(在cpp和go的版本中都是默认8545的端口); -* 修改WS_SECRET选项右边的值,改成密令secret(你必须从官方的Skype联系渠道)获得 - -最后用以下的指令去运行进程: - - pm2 start app.json - -一些指令是可用的: - -* pm2 list 以显示进程状态; -* pm2 logs 以显示记录; -* pm2 gracefulReload node-app 以用于软重启; -* pm2 stop node-app 以停止应用程序; -* pm2 kill 以停止后台进程. - -### 升级 - -如果想升级的话,需要根据以下步骤进行: - -* git pull 以获取最新的版本 -* sudo npm update 以更新程序依赖库 -* pm2 gracefulReload node-app以重新载入客户端 - -## 在一个干净的Ubuntu系统里自动安装 - -获取和运行build shell。这会安装你需要的所有东西:在develop开发分支(你可以选eth或者geth)里面的ethereum – CLI, node.js, npm & pm2. - - bash <(curl https://raw.githubusercontent.com/cubedro/eth-net-intelligence-api/master/bin/build.sh) - -### 配置 - -通过修改processes.json配置应用程序。注意你必须修改 ./bin/processes.json,这是processes.json的备份。(以让你可以设置环境变量,而不需要在更新的时候重写它) - - "env": - { - "NODE_ENV" : "production", //告诉客户端我们在生产环境 - "RPC_HOST" : "localhost", // eth JSON-RPC Host,默认是8545 - "RPC_PORT" : "8545", // eth JSON-RPC 端口 - "LISTENING_PORT" : "30303", // eth监听端口(只用于显示) - "INSTANCE_NAME" : "", // 你想给节点起的名字 - "CONTACT_DETAILS" : "", //如果你想的话可以在这里加入你的联系信息,如电子邮件或skype - "WS_SERVER" : "wss://stats.ethdev.com", //eth-netstats WebSockets api服务器的路径 - "WS_SECRET" : "", // 用于登陆的WebSockets api 服务器密令secret } - -## 运行 - -使用pm2运行: - - cd ~/bin - pm2 start processes.json - -以太坊(eth或者geth)必须在允许rpc选项的情况下运行: - - geth --rpc - -在geth下,默认的rpc端口(如果没有指定的话)是8545 - -## 升级 - -要升级API客户端的话就要使用如下的命令: - - ~/bin/www/bin/update.sh - -这会停止当前的netstats客户端进程,自动检测你的以太坊的安装状态和版本,升级到最新的开发者版本,更新netstats客户端并重新载入进程。 - - diff --git "a/pages/other-languages/\320\240\321\203\320\272\320\276\320\262\320\276\320\264\321\201\321\202\320\262\320\276-\320\277\320\276-Solidity.md" "b/pages/other-languages/\320\240\321\203\320\272\320\276\320\262\320\276\320\264\321\201\321\202\320\262\320\276-\320\277\320\276-Solidity.md" deleted file mode 100644 index 1ab9395db..000000000 --- "a/pages/other-languages/\320\240\321\203\320\272\320\276\320\262\320\276\320\264\321\201\321\202\320\262\320\276-\320\277\320\276-Solidity.md" +++ /dev/null @@ -1,1256 +0,0 @@ -_исходный текст [Solidity Tutorial](https://ethereum.github.io/solidity/docs/home/), 05.10.2015_ -*** -Solidity - это высокоуровневый язык для виртуальной машины Ethereum с синтаксисом, похожим на JavaScript. Это учебное руководство обеспечивает основное введение в Solidity и предполагает некоторое знание Виртуальной машины Ethereum и программирования в целом. Оно не касается таких функций как [естественная спецификация языка](https://github.com/ethereum/wiki/wiki/Solidity-Tutorial/Ethereum-Natural-Specification-Format) или формальная верификация и не является заключительной спецификацией языка. - -Можно начать использовать [Solidity в браузере](http://chriseth.github.io/cpp-ethereum) без потребности загружать или компилировать что-либо. Это приложение только поддерживает компиляцию - если Вы хотите выполнить код или ввести его в блокчейн, необходимо использовать клиент, такой как например [Geth](https://github.com/ethereum/go-ethereum) или [AlethZero](https://github.com/ethereum/alethzero). - - -**Быстрые ссылки:** - -- [Шпаргалка](#cheatsheet) -- [Подсказки и Приемы](#tips-and-tricks) - -**Оглавление** - - -- [Некоторые примеры](#Некоторые-примеры) - - [Хранилище](#Хранилище) - - [Пример подвалюты](#Пример-подвалюты) -- [Разметка исходного файла Solidity](#Разметка-исходного-файла-solidity) -- [Структура контракта Solidity](#Структура-контракта-solidity) -- [Типы](#Типы) - - [Элементарные типы (типы значений)](#Элементарные-типы-типы-значений) - - [Операторы, включающие LValues](#Операторы-включающие-lvalue) - - [Преобразования между элементарными типами](#conversions-between-elementary-types) - - [Неявные преобразования](#implicit-conversions) - - [Явные преобразования](#explicit-conversions) - - [Тип возвращаемых значений](#type-deduction) - - [Функции на адресах](#functions-on-addresses) - - [Перечисления(Enums)](#enums) - - [Ссылочные типы](#reference-types) - - [Расположение данных](#data-location) - - [Массивы](#arrays) - - [Структуры](#structs) -- [Синтаксический сахар и глобально доступные переменные](#syntactic-sugar-and-globally-available-variables) - - [Эфир и единицы измерения времени](#ether-and-time-units) - - [Специальные переменные и функции](#special-variables-and-functions) - - [Блок и свойства транзакции](#block-and-transaction-properties) - - [Криптографические функции](#cryptographic-functions) - - [Касательно контракта](#contract-related) -- [Управляющие структуры](#control-structures) - - [Вызовы функции](#function-calls) - - [Внутренние вызовы функции](#internal-function-calls) - - [Внешние вызовы функции](#external-function-calls) - - [Названные и дополнительные параметры функции](#named-and-optional-function-parameters) - - [Порядок оценки выражений](#order-of-evaluation-of-expressions) - - [Присвоение](#assignment) - - [Исключения](#exceptions) -- [Договоры](#contracts) - - [Взаимодействие через интерфейс с другими контрактами](#interfacing-with-other-contracts) - - [Библиотеки](#libraries)_(todo)_ - - [Параметры конструктора](#constructor-arguments) - - [Наследование контракта](#contract-inheritance) - - [Параметры для конструкторов базового контракта](#arguments-for-base-constructors) - - [Множественное наследование и линеаризация](#multiple-inheritance-and-linearization) - - [Абстрактные контракты](#abstract-contracts) - - [Спецификаторы видимости](#visibility-specifiers) - - [Функции доступа](#accessor-functions) - - [Функции нейтрализации](#fallback-functions) - - [Функции модификаторов](#function-modifiers) - - [Контракты](#constants) - - [События](#events) - - [Дополнительные ресурсы для понимания событий:](#additional-resources-for-understanding-events) -- [Разное](#miscellaneous) - - [Разметка переменных состояния в хранилище](#layout-of-state-variables-in-storage) - - [Скрытые особенности](#esoteric-features) - - [Внутреннее - Оптимизатор](#internals-the-optimizer) - - [Использование компилятора командной строки](#using-the-commandline-compiler) - - [Подсказки и Приемы](#tips-and-tricks) - - [Ловушки](#pitfalls) - - [Шпаргалка](#cheatsheet) - - [Глобальные переменные](#global-variables) - - [Спецификаторы видимости для функции](#function-visibility-specifiers) - - [Модификаторы](#modifiers) - - [Типы](#types) - - -*** -# Некоторые примеры - -Давайте начнем с некоторых примеров. Позже мы рассмотрим все подробнее. - -## Хранилище - -```js -contract SimpleStorage { - uint storedData; - function set(uint x) { - storedData = x; - } - function get() constant returns (uint retVal) { - return storedData; - } -} -``` - -`uint storedData` объявляет переменную состояния, названную storedData типа uint (целое без знака 256 битов), чья позиция в хранилище автоматически решается компилятором. -Функции `set` и `get` используются для изменения и получения значения переменной. - -## Пример подвалюты - -```js -contract Coin { - address minter; - mapping (address => uint) balances; - - event Send(address from, address to, uint value); - - function Coin() { - minter = msg.sender; - } - function mint(address owner, uint amount) { - if (msg.sender != minter) return; - balances[owner] += amount; - } - function send(address receiver, uint amount) { - if (balances[msg.sender] < amount) return; - balances[msg.sender] -= amount; - balances[receiver] += amount; - Send(msg.sender, receiver, amount); - } - function queryBalance(address addr) constant returns (uint balance) { - return balances[addr]; - } -} -``` - -Настоящий контракт представляет некоторые новые понятия. Одно из них тип address-а, который является 160 битовым значением, не позволяющим арифметические операции. -Кроме того, тип переменной состояния `balances` отображает адреса на целие числа без знака. Отображения можно представить как хеш-таблицу виртуально инициализированную таким образом, чтобы каждый возможный ключ существовал и отображался в значении, байт-представление которого является нулями. Специальная функция `Coin` является конструктором, который выполняют во время создания контракта и её нельзя вызвать впоследствии. Она хранит адрес лица, создающего договор вместе с `tx` и `block`, `msg` является волшебной глобальной переменной, содержащей некоторые свойства, предоставляющие доступ к миру за пределами контракта. -Функция `queryBalance` объявлена как постоянная и таким образом не позволяется изменить состояние контракта(обратите внимание на то, что это не принудительно). -В Solidity возвращаемые параметры наименованы и по существу создают локальную переменную. Таким образом для возврата баланса мы могли бы просто использовать `balance = balances[addr];` без какого-либо `return`. Такие события, как `Send`, позволяют внешним клиентам искать в блокчейне более эффективно. -Если событие вызывается как в функция `Send`, этот факт будет сохранен и отображён в блокчейне, мы узнаем больше об этом позже. - -# Разметка исходного файла Solidity - -Исходный файл Solidity может содержать произвольное число контрактов. -На **другие исходные файлы** можно сослаться с помощью `import "filename";`, символы, определенные там, также будут доступны в текущем исходном файле. -Обратите внимание на то, что компилятор в браузере поддерживает не больше одного файла и если Вы используете компилятор командной строки, необходимо явно указать все файлы, которые Вы будете использовать в качестве параметров, компилятор не будет ничего искать в Вашей файловой системе самостоятельно. - -**Комментарии** однострочные комментарии (`//`) и многострочные комментарии (`/*...*/`)возможны, в то время как тройная наклонная черта (`///`) справа перед объявлениями функции производит комментарий -[NatSpec](Ethereum-Natural-Specification-Format) (Комментарии NatSepc не освещены здесь). - -# Структура контракта Solidity - -Контракты в Solidity - то же, что и классы в объектно-ориентированных языках. Они могут содержать так называемые переменные состояния, которые постоянно хранятся в хранилище вместе с контрактом и функциями, указателями входа для работы с этими переменными состояния. Кроме переменных состояния, существуют также локальные переменные, объявленные в функциях, содержание которых очищается как только поток управления возвращается из функции. - -# Типы - -Solidity является статически типизированным языком и это означает, что тип каждой переменной(состояния и локальных) должен быть указан(или по крайней мере известен - см. [Дедукция типа](#Дедукция-типа) ниже) во время компиляции. Solidity предоставляет несколько элементарных типов, которые могут быть объединены в составные типы. - -## Элементарные типы (типы значений) - -Следующие типы также называют типами значения, потому что переменные этих типов будут всегда передаваться по значению, т.е. они всегда копируются, когда они используются в качестве аргументов функции или в присвоениях. - -**Логический тип** -`bool`: Возможные значения константы `true`, `false` - -Операторы: -`!` (логическое отрицание) `&&` (логическая конъюнкция, "and"), `||` (логическая дизъюнкция, "or"), `==` (равенство) and `!=` (неравенство). Операторы `||` и `&&` применяют обычные правила short-circuiting. Это означает, что в выражении `f(x) || g(y)`, если `f(x)` оценивается как `true`, `g(y)` не будет рассмотрен даже если это может иметь побочные эффекты. - -**Числа** -`int•` / `uint•`: Целые числа со знаком и без знака различных размеров. Ключевые слова `uint8` до `uint256` с шагом `8` (Целые числа без знака с 8 до максимум 256 битов) и `int8` до `int256`. `uint` и `int` являются псевдонимами для `uint256` и `int256`, соответственно. - -Операторы: -Сравнения: `<=`, `<`, `==`, `!=`, `>=`, `>` (возвращают `bool`) -Битовые операции: `&`, `|`, `^` (Побитовое исключающее ИЛИ), `~` (Побитовое отрицание) -Арифметические операторы: `+`, `-`, унарный `-`, унарный `+`, `*`, `/`, `%` (Деление с остатком (деление по модулю) ), `**` (Возведение в степень) - -**Адресный тип** -`address`: Содержит 20 байтное значение (размер адреса Ethereum). Адресный тип также имеет члены(см. [Функции на адреса](#Функции-на-адреса)) и служит основой для всех контрактов. - -Операторы: -`<=`, `<`, `==`, `!=`, `>=` и `>`. - -**Массивы фиксированного размера** -`bytes1`, `bytes2`, `bytes3`, ..., `bytes32`: массивы фиксированного размера, `byte` является псевдонимом для `bytes1`. - -Операторы: -Сравнения: `<=`, `<`, `==`, `!=`, `>=`, `>` (возвращают `bool`) -Битовые операции: `&`, `|`, `^` (Побитовое исключающее ИЛИ), `~` (Побитовое отрицание) - -**Динамично измеряемые массивы** -`bytes`: динамично измеряемый массив, см. [Массивы](#массивы). Не является типом значения! -`string`: динамично измеряемая UTF8-кодированная строка, см. [Массивы](#массивы). Не является типом значения! - -**Целочисленные Литералы** -Целочисленные литералы являются целыми числами произвольной точности, пока они не используются вместе с не-литералом. В `var x = 1 - 2;`, например, `1 - 2` имеет занчение `-1`, которое присваивается `x` и таким образом `x` получает тип `int8` -- наименьший тип который может хранить `-1`, несмотря на то, что естественные типы `1` и `2` фактически `uint8`. -Возможно даже временно превысить максимум 256 битов до тех пор пока для вычисления используются целочисленные литералы: `var x = (0xffffffffffffffffffff * 0xffffffffffffffffffff) * 0;` Здесь, `x` будет иметь значение `0` и таким образом тип `uint8`. - -**Строковые Литералы** -Строковые литералы записываются с двойными кавычками(`"abc"`). Как с целочисленными литералами, тип может варьироваться, но они неявно конвертируемы в `bytes•` если помещаются, в `bytes` и в `string`. - -## Операторы, включающие LValue - -**Операторы инкремента/декремента** -Если `a` LValue (т.е. переменная или что-то, что может быть присвоено), следующие операторы доступны как сокращения: -`a += e` эквивалентен `a = a + e`. Операторы `-=`, `*=`, `/=`, `%=`, `a |=`, `&=` и `^=` определяются соответственно. `a++` и `a--` эквивалентны `a += 1` / `a -= 1`, но само выражение все еще имеет предыдущее значение `a`. Напротив, `--a` и `++a` имеют тот же эффект, но возвращяют значения после изменения. - -**delete** -`delete a` присваивает `a` начальное значения для типа. Т.е. для целых чисел это `a = 0`, но он также может использоваться в массивах, где он присваивает длине динамического массива `0`, а статическому - массив той же длины где элементы имеют начальные значения. Для структур он присваивает переменной структуру со сбрасыванием значений для всех элементов. - -`delete` не имеет никакого эффекта на соответствиях(mappings)(поскольку ключи соответствий могут быть произвольными и обычно неизвестны). Таким образом, при удалении структуры, значения всех элементов кроме соответствий будут сброшены(рекурсивно для членов кроме соодветсвий). Однако отдельные ключи и то на что они отображаются, могут быть удалены. - -Важно отметить, что `delete a`, в действительности ведет себя как присвоение на `a`, т.е. хранит новый объект в `a`. -```js -contract DeleteExample { - uint data; - uint[] dataArray; - function f() { - uint x = data; - delete x; // x = 0, не влияет на data - delete data; // data = 0, не влияет на x, каторая все еще содержит копию - uint[] y = dataArray; - delete dataArray; // обнуляет dataArray.length, но поскольку uint[] сложный объект, также - // затронут y, который является псевдонимом к объекту хронилища. - // С другой стороны: «delete y», не действительнo, так как присвоение локальным переменным - // ссылающимся на объекты хронилища может быть сделано только из существующих объектов хронилища. - } -} -``` - -## Conversions between Elementary Types - -### Implicit Conversions - -If an operator is applied to different types, the compiler tries to -implicitly convert one of the operands to the type of the other (the same is -true for assignments). In general, an implicit conversion between value-types -is possible if it -makes sense semantically and no information is lost: `uint8` is convertible to -`uint16` and `int128` to `int256`, but `int8` is not convertible to `uint256` -(because `uint256` cannot hold e.g. `-1`). -Furthermore, unsigned integers can be converted to bytes of the same or larger -size, but not vice-versa. Any type that can be converted to `uint160` can also -be converted to `address`. - -### Explicit Conversions - -If the compiler does not allow implicit conversion but you know what you are -doing, an explicit type conversion is sometimes possible: - -```js -int8 y = -3; -uint x = uint(y); -``` - -At the end of this code snippet, `x` will have the value `0xfffff..fd` (64 hex -characters), which is -3 in two's complement representation of 256 bits. - -If a type is explicitly converted to a smaller type, higher-order bits are -cut off: - -```js -uint32 a = 0x12345678; -uint16 b = uint16(a); // b will be 0x5678 now -``` - -### Type Deduction - -For convenience, it is not always necessary to explicitly specify the type of a -variable, the compiler automatically infers it from the type of the first -expression that is assigned to the variable: -```js -uint20 x = 0x123; -var y = x; -``` -Here, the type of `y` will be `uint20`. Using `var` is not possible for function -parameters or return parameters. - -Beware that currently, the type is only deduced from the first assignment, so -the loop in the following snippet is infinite, as `i` will have the type -`uint8` and any value of this type is smaller than `2000`. -```js -for (var i = 0; i < 2000; i++) -{ - // do something -} -``` - -## Functions on addresses - -It is possible to query the balance of an address using the property `balance` -and to send Ether (in units of wei) to an address using the `send` function: - -```js -address x = 0x123; -address myAddress = this; -if (x.balance < 10 && myAddress.balance >= 10) x.send(10); -``` - -Beware that if `x` is a contract address, its code (more specifically: its fallback function, if present) will be executed together with the `send` call (this is a limitation of the EVM and cannot be prevented). If that execution runs out of gas or fails in any way, the Ether transfer will be reverted. In this case, `send` returns `false`. - -Furthermore, to interface with contracts that do not adhere to the ABI (like the classic NameReg contract), -the function `call` is provided which takes an arbitrary number of arguments of any type. These arguments are ABI-serialized (i.e. also padded to 32 bytes). One exception is the case where the first argument is encoded to exactly four bytes. In this case, it is not padded to allow the use of function signatures here. - -```js -address nameReg = 0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2; -nameReg.call("register", "MyName"); -nameReg.call(bytes4(sha3("fun(uint256)")), a); -``` - -`call` returns a boolean indicating whether the invoked function terminated (`true`) or caused an EVM exception (`false`). It is not possible to access the actual data returned (for this we would need to know the encoding and size in advance). - -In a similar way, the function `callcode` can be used: The difference is that only the code of the given address is used, all other aspects (storage, balance, ...) are taken from the current contract. The purpose of `callcode` is to use library code which is stored in another contract. The user has to ensure that the layout of storage in both contracts is suitable for callcode to be used. - -Both `call` and `callcode` are very low-level functions and should only be used as a *last resort* as they break the type-safety of Solidity. - -Note that contracts inherit all members of address, so it is possible to query the balance of the -current contract using `this.balance`. - -## Enums - -Enums are one way to create a user-defined type in Solidity. They are explicitly convertible -to and from all integer types but implicit conversion is not allowed. - -```js -contract test { - enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill } - ActionChoices choice; - ActionChoices constant defaultChoice = ActionChoices.GoStraight; - function setGoStraight() - { - choice = ActionChoices.GoStraight; - } - // Since enum types are not part of the ABI, the signature of "getChoice" - // will automatically be changed to "getChoice() returns (uint8)" - // for all matters external to Solidity. The integer type used is just - // large enough to hold all enum values, i.e. if you have more values, - // `uint16` will be used and so on. - function getChoice() returns (ActionChoices) - { - return choice; - } - function getDefaultChoice() returns (uint) - { - return uint(defaultChoice); - } -} -``` - -## Reference Types - -Complex types, i.e. types which do not always fit into 256 bits have to be handled -more carefully than the value-types we have already seen. Since copying -them can be quite expensive, we have to think about whether we want them to be -stored in memory (which is not persisting) or storage (where the state -variables are held). - -### Data location - -Every complex type, i.e. *arrays* and *structs*, has an additional -annotation, the "data location", about whether it is stored in memory or in storage. Depending on the -context, there is always a default, but it can be overridden by appending -either `storage` or `memory` to the type. The default for function parameters (including return parameters) is `memory`, the default for local variables is `storage` and the location is forced -to `storage` for state variables (obviously). - -There is also a third data location, "calldata" which is a non-modifyable -non-persistent area whether function arguments are stored. Function parameters -(not return parameters) of external functions are forced to "calldata" and -it behaves mostly like memory. - -Data locations are important because they change how assignments behave: -Assignments between storage and memory and also to a state variable (even from other state variables) -always create an independent copy. -Assignments to local storage variables only assign a reference though, and -this reference always points to the state variable even if the latter is changed -in the meantime. -On the other hand, assignments from a memory stored reference type to another -memory-stored reference type does not create a copy. - -```js -contract c { - uint[] x; // the data location of x is storage - // the data location of memoryArray is memory - function f(uint[] memoryArray) { - x = memoryArray; // works, copies the whole array to storage - var y = x; // works, assigns a pointer, data location of y is storage - y[7]; // fine, returns the 8th element - y.length = 2; // fine, modifies x through y - delete x; // fine, clears the array, also modifies y - // The following does not work; it would need to create a new temporary / - // unnamed array in storage, but storage is "statically" allocated: - // y = memoryArray; - // This does not work either, since it would "reset" the pointer, but there - // is no sensible location it could point to. - // delete y; - g(x); // calls g, handing over a reference to x - h(x); // calls h and creates an independent, temporary copy in memory - } - function g(uint[] storage storageArray) internal {} - function h(uint[] memoryArray) {} -} -``` - -**Summary:** - -Forced data location: - - parameters (not return) of external functions: calldata - - state variables: storage - -Default data location: - - parameters (also return) of functions: memory - - all other local variables: storage - -### Arrays - -Arrays can have a compile-time fixed size or they can be dynamic. -For storage arrays, the element type can be arbitrary (i.e. also other -arrays, mappings or structs). For memory arrays, it cannot be a mapping and -has to be an ABI type if it is an argument of a publicly-visible function. - -An array of fixed size `k` and element type `T` is written as `T[k]`, -an array of dynamic size as `T[]`. As an example, an array of 5 dynamic -arrays of `uint` is `uint[][5]` (note that the notation is reversed when -compared to some other languages). To access the second uint in the -third dynamic array, you use `x[2][1]` (indices are zero-based and -access works in the opposite way of the declaration, i.e. `x[2]` -shaves off one level in the type from the right). - -Arrays have a `length` member to hold their number of elements. -Dynamic arrays can be resized in storage (not in memory) by changing the -`.length` member. This does not happen automatically when attempting to access elements outside the current length. The size of memory arrays is fixed (but dynamic, i.e. it can depend on runtime parameters) once they are created. - -Variables of type `bytes` and `string` are special arrays. A `bytes` is similar to `byte[]`, -but it is packed tightly in calldata. `string` is equal to `bytes` but does not allow -length or index access (for now). - -```js -contract ArrayContract { - uint[2**20] m_aLotOfIntegers; - // Note that the following is not a pair of arrays but an array of pairs. - bool[2][] m_pairsOfFlags; - // newPairs is stored in memory - the default for function arguments - function setAllFlagPairs(bool[2][] newPairs) { - // assignment to a storage array replaces the complete array - m_pairsOfFlags = newPairs; - } - function setFlagPair(uint index, bool flagA, bool flagB) { - // access to a non-existing index will throw an exception - m_pairsOfFlags[index][0] = flagA; - m_pairsOfFlags[index][1] = flagB; - } - function changeFlagArraySize(uint newSize) { - // if the new size is smaller, removed array elements will be cleared - m_pairsOfFlags.length = newSize; - } - function clear() { - // these clear the arrays completely - delete m_pairsOfFlags; - delete m_aLotOfIntegers; - // identical effect here - m_pairsOfFlags.length = 0; - } - bytes m_byteData; - function byteArrays(bytes data) { - // byte arrays ("bytes") are different as they are stored without padding, - // but can be treated identical to "uint8[]" - m_byteData = data; - m_byteData.length += 7; - m_byteData[3] = 8; - delete m_byteData[2]; - } -} -``` - -### Structs - -Solidity provides a way to define new types in the form of structs, which is -shown in the following example: - -```js -contract CrowdFunding { - // Defines a new type with two fields. - struct Funder { - address addr; - uint amount; - } - struct Campaign { - address beneficiary; - uint fundingGoal; - uint numFunders; - uint amount; - mapping (uint => Funder) funders; - } - uint numCampaigns; - mapping (uint => Campaign) campaigns; - function newCampaign(address beneficiary, uint goal) returns (uint campaignID) { - campaignID = numCampaigns++; // campaignID is return variable - // Creates new struct and saves in storage. We leave out the mapping type. - campaigns[campaignID] = Campaign(beneficiary, goal, 0, 0); - } - function contribute(uint campaignID) { - Campaign c = campaigns[campaignID]; - // Creates a new temporary memory struct, initialised with the given values - // and copies it over to storage. - // Note that you can also use Funder(msg.sender, msg.value) to initialise. - c.funders[c.numFunders++] = Funder({addr: msg.sender, amount: msg.value}); - c.amount += msg.value; - } - function checkGoalReached(uint campaignID) returns (bool reached) { - Campaign c = campaigns[campaignID]; - if (c.amount < c.fundingGoal) - return false; - c.beneficiary.send(c.amount); - c.amount = 0; - return true; - } -} -``` - -The contract does not provide the full functionality of a crowdfunding -contract, but it contains the basic concepts necessary to understand structs. -Struct types can be used inside mappings and arrays and they can itself -contain mappings and arrays. - -It is not possible for a struct to contain a member of its own type, -although the struct itself can be the value type of a mapping member. -This restriction is necessary, as the size of the struct has to be finite. - -Note how in all the functions, a struct type is assigned to a local variable -(of the default storage data location). -This does not copy the struct but only stores a reference so that assignments to -members of the local variable actually write to the state. - -Of course, you can also directly access the members of the struct without -assigning it to a local variable, as in -`campaigns[campaignID].amount = 0`. - -# Syntactic Sugar and Globally Available Variables - -## Ether and Time Units - -A literal number can take a suffix of `wei`, `finney`, `szabo` or `ether` to convert between the subdenominations of ether, where Ether currency numbers without a postfix are assumed to be "wei", e.g. `2 ether == 2000 finney` evaluates to `true`. - -Furthermore, suffixes of `seconds`, `minutes`, `hours`, `days`, `weeks` and `years` can be used to convert between units of time where seconds are the base unit and units are converted naively (i.e. a year is always exactly 365 days, etc.). - -## Special Variables and Functions - -There are special variables and functions which always exist in the global -namespace and are mainly used to provide information about the blockchain. - -### Block and Transaction Properties - - - `block.coinbase` (`address`): current block miner's address - - `block.difficulty` (`uint`): current block difficulty - - `block.gaslimit` (`uint`): current block gaslimit - - `block.number` (`uint`): current block number - - `block.blockhash` (`function(uint) returns (bytes32)`): hash of the given block - - `block.timestamp` (`uint`): current block timestamp - - `msg.data` (`bytes`): complete calldata - - `msg.gas` (`uint`): remaining gas - - `msg.sender` (`address`): sender of the message (current call) - - `msg.sig` (`bytes4`): first four bytes of the calldata (i.e. function identifier) - - `msg.value` (`uint`): number of wei sent with the message - - `now` (`uint`): current block timestamp (alias for `block.timestamp`) - - `tx.gasprice` (`uint`): gas price of the transaction - - `tx.origin` (`address`): sender of the transaction (full call chain) - -### Cryptographic Functions - - - `sha3(...) returns (bytes32)`: compute the Ethereum-SHA-3 hash of the (tightly packed) arguments - - `sha256(...) returns (bytes32)`: compute the SHA-256 hash of the (tightly packed) arguments - - `ripemd160(...) returns (bytes20)`: compute RIPEMD-160 hash of the (tightly packed) arguments - - `ecrecover(bytes32, byte, bytes32, bytes32) returns (address)`: recover public key from elliptic curve signature - arguments are (data, v, r, s) - -In the above, "tightly packed" means that the arguments are concatenated without padding, i.e. -`sha3("ab", "c") == sha3("abc") == sha3(0x616263) == sha3(6382179) = sha3(97, 98, 99)`. If padding is needed, explicit type conversions can be used. - -It might be that you run into Out-of-Gas for `sha256`, `ripemd160` or `ecrecover` on a *private blockchain*. The reason for this is that those are implemented as so-called precompiled contracts and these contracts only really exist after they received the first message (although their contract code is hardcoded). Messages to non-existing contracts are more expensive and thus the execution runs into an Out-of-Gas error. A workaround for this problem is to first send e.g. 1 Wei to each of the contracts before you use them in your actual contracts. This is not an issue on the official or test net. - -### Contract Related - - - `this` (current contract's type): the current contract, explicitly convertible to `address` - - `suicide(address)`: suicide the current contract, sending its funds to the given address - -Furthermore, all functions of the current contract are callable directly including the current function. - -# Control Structures - -Most of the control structures from C/JavaScript are available in Solidity -except for `switch` and `goto`. So -there is: `if`, `else`, `while`, `for`, `break`, `continue`, `return`, with -the usual semantics known from C / JavaScript. - -Parentheses can *not* be omitted for conditionals, but curly brances can be omitted -around single-statement bodies. - -Note that there is no type conversion from non-boolean to boolean types as -there is in C and JavaScript, so `if (1) { ... }` is _not_ valid Solidity. - -## Function Calls - -### Internal Function Calls - -Functions of the current contract can be called directly ("internally"), also recursively, as seen in -this nonsensical example: - -```js -contract c { - function g(uint a) returns (uint ret) { return f(); } - function f() returns (uint ret) { return g(7) + f(); } -} -``` - -These function calls are translated into simple jumps inside the EVM. This has -the effect that the current memory is not cleared, i.e. passing memory references -to internally-called functions is very efficient. Only functions of the same -contract can be called internally. - -### External Function Calls - -The expression `this.g(8);` is also a valid function call, but this time, the function -will be called "externally", via a message call and not directly via jumps. -Functions of other contracts have to be called externally. For an external call, -all function arguments have to be copied to memory. - -When calling functions -of other contracts, the amount of Wei sent with the call and the gas can be specified: -```js -contract InfoFeed { - function info() returns (uint ret) { return 42; } -} -contract Consumer { - InfoFeed feed; - function setFeed(address addr) { feed = InfoFeed(addr); } - function callFeed() { feed.info.value(10).gas(800)(); } -} -``` -Note that the expression `InfoFeed(addr)` performs an explicit type conversion stating -that "we know that the type of the contract at the given address is `InfoFeed`" and -this does not execute a constructor. We could also have used `function setFeed(InfoFeed _feed) { feed = _feed; }` directly. Be careful about the fact that `feed.info.value(10).gas(800)` -only (locally) sets the value and amount of gas sent with the function call and only the -parentheses at the end perform the actual call. - -### Named Calls and Anonymous Function Parameters - -Function call arguments can also be given by name, in any order, and the names -of unused parameters (especially return parameters) can be omitted. - -```js -contract c { - function f(uint key, uint value) { ... } - function g() { - // named arguments - f({value: 2, key: 3}); - } - // omitted parameters - function func(uint k, uint) returns(uint) { - return k; - } -} -``` - -## Order of Evaluation of Expressions - -The evaluation order of expressions is not specified (more formally, the order -in which the children of one node in the expression tree are evaluated is not -specified, but they are of course evaluated before the node itself). It is only -guaranteed that statements are executed in order and short-circuiting for -boolean expressions is done. - -## Assignment - -The semantics of assignment are a bit more complicated for non-value types like arrays and structs. -Assigning *to* a state variable always creates an independent copy. On the other hand, assigning to a local variable creates an independent copy only for elementary types, i.e. static types that fit into 32 bytes. If structs or arrays (including `bytes` and `string`) are assigned from a state variable to a local variable, the local variable holds a reference to the original state variable. A second assignment to the local variable does not modify the state but only changes the reference. Assignments to members (or elements) of the local variable *do* change the state. - -## Exceptions - -There are some cases where exceptions are thrown automatically (see below). You can use the `throw` instruction to throw an exception manually. The effect of an exception is that the currently executing call is stopped and reverted (i.e. all changes to the state and balances are undone) and the exception is also "bubbled up" through Solidity function calls (exceptions are `send` and the low-level functions `call` and `callcode`, those return `false` in case of an exception). - -Catching exceptions is not yet possible. - -In the following example, we show how `throw` can be used to easily revert an Ether transfer and also how to check the return value of `send`: -``` -contract Sharer { - function sendHalf(address addr) returns (uint balance) { - if (!addr.send(msg.value/2)) - throw; // also reverts the transfer to Sharer - return this.balance; - } -} -``` - -Currently, there are two situations, where exceptions happen automatically in Solidity: - -1. If you access an array beyond its length (i.e. `x[i]` where `i >= x.length`) -2. If a function called via a message call does not finish properly (i.e. it runs out of gas or throws an exception itself). - -Internally, Solidity performs an "invalid jump" when an exception is thrown and thus causes the EVM to revert all changes made to the state. The reason for this is that there is no safe way to continue execution, because an expected effect did not occur. Because we want to retain the atomicity of transactions, the safest thing to do is to revert all changes and make the whole transaction (or at least call) without effect. - -# Contracts - -## Interfacing with other Contracts - -There are two ways to interface with other contracts: Either call a method of a contract whose address is known or create a new contract. Both uses are shown in the example below. Note that (obviously) the source code of a contract to be created needs to be known, which means that it has to come before the contract that creates it (and cyclic dependencies are not possible since the bytecode of the new contract is actually contained in the bytecode of the creating contract). - -```js -contract OwnedToken { - // TokenCreator is a contract type that is defined below. It is fine to reference it - // as long as it is not used to create a new contract. - TokenCreator creator; - address owner; - bytes32 name; - function OwnedToken(bytes32 _name) { - address nameReg = 0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2; - nameReg.call("register", _name); // This is an unsafe raw call to another contract. - owner = msg.sender; - // We do an explicit type conversion from `address` to `TokenCreator` and assume that the type of - // the calling contract is TokenCreator, there is no real way to check. - creator = TokenCreator(msg.sender); - name = _name; - } - function changeName(bytes32 newName) { - // Only the creator can alter the name -- contracts are implicitly convertible to addresses. - if (msg.sender == creator) name = newName; - } - function transfer(address newOwner) { - // Only the current owner can transfer the token. - if (msg.sender != owner) return; - // We also want to ask the creator if the transfer is fine. - // Note that this calls a function of the contract defined below. - // If the call fails (e.g. due to out-of-gas), the execution here stops - // immediately (the ability to catch this will be added later). - if (creator.isTokenTransferOK(owner, newOwner)) - owner = newOwner; - } -} -contract TokenCreator { - function createToken(bytes32 name) returns (OwnedToken tokenAddress) { - // Create a new Token contract and return its address. - // From the JavaScript side, the return type is simply "address", as this is the closest - // type available in the ABI. - // To get the address, this can only be called by another contract (not eth_call). - return new OwnedToken(name); - } - function changeName(OwnedToken tokenAddress, bytes32 name) { - // Again, the external type of "tokenAddress" is simply "address". - tokenAddress.changeName(name); - } - function isTokenTransferOK(address currentOwner, address newOwner) returns (bool ok) { - // Check some arbitrary condition. - address tokenAddress = msg.sender; - return (sha3(newOwner) & 0xff) == (bytes20(tokenAddress) & 0xff); - } -} -``` - -## Libraries - -Libraries are similar to contracts, but their purpose is that they are deployed only once at a specific address and their code is reused using the `CALLCODE` feature of the EVM. This means that if library functions are called, their code is executed in the context of the calling contract, i.e. `this` points to the calling contract and especially the storage from the calling contract can be accessed (this is not yet possible from solidity). - -The following example illustrates how to use libraries. Note that the library given below is not a good example for a library, since the benefits of a library in terms of saving gas for code deployment are only visible starting from a certain size. -``` -library Math { - function max(uint a, uint b) returns (uint) { - if (a > b) return a; - else return b; - } - function min(uint a, uint b) returns (uint) { - if (a < b) return a; - else return b; - } -} -contract C { - function register(uint value) { - // The library functions can be called without a specific instance of the library, - // since the "instance" will be the current contract. - value = Math.max(10, Math.min(100, value)); // clamp value to [10, 100] - // ... - } -} -``` - -The calls to `Math.max` and `Math.min` are both compiled as calls (`CALLCODE`s) to an external contract. If you use libraries, take care that an actual external function call is performed, so `msg.sender` does not point to the original sender anymore but to the the calling contract and also `msg.value` contains the funds sent during the call to the library function. - -As the compiler cannot know where the library will be deployed at, these addresses have to be filled into the final bytecode by a linker (see [Using the Commandline Compiler](#using-the-commandline-compiler) on how to use the commandline compiler for linking). If the addresses are not given as arguments to the compiler, the compiled hex code will contain placeholders of the form `__Math______` (where `Math` is the name of the library). The address can be filled manually by replacing all those 40 symbols by the hex encoding of the address of the library contract. - -Restrictions for libraries in comparison to contracts: - - - no state variables - - cannot inherit nor be inherited - -(these might be lifted at a later point) - -## Constructor Arguments - -A Solidity contract expects constructor arguments after the end of the contract data itself. -This means that you pass the arguments to a contract by putting them after the -compiled bytes as returned by the compiler in the usual ABI format. - -If you use web3.js's `MyContract.new()`, you do not have to care about this, though. - -## Contract Inheritance - -Solidity supports multiple inheritance by copying code including polymorphism. -Details are given in the following example. - -```js -contract owned { - function owned() { owner = msg.sender; } - address owner; -} - -// Use "is" to derive from another contract. Derived contracts can access all non-private members -// including internal functions and state variables. These cannot be accessed externally via -// `this`, though. -contract mortal is owned { - function kill() { if (msg.sender == owner) suicide(owner); } -} - -// These are only provided to make the interface known to the compiler. -// Note the bodiless functions. If a contract does not implement all functions -// it can only be used as an interface. -contract Config { function lookup(uint id) returns (address adr); } -contract NameReg { function register(bytes32 name); function unregister(); } - -// Multiple inheritance is possible. Note that "owned" is also a base class of -// "mortal", yet there is only a single instance of "owned" (as for virtual -// inheritance in C++). -contract named is owned, mortal { - function named(bytes32 name) { - address ConfigAddress = 0xd5f9d8d94886e70b06e474c3fb14fd43e2f23970; - NameReg(Config(ConfigAddress).lookup(1)).register(name); - } - -// Functions can be overridden, both local and message-based function calls take -// these overrides into account. - function kill() { - if (msg.sender == owner) { - address ConfigAddress = 0xd5f9d8d94886e70b06e474c3fb14fd43e2f23970; - NameReg(Config(ConfigAddress).lookup(1)).unregister(); -// It is still possible to call a specific overridden function. - mortal.kill(); - } - } -} - -// If a constructor takes an argument, it needs to be provided in the header (or modifier-invocation-style at the constructor of the derived contract (see below)). -contract PriceFeed is owned, mortal, named("GoldFeed") { - function updateInfo(uint newInfo) { - if (msg.sender == owner) info = newInfo; - } - - function get() constant returns(uint r) { return info; } - - uint info; -} -``` - -Note that above, we call `mortal.kill()` to "forward" the destruction request. The way this is done -is problematic, as seen in the following example: -```js -contract mortal is owned { - function kill() { if (msg.sender == owner) suicide(owner); } -} -contract Base1 is mortal { - function kill() { /* do cleanup 1 */ mortal.kill(); } -} -contract Base2 is mortal { - function kill() { /* do cleanup 2 */ mortal.kill(); } -} -contract Final is Base1, Base2 { -} -``` - -A call to `Final.kill()` will call `Base2.kill` as the most derived override, but this -function will bypass `Base1.kill`, basically because it does not even know about `Base1`. -The way around this is to use `super`: -```js -contract mortal is owned { - function kill() { if (msg.sender == owner) suicide(owner); } -} -contract Base1 is mortal { - function kill() { /* do cleanup 1 */ super.kill(); } -} -contract Base2 is mortal { - function kill() { /* do cleanup 2 */ super.kill(); } -} -contract Final is Base2, Base1 { -} -``` - -If `Base1` calls a function of `super`, it does not simply call this function on one of its -base contracts, it rather calls this function on the next base contract in the final -inheritance graph, so it will call `Base2.kill()` (note that the final inheritance sequence is --- starting with the most derived contract: Final, Base1, Base2, mortal, owned). Note that the actual function that -is called when using super is not known in the context of the class where it is used, -although its type is known. This is similar for ordinary virtual method lookup. - -### Arguments for Base Constructors - -Derived contracts need to provide all arguments needed for the base constructors. This can be done at two places: - -```js -contract Base { - uint x; - function Base(uint _x) { x = _x; } -} -contract Derived is Base(7) { - function Derived(uint _y) Base(_y * _y) { - } -} -``` - -Either directly in the inheritance list (`is Base(7)`) or in the way a modifier would be invoked as part of the header of the derived constructor (`Base(_y * _y)`). The first way to do it is more convenient if the constructor argument is a constant and defines the behaviour of the contract or describes it. The second way has to be used if the constructor arguments of the base depend on those of the derived contract. If, as in this silly example, both places are used, the modifier-style argument takes precedence. - - -### Multiple Inheritance and Linearization - -Languages that allow multiple inheritance have to deal with several problems, one of them being the [Diamond Problem](https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem). Solidity follows the path of Python and uses "[C3 Linearization](https://en.wikipedia.org/wiki/C3_linearization)" to force a specific order in the DAG of base classes. This results in the desirable property of monotonicity but disallows some inheritance graphs. Especially, the order in which the base classes are given in the `is` directive is important. In the following code, Solidity will give the error "Linearization of inheritance graph impossible". -```js -contract X {} -contract A is X {} -contract C is A, X {} -``` -The reason for this is that `C` requests `X` to override `A` (by specifying `A, X` in this order), but `A` itself requests to override `X`, which is a contradiction that cannot be resolved. - -A simple rule to remember is to specify the base classes in the order from "most base-like" to "most derived". - -## Abstract Contracts - -Contract functions can lack an implementation as in the following example (note that the function declaration header is terminated by `;`). -```js -contract feline { - function utterance() returns (bytes32); -} -``` -Such contracts cannot be compiled (even if they contain implemented functions alongside non-implemented functions), but they can be used as base contracts: -```js -contract Cat is feline { - function utterance() returns (bytes32) { return "miaow"; } -} -``` -If a contract inherits from an abstract contract and does not implement all non-implemented functions by overriding, it will itself be abstract. - -## Visibility Specifiers - -Functions and state variables can be specified as being `public`, `internal` or `private`, where the default for functions is `public` and `internal` for state variables. In addition, functions can also be specified as `external`. - -`external`: External functions are part of the contract interface and they can be called from other contracts and via transactions. An external function `f` cannot be called internally (i.e. `f()` does not work, but `this.f()` works). Furthermore, all function parameters are immutable. - -`public`: Public functions are part of the contract interface and can be either called internally or via messages. For public state variables, an automatic accessor function (see below) is generated. - -`internal`: Those functions and state variables can only be accessed internally, i.e. from within the current contract or contracts deriving from it without using `this`. - -`private`: Private functions and state variables are only visible for the contract they are defined in and not in derived contracts. - -```js -contract c { - function f(uint a) private returns (uint b) { return a + 1; } - function setData(uint a) internal { data = a; } - uint public data; -} -``` - -Other contracts can call `c.data()` to retrieve the value of data in state storage, but are not able to call `f`. Contracts derived from `c` can call `setData` to alter the value of `data` (but only in their own state). - -## Accessor Functions - -The compiler automatically creates accessor functions for all public state variables. The contract given below will have a function called `data` that does not take any arguments and returns a uint, the value of the state variable `data`. The initialization of state variables can be done at declaration. - -```js -contract test { - uint public data = 42; -} -``` - -The next example is a bit more complex: - -```js -contract complex { - struct Data { uint a; bytes3 b; mapping(uint => uint) map; } - mapping(uint => mapping(bool => Data[])) public data; -} -``` - -It will generate a function of the following form: -```js -function data(uint arg1, bool arg2, uint arg3) returns (uint a, bytes3 b) -{ - a = data[arg1][arg2][arg3].a; - b = data[arg1][arg2][arg3].b; -} -``` - -Note that the mapping in the struct is omitted because there is no good way to provide the key for the mapping. - -## Fallback Functions - -A contract can have exactly one unnamed -function. This function cannot have arguments and is executed on a call to the contract if -none of the other functions matches the given function identifier (or if no data was supplied at all). - -```js -contract Test { - function() { x = 1; } - uint x; -} - -contract Caller { - function callTest(address testAddress) { - Test(testAddress).call(0xabcdef01); // hash does not exist - // results in Test(testAddress).x becoming == 1. - } -} -``` - -## Function Modifiers - -Modifiers can be used to easily change the behaviour of functions, for example to automatically check a condition prior to executing the function. They are inheritable properties of contracts and may be overridden by derived contracts. - -```js -contract owned { - function owned() { owner = msg.sender; } - address owner; - - // This contract only defines a modifier but does not use it - it will - // be used in derived contracts. - // The function body is inserted where the special symbol "_" in the - // definition of a modifier appears. - modifier onlyowner { if (msg.sender == owner) _ } -} -contract mortal is owned { - // This contract inherits the "onlyowner"-modifier from "owned" and - // applies it to the "kill"-function, which causes that calls to "kill" - // only have an effect if they are made by the stored owner. - function kill() onlyowner { - suicide(owner); - } -} -contract priced { - // Modifiers can receive arguments: - modifier costs(uint price) { if (msg.value >= price) _ } -} -contract Register is priced, owned { - mapping (address => bool) registeredAddresses; - uint price; - function Register(uint initialPrice) { price = initialPrice; } - function register() costs(price) { - registeredAddresses[msg.sender] = true; - } - function changePrice(uint _price) onlyowner { - price = _price; - } -} -``` - -Multiple modifiers can be applied to a function by specifying them in a whitespace-separated list and will be evaluated in order. Explicit returns from a modifier or function body immediately leave the whole function, while control flow reaching the end of a function or modifier body continues after the "_" in the preceding modifier. Arbitrary expressions are allowed for modifier arguments and in this context, all symbols visible from the function are visible in the modifier. Symbols introduced in the modifier are not visible in the function (as they might change by overriding). - -## Constants - -State variables of value type can be declared as constant. -```js -contract C { - uint constant x = 32; - bytes3 constant text = "abc"; -} -``` - -This has the effect that the compiler does not reserve a storage slot -for these variables and every occurrence is replaced by their constant value. - -## Events - -Events allow the convenient usage of the EVM logging facilities. Events are inheritable members of contracts. When they are called, they cause the arguments to be stored in the transaction's log. Up to three parameters can receive the attribute `indexed` which will cause the respective arguments to be treated as log topics instead of data. The hash of the signature of the event is one of the topics except if you declared the event with `anonymous` specifier. All non-indexed arguments will be stored in the data part of the log. Example: - -```js -contract ClientReceipt { - event Deposit(address indexed _from, bytes32 indexed _id, uint _value); - function deposit(bytes32 _id) { - Deposit(msg.sender, _id, msg.value); - } -} -``` -Here, the call to `Deposit` will behave identical to -`log3(msg.value, 0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20, sha3(msg.sender), _id);`. Note that the large hex number is equal to the sha3-hash of "Deposit(address,bytes32,uint256)", the event's signature. - -### Additional Resources for Understanding Events: - -- Javascript documentation: -- Example usage of events: -- How to access them in js: - -# Miscellaneous - -## Layout of State Variables in Storage - -Statically-sized variables (everything except mapping and dynamically-sized array types) are laid out contiguously in storage starting from position `0`. Multiple items that need less than 32 bytes are packed into a single storage slot if possible, according to the following rules: - -- The first item in a storage slot is stored lower-order aligned. -- Elementary types use only that many bytes that are necessary to store them. -- If an elementary type does not fit the remaining part of a storage slot, it is moved to the next storage slot. -- Structs and array data always start a new slot and occupy whole slots (but items inside a struct or array are packed tightly according to these rules). - -The elements of structs and arrays are stored after each other, just as if they were given explicitly. - -Due to their unpredictable size, mapping and dynamically-sized array types use a `sha3` -computation to find the starting position of the value or the array data. These starting positions are always full stack slots. - -The mapping or the dynamic array itself -occupies an (unfilled) slot in storage at some position `p` according to the above rule (or by -recursively applying this rule for mappings to mappings or arrays of arrays). For a dynamic array, this slot stores the number of elements in the array (byte arrays and strings are an exception here, see below). For a mapping, the slot is unused (but it is needed so that two equal mappings after each other will use a different hash distribution). -Array data is located at `sha3(p)` and the value corresponding to a mapping key -`k` is located at `sha3(k . p)` where `.` is concatenation. If the value is again a -non-elementary type, the positions are found by adding an offset of `sha3(k . p)`. - -`bytes` and `string` store their data in the same slot where also the length is stored if they are short. In particular: If the data is at most `31` bytes long, it is stored in the higher-order bytes (left aligned) and the lowest-order byte stores `length * 2`. If it is longer, the main slot stores `length * 2 + 1` and the data is stored as usual in `sha3(slot)`. - -So for the following contract snippet: -```js -contract c { - struct S { uint a; uint b; } - uint x; - mapping(uint => mapping(uint => S)) data; -} -``` -The position of `data[4][9].b` is at `sha3(uint256(9) . sha3(uint256(4) . uint(256(1))) + 1`. - -## Esoteric Features - -There are some types in Solidity's type system that have no counterpart in the syntax. One of these types are the types of functions. But still, using `var` it is possible to have local variables of these types: - -```js -contract FunctionSelector { - function select(bool useB, uint x) returns (uint z) { - var f = a; - if (useB) f = b; - return f(x); - } - function a(uint x) returns (uint z) { - return x * x; - } - function b(uint x) returns (uint z) { - return 2 * x; - } -} -``` - -Calling `select(false, x)` will compute `x * x` and `select(true, x)` will compute `2 * x`. - - -## Internals - the Optimizer - -The Solidity optimizer operates on assembly, so it can be and also is used by other languages. It splits the sequence of instructions into basic blocks at JUMPs and JUMPDESTs. Inside these blocks, the instructions are analysed and every modification to the stack, to memory or storage is recorded as an expression which consists of an instruction and a list of arguments which are essentially pointers to other expressions. The main idea is now to find expressions that are always equal (on every input) and combine them into an expression class. The optimizer first tries to find each new expression in a list of already known expressions. If this does not work, the expression is simplified according to rules like `constant` + `constant` = `sum_of_constants` or `X` * 1 = `X`. Since this is done recursively, we can also apply the latter rule if the second factor is a more complex expression where we know that it will always evaluate to one. Modifications to storage and memory locations have to erase knowledge about storage and memory locations which are not known to be different: If we first write to location x and then to location y and both are input variables, the second could overwrite the first, so we actually do not know what is stored at x after we wrote to y. On the other hand, if a simplification of the expression x - y evaluates to a non-zero constant, we know that we can keep our knowledge about what is stored at x. - -At the end of this process, we know which expressions have to be on the stack in the end and have a list of modifications to memory and storage. This information is stored together with the basic blocks and is used to link them. Furthermore, knowledge about the stack, storage and memory configuration is forwarded to the next block(s). If we know the targets of all JUMP and JUMPI instructions, we can build a complete control flow graph of the program. If there is only one target we do not know (this can happen as in principle, jump targets can be computed from inputs), we have to erase all knowledge about the input state of a block as it can be the target of the unknown JUMP. If a JUMPI is found whose condition evaluates to a constant, it is transformed to an unconditional jump. - -As the last step, the code in each block is completely re-generated. A dependency graph is created from the expressions on the stack at the end of the block and every operation that is not part of this graph is essentially dropped. Now code is generated that applies the modifications to memory and storage in the order they were made in the original code (dropping modifications which were found not to be needed) and finally, generates all values that are required to be on the stack in the correct place. - -These steps are applied to each basic block and the newly generated code is used as replacement if it is smaller. If a basic block is split at a JUMPI and during the analysis, the condition evaluates to a constant, the JUMPI is replaced depending on the value of the constant, and thus code like -```js -var x = 7; -data[7] = 9; -if (data[x] != x + 2) - return 2; -else - return 1; -``` -is simplified to code which can also be compiled from -```js -data[7] = 9; -return 1; -``` -even though the instructions contained a jump in the beginning. - -## Using the Commandline Compiler - -One of the build targets of the Solidity repository is `solc`, the solidity commandline compiler. -Using `solc --help` provides you with an explanation of all options. The compiler can produce various outputs, ranging from simple binaries and assembly over an abstract syntax tree (parse tree) to estimations of gas usage. -If you only want to compile a single file, you run it as `solc --bin sourceFile.sol` and it will print the binary. Before you deploy your contract, activate the optimizer while compiling using `solc --optimize --bin sourceFile.sol`. If you want to get some of the more advanced output variants of `solc`, it is probably better to tell it to output everything to separate files using `solc -o outputDirectory --bin --ast --asm sourceFile.sol`. - -Of course, you can also specify several source files and actually that is also required if you use the `import` statement in Solidity: The compiler will (for now) not automatically discover source files for you, so you have to provide it with all source files your project consists of. - -If your contracts use [libraries](#libraries), you will notice that the bytecode contains substrings of the form `__LibraryName______`. You can use `solc` as a linker meaning that it will insert the library addresses for you at those points: - -Either add `--libraries "Math:0x12345678901234567890 Heap:0xabcdef0123456" to your command to provide an address for each library or store the string in a file (one library per line) and run `solc` using `--libraries fileName`. - -If `solc` is called with the option `--link`, all input files are interpreted to be unlinked binaries (hex-encoded) in the `__LibraryName____`-format given above and are linked in-place (if the input is read from stdin, it is written to stdout). All options except `--libraries` are ignored (including `-o`) in this case. - -## Tips and Tricks - - * Use `delete` on arrays to delete all its elements. - * Use shorter types for struct elements and sort them such that short types are grouped together. This can lower the gas costs as multiple SSTORE operations might be combined into a single (SSTORE costs 5000 or 20000 gas, so this is what you want to optimise). Use the gas price estimator (with optimiser enabled) to check! - * Make your state variables public - the compiler will create [getters](#accessor-functions) for you for free. - * If you end up checking conditions on input or state a lot at the beginning of your functions, try using [modifiers](#function-modifiers) - * If your contract has a function called `send` but you want to use the built-in send-function, use `address(contractVariable).send(amount)`. - * If you want your contracts to receive ether when called via `send`, you have to implement the [fallback function](#fallback-functions). - * Initialise storage structs with a single assignment: `x = MyStruct({a: 1, b: 2});` - -## Pitfalls - -Unfortunately, there are some subtleties the compiler does not yet warn you about. - - - If you use `StructName x` or `uint[] x` as a local variable, it **has** to be assigned from a state variable, - otherwise it behaves like a "null pointer" to storage, so you cannot use it on its own. - Please read about [data locations](#data-location). The most common solution is to use `StructName memory x` or `uint[] memory x`. - - In `for (var i = 0; i < arrayName.length; i++) { ... }`, the type of `i` will be `uint8`, because this is the smallest type that is required to hold the value `0`. If the array has more than 255 elements, the loop will not terminate. - -## Cheatsheet - -### Global Variables - - - `block.coinbase` (`address`): current block miner's address - - `block.difficulty` (`uint`): current block difficulty - - `block.gaslimit` (`uint`): current block gaslimit - - `block.number` (`uint`): current block number - - `block.blockhash` (`function(uint) returns (bytes32)`): hash of the given block - - `block.timestamp` (`uint`): current block timestamp - - `msg.data` (`bytes`): complete calldata - - `msg.gas` (`uint`): remaining gas - - `msg.sender` (`address`): sender of the message (current call) - - `msg.value` (`uint`): number of wei sent with the message - - `now` (`uint`): current block timestamp (alias for `block.timestamp`) - - `tx.gasprice` (`uint`): gas price of the transaction - - `tx.origin` (`address`): sender of the transaction (full call chain) - - `sha3(...) returns (bytes32)`: compute the Ethereum-SHA3 hash of the (tightly packed) arguments - - `sha256(...) returns (bytes32)`: compute the SHA256 hash of the (tightly packed) arguments - - `ripemd160(...) returns (bytes20)`: compute RIPEMD of 256 the (tightly packed) arguments - - `ecrecover(bytes32, byte, bytes32, bytes32) returns (address)`: recover public key from elliptic curve signature - - `this` (current contract's type): the current contract, explicitly convertible to `address` - - `super`: the contract one level higher in the inheritance hierarchy - - `suicide(address)`: suicide the current contract, sending its funds to the given address - - `
.balance`: balance of the address in Wei - - `
.send(uint256) returns (bool)`: send given amount of Wei to address, returns `false` on failure. - -### Function Visibility Specifiers - -```js -function myFunction() returns (bool) { - return true; -} -``` - - - `public`: visible externally and internally (creates accessor function for storage/state variables) - - `private`: only visible in the current contract - - `external`: only visible externally (only for functions) - i.e. can only be message-called (via `this.fun`) - - `internal`: only visible internally - -### Modifiers - - - `constant` for state variables: Disallows assignment (except initialisation), does not occupy storage slot. - - `constant` for functions: Disallows modification of state - this is not enforced yet. - - `anonymous` for events: Does not store event signature as topic. - - `indexed` for event parameters: Stores the parameter as topic. - -### Types - -TODO - - - -*** - -_Большое спасибо General-Beck Денис Солдатову за перевод._ -_Другие переводы от Дениса на тему Ethereum можно найти [здесь](http://general-beck.info/component/tags/tag/98-ethereum)_ - -_Note: This page is under construction_ diff --git a/pages/swarm/Swarm-Hash.md b/pages/swarm/Swarm-Hash.md deleted file mode 100644 index ac53ec54d..000000000 --- a/pages/swarm/Swarm-Hash.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -name: Swarm Hash -category: ---- - -# Introduction - -Swarm Hash (a.k.a. [`bzzhash`](https://github.com/ethersphere/go-ethereum/tree/bzz/bzz/bzzhash)) is a Merkle tree hash designed for the purpose of efficient storage and retrieval in content-addressed storage, both local and networked. While it is used in [Swarm](https://github.com/ethereum/go-ethereum/wiki/Swarm---distributed-preimage-archive), there is nothing Swarm-specific in it and the authors recommend it as a drop-in substitute of sequential-iterative hash functions (like SHA3) whenever one is used for referencing integrity-sensitive content, as it constitutes an improvement in terms of performance and usability without compromising security. For instance in the [URL Hint Protocol](https://github.com/ethereum/wiki/wiki/URL-Hint-Protocol). - -In particular, it can take advantage of parallelisms (including SMP and massively-parallel architectures such as GPU's) for faster calculation and verification, can be used to verify the integrity of partial content without having to transmit all of it. Proofs of security to the underlying hash function carry over to Swarm Hash. - -# Description - -Swarm Hash is constructed using a regular hash function (in our case, SHA3) with a generalization of Merkle's tree hash scheme. The basic unit of hashing is a _chunk_, that can be either a _leaf chunk_ containing a section of the content to be hashed or an _inner chunk_ containing hashes of its children, which can be of either variety. - -Hashes of leaf chunks are defined as the hashes of the concatenation of the 64-bit length (in LSB-first order) of the content and the content itself. Because of the inclusion of the length, it is resistant to length extension attacks, even if the underlying hash function is not. Note that this "safety belt" measure is extensively used in the latest edition of OpenPGP standard. It is, however, important to emphasize that Swarm Hash is obviously vulnerable to length extension attacks, but can be easily protected against them, when necessary, using similar measures in a higher layer. A possibly very profitable performance optimization (not currently implemented) is to initialize the hash calculation with the length of the standard chunk size (e.g. 4096 bytes), thus saving the repeated hashing thereof. - -Hashes of inner chunks are defined as the hashes of the concatenation of the 64-bit length (in LSB-first order) of the content hashed by the entire (sub-) tree rooted on this chunk and the hashes of its children. - -To distinguish between the two, one should compare the length of the chunk to the 64-bit number with which every chunk begins. If the chunk is exactly 8 bytes longer than this number, it is a leaf chunk. If it is shorter than that, it is an inner chunk. Otherwise, it is not a valid Swarm Hash chunk. - -# Strict interpretation - -A strict Swarm Hash is one where every chunk with the possible exception of those on the rightmost branch is of a specified length, i.e. 4 kilobytes. Those on the rightmost branch are no longer, but possibly shorter than this length. The hash tree must be balanced, meaning that all root-to-leaf branches are of the same length. - -The strict interpretation is unique in that only one hash value matches a particular content. The strict interpretation is only vulnerable to length extension attacks if the length of the content is a multiple of the chunk size, and the number of leaf chunks is an integer power of branching size (the fix maximum chunk size divided by hash length). - -A [parallelized implementation in Go](https://github.com/ethersphere/go-ethereum/tree/bzz/bzz) is available as well as [a command-line tool](https://github.com/ethersphere/go-ethereum/tree/bzz/bzz/bzzhash) for hashing files on the local filesystem using the strict interpretation. - -# Loose interpretations - -Swarm Hash interpreted less strictly may allow for different tree structures, imposing fewer restrictions or none at all. In this way, different hash values can resolve to the same content, which might have some adverse security implications. - -However, it might open the door for different applications where this does not constitute a vulnerability. For example, accepting single-leaf hashes in addition to strict Swarm hashes allows for referencing files without having to implement the whole thing. - -# References - -- [Merkle tree](http://en.wikipedia.org/wiki/Merkle_tree) -- [Length extension attack on wikipedia](http://en.wikipedia.org/wiki/Length_extension_attack) -- [IETF RFC4880](https://tools.ietf.org/html/rfc4880) -- [bzzhash code](https://github.com/ethersphere/go-ethereum/tree/bzz/bzz/bzzhash) -- [Swarm documentation and draft specs](https://github.com/ethereum/go-ethereum/wiki/Swarm---distributed-preimage-archive) \ No newline at end of file diff --git a/pages/whisper/Whisper-Overview.md b/pages/whisper/Whisper-Overview.md deleted file mode 100644 index 539fe5819..000000000 --- a/pages/whisper/Whisper-Overview.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -name: Whisper Overview -category: ---- - -### Example ("Dream") API Usage - -```js -var shh = web3.shh; -var appName = "My silly app!"; -var myName = "Gav Would"; -var myIdentity = shh.newIdentity(); - -shh.post({ - "from": myIdentity, - "topic": [ web3.fromAscii(appName) ], - "payload": [ web3.fromAscii(myName), web3.fromAscii("What is your name?") ], - "ttl": 100, - "priority": 1000 -}); - -var replyWatch = shh.watch({ - "topic": [ web3.fromAscii(appName), myIdentity ], - "to": myIdentity -}); -// could be "topic": [ web3.fromAscii(appName), null ] if we wanted to filter all such -// messages for this app, but we'd be unable to read the contents. - -replyWatch.arrived(function(m) -{ - // new message m - console.log("Reply from " + web3.toAscii(m.payload) + " whose address is " + m.from); -}); - -var broadcastWatch = shh.watch({ "topic": [ web3.fromAscii(appName) ] }); -broadcastWatch.arrived(function(m) -{ - if (m.from != myIdentity) - { - // new message m: someone's asking for our name. Let's tell them. - var broadcaster = web3.toAscii(m.payload).substr(0, 32); - console.log("Broadcast from " + broadcaster + "; replying to tell them our name."); - shh.post({ - "from": eth.key, - "to": m.from, - "topics": [ eth.fromAscii(appName), m.from ], - "payload": [ eth.fromAscii(myName) ], - "ttl": 2, - "priority": 500 - }); - } -}); -``` - -### Basic operation - -`post` takes a JSON object containing four key parameters: - -```js -shh.post({ "topic": t, "payload": p, "ttl": ttl, "workToProve": work }); -``` - -- `topic`, provided as either a list of, or a single, arbitrary data items that are used to encode the abstract topic of this message, later used to filter messages for those that are of interest; -- `payload`, provided similarly to topic but left as an unformatted byte array provides the data to be sent. -- `ttl` is a time for the message to live on the network, specified in seconds. This defaults to 50. -- `work` is the amount of priority you want the packet to have on the network. It is specified in milliseconds of processing time on your machine. This defaults to 50. - -Two other parameters optionally specify the addressing: recipient (`to`), sender (`from`). The latter is meaningless unless a recipient has been specified. - -### Use cases -- `shh.post({ "topic": t, "payload": p });` No signature, no encryption: Anonymous broadcast; a bit like an anonymous subject-filtered twitter feed. -- `shh.post({ "from": myIdentity, "topic": t, "payload": p });` Open signature, no encryption: Clear-signed broadcast; a bit like a normal twitter feed - anyone interested can see a particular identity is sending particular stuff out to no-one in particular. -- `shh.post({ "to": recipient, "topic": t, "payload": p });` No signature, encryption: Encrypted anonymous message; a bit like an anonymous drop-box - message is private to the owner of the dropbox. They can't tell from whom it is. -- `shh.post({ "from": myIdentity, "to": recipient, "topic": t, "payload": p });` Secret signature, encryption: Encrypted signed message; like a secure e-mail. One identity tells another something - nobody else can read it. The recipient alone knows it came from the sender. -- `shh.post({ "from": myIdentity, "to": recipient, "topic": t, "payload": p, "deniable": d });` Secret signature, encryption with optional plausible deniability. If boolean parameter `d` is **false**, it is equivalent to the previous call. If `d` is **true**, recipient cannot prove to any third party that the message originates from sender, though still can verify it for herself. This is achieved by the digital signature being calculated on the symmetric session encryption key instead of the message body. - -In addition to the basic use cases, there will also be support for secure multi-casting. For this, you set up a group with `shh.newGroup`: - -``` -var group = shh.newGroup(eth.key, [ recipient1, recipient2 ]); -``` - -Then can use this as a recipient as you would normally: - -``` -shh.post({ "from": eth.key, "to": group, "topic": t, "payload": p }); -``` - -The `newGroup` actually does something like: - -``` -var group = shh.newIdentity(); -shh.post([ "from": myIdentity, "to": recipient1, "topic": [invSHA3(2^255), recipient1], "payload": secretFromPublic(group) ]); -shh.post([ "from": myIdentity, "to": recipient2, "topic": [invSHA3(2^255), recipient2], "payload": secretFromPublic(group) ]); -return keypair; -``` - -Here, the `invSHA3(2^255)` topic is a sub-band topic (intercepted by the Whisper protocol layer) which takes the key and adds it to the key database. When a packet is addressed to `group`, it encrypts with group's public key. `group` is not generally used for signing. `secretFromPublic` obviously isn't a public API and invSHA3 is only possible because we know each item of the topic is SHA3ed prior to amalgamation in the final topic. - -When signing a message (one with a `from` parameter), the message-hash is the hash of the clear-text (unencrypted) payload. - -Topics is constructed from a number of components - this simply compresses (sha3 + crop) each into a final set of 4-byte crypto-secure hashes. When composing filters, it's the same process. Importantly, all such hashes given in the filters must be includes in. - -To filter on sender/recipient, they should be encoded within the topic by the sender. - -### Silent Operation - -In normal operation (and assuming a non-degenerate attack condition), there is a trade-off between true anonymity/plausible deniability over ones communications and efficiency of operation. The more one advertises to ones peers attempting to "fish" for useful messages and steer such message towards oneself, the more one reveals to ones peers. - -For a securely anonymous dynamic two-way conversation, this trade-off becomes problematic; significant topic-advertising would be necessary for the point-to-point conversation to happen with sensible latency and yet so little about the topic can be advertised to guide messages home without revealing substantial information should there be adversary peers around an endpoint. (If substantial numbers of adversary peers surround both endpoints, a tunnelling system similar to TOR must be used to guarantee security.) - -In this situation, dynamic topic generation would be used. This effectively turns the datagram-orientated channel into a connection-oriented channel. The endpoint to begin the conversation sends a point-to-point (i.e. signed and encrypted) conversation-begin message that contains a randomly chosen 256-bit topic seed. The seed is combined (by both endpoints) with a message nonce (beginning at 0 and incrementing over the course of the conversation) to provide a secure chain of single-use topics. It then generates a bloom filter using randomly selected bits from the new topic to match against and gives the filter to its peers; once a randomly selected minimum of messages fitting this filter have been collected (we assume one of these is the message we are interested in), we send our reply, deriving a new topic (incrementing the nonce), then advertise for that with yet another topic (another nonce increment) with another randomly selected group of bits. diff --git a/pages/whisper/Whisper-PoC-2-Protocol-Spec.md b/pages/whisper/Whisper-PoC-2-Protocol-Spec.md deleted file mode 100644 index 779356b1f..000000000 --- a/pages/whisper/Whisper-PoC-2-Protocol-Spec.md +++ /dev/null @@ -1,141 +0,0 @@ ---- -name: Whisper PoC-2 Protocol Spec -category: ---- - -This page, in addition to the Whisper Wire Specification, details the full Whisper protocol for the first proof-of-concept and sets the vision for the final design. It evolve alongside the Whisper protocol as the prototype is refined. From it you should be able to develop compliant Whisper implementations. This document is intended to give only the base specification. Many of the aspects leading to an implementation of Whisper are game theoretic and best not prescribed in the specification, but rather left to individual implementation teams to determine for themselves. - -### What Whisper Is (and Is Not) - -Whisper combines aspects of both DHTs and datagram messaging systems (e.g. UDP). As such it may be likened and compared to both, not dissimilar to the matter/energy duality (apologies to physicists for the blatant abuse of a fundamental and beautiful natural principle). - -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. - -Alternatively, Whisper may be likened to a DHT with a per-entry configurable TTL and conventions for the signing and encryption of values. In this sense, Whisper provides the ability to have multiply-indexable, non-unique entries (i.e. the same entry having multiple keys, some or all of which may be the same as other entries). - -As such, Whisper is not a typical communications system. It is not designed to replace or substitute TCP/IP, UDP, HTTP or any other traditional protocols; it is not designed to provide a connection oriented system, nor for simply delivering data betwixt a pair of specific network endpoints; it does not have a primary goal of maximising bandwidth or minimising latency (though as with any transmission system, these are concerns). - -Whisper is a new protocol designed expressly for a new paradigm of application development. It is designed from the ground up for easy and efficient multi-casting and broadcasting. Similarly, low-level partially-asynchronous communications is an important goal. Low-value traffic reduction or retardation is another goal (which might also be likened to the quest for QoS). It is designed to be a building block in next generation ÐApps which require large-scale many-to-many data-discovery, signal negotiation and modest transmissions with an absolute minimum of fuss and the expectation that one has a very reasonable assurance of complete privacy. - -### Pitch-Black Darkness - -Whisper operates around the notion of being user-configurable with regard to how much information it leaks concerning the ÐApp content and ultimately, the user activities. To understand information leakage, it is important to distinguish between mere encryption, and *darkness*. Many protocols, both those designed around p2p and more traditional client/server models provide a level of encryption. For some, encryption forms an intrinsic part of the protocol and, applied alone, delivers its primary requirement. While decentralising and encrypting is a great start on building a legitimately "post-Snowden" Web, it is not the end. - -Even with encrypted communications, well-funded attackers are still able to compromise ones privacy, often quite easily. Bulk metadata collection becomes the new battleground, and is at once dismissed as a privacy concern by authorities yet trumpeted as the Next Big Thing by big-data outfits. In the case of a simple client/server model, metadata betrays with which hosts one communicates - this is often plenty enough to compromise privacy given that content is, in many cases, largely determinable from the host. - -With decentralised communications systems, e.g. a basic non-routed but encrypted VoIP call or Telehash communication, a network packet-sniffing attacker may not be able to determine the specific content of a transmission, but with the help of ISP IP address logs they would be able to determine to whom one communicated, when and how often. For certain types of applications in various jurisdictions, this is enough to be a concerning lack of privacy. - -Even with encryption and packet forwarding through a third relay node, there is still ample room for a determined bulk transmissions-collector to execute statistical attacks on timing and bandwidth, effectively using their knowledge of certain network invariants and the fact that only a finite amount of actors are involved (i.e. that nodes tend to forward messages between the same two peers with minimal latency and that there aren't all that many pairs of nodes that are trying to communicate via the same relay). There are ways to mitigate this attack vector, such as using multiple third-party relays and switching between them randomly or to use very strict framing, however both are imperfect and can lead to substantial inefficiencies. - -A truly dark system is one that is utterly uncompromising in information leakage from metadata. At its most secure mode of operation, Whisper can (at a considerable cost of bandwidth and latency) deliver 100% dark operation. Even better, this applies not only for metadata collection from inter-peer conduits (i.e. backbone dragnet devices), but even against a much more arduous "100% - 2" attack; i.e. where every node in the network were compromised (though functional) save a pair running ÐApps for people that wanted to communicate without anybody else knowing. - -### Routing and Lack Thereof - -Fundamentally, at least with the present state of computer science, all systems present a trade off between the efficiency of deterministic (and thus supposedly optimal) routing and darkness (or, put another way, routing privacy). One of Whisper's differences is in providing a user-configurable trade-off between ones routing privacy and ones routing efficiency. - -At its most dark, Whisper nodes are entirely reactive - they receive and record pieces of data and forward them trying to maximise the utility of information transmission to the peers. These pieces of information include what is known as a *topic*, which may be viewed both as a secure-probabilistic routing endpoint and/or a DHT multi-key. - -However, Whisper is also designed to be able to route probabilistically using two methods, both giving away minimal routing information and both being exceptionally resilient to statistical attacks from large-scale metadata collection. - -The first builds on the functionality of the ÐΞV-p2p backend. This backend provides the ability of Whisper to rate peers and, over time, probabilistically alter (or *steer*) its set of peers to those which tend to deliver useful (on-topic, timely, required for ones ÐApps to function) information. Ultimately, as the network evolves and the peer-set is steered, the number of hops between this peer and any others that tend to be good conduits of useful information (be they the emitters or simply the well-positioned hubs) will tend to 0. - -Peer steering also provides the incentive for nodes to provide useful information to peers. The fear of being identified as an under-performing peer and thus being rotated out in favour of other nodes gives all nodes incentive to cooperate and share the most useful information. Useful in this case means provably difficult to author (use of a proof-of-work function helps here); a low time-to-live; and well-corresponding to any provided information on what might be useful (read on for more). - -The second is more dynamic. Nodes are informed by their ÐApps over what sort of topics are useful. Nodes are then allowed to advertise to each peer describing these topics. Topics may be described, using masks or Bloom filters, and thus in an incomplete manner, to reduce the amount of information leaked and make passive statistical attacks arbitrarily difficult to execute. The determination of the amount of information to give to peers is both made through an explicit setting from the user and through topic/traffic modelling: "Given the information coming from this peer and my models of information distribution made from total traffic, am I receiving the amount of useful valuable information that I would expect to receive? If so, narrowing it down with additional description information to the peer may be warranted." - -These settings can even be configured per-peer (more trusted/longer-lasting peers may be afforded greater amounts of information), and per-ÐApp (those ÐApps that may be more sensitive could be afforded less advertising than others). We can also make use of proof-of-work algorithms to minimise the changes of both DoS attacks and 'everything-but' attacks (where a peer is flooded with almost-useful information prompting it to give away more about its true requirements than it would do otherwise). - -Through combining and reducing the Blooms/masks, weaker Nth-level information can be provided to peers about their peers' interests, forming a probabilistic topic-reception vortex around nodes, the "topic-space" gravity-well getting weaker and less certain the farther away with the network hop distance from any interested peers. - -## Basic Protocol Elements - -### Envelopes - -There are two key concepts in Whisper: *Envelopes* and *Messages*. Envelopes may be considered items should Whisper be considered a DHT. Should Whisper be considered a datagram messaging system then envelopes become the packet format which house the potentially encrypted datagrams. Envelopes are necessarily comprehensible by any node (i.e. they themselves are unencrypted). - -They contain information to the entry/datagram such as the original time to live (*TTL*), the absolute time for *expiry* and, importantly, the *topics*. Topics are a set of indexes to this item, recorded in order to help an interested party ("recipient") find it or have it routed to them. They might be likened to binary tags or keywords. Envelopes additionally contain a nonce allowing the original insertion node ("sender") to prove that some arbitrary amount of work was done in its composition. Finally, envelopes contain a message-*data* field; this stores the actual payload, together with some information and potentially a signature; together this forms a message. This field may be encrypted. - -Envelopes are transmitted as RLP-encoded structures. The precise definition is given by: - -[`expiry`: `P`, `ttl`: `P`, [`topic0`: `B_4`, `topic1`: `B_4`, ...], `data`: `B`, `nonce`: `P`] - -Here, `ttl` is given in seconds, `expiry` is the Unix time of the intended expiry date/time for the envelope. Following this point in time the envelope should no longer be transmitted (or stored, unless there is some extenuating circumstance). Prior to this point in time less the `ttl` (i.e. the implied insertion time), the envelope is considered utterly invalid and should be dropped immediately and the transmitting peer punished. - -`nonce` is an arbitrary value. We say the work proved through the value of the SHA3 of the concatenation of the nonce and the SHA3 of the RLP of the packet save the nonce (i.e. just a 4-item RLP list), each of the components as a fixed-length 256-bit hash. When this final hash is interpreted as a BE-encoded value, the smaller it is, the higher the work proved. This is used later to judge a peer. - -### Topics - -Topics are cryptographically secure, probabilistic partial-classifications of the message. Each topic in the set (order is unimportant) is determined as the first (left) 4 bytes of the SHA3-256 hash of some arbitrary data given by the original author of the message. These might e.g. correspond to "twitter" hash-tags or an intended recipient's public key hashed with some session nonce or application-identity. - -Four bytes was chosen to minimise space should a large number of topics be mentioned while still keeping a sufficiently large space to avoid large-scale topic-collision (though it may yet be reviewed and possibly made dynamic in later revisions of the protocol). - -### Messages - -A message is formed as the concatenation of a single byte for flags (at present only a single flag is used), followed by any additional data (as stipulated by the flags) and finally the actual payload. This series of bytes is what forms the `data` item of the envelope and is always encrypted. - -In the present protocol version, no explicit authentication token is given to indicate that the data field is encrypted; any would-be readers of the message must know ahead of time, through the choice of topic that they have specifically filtered for, that the message is encrypted with a particular key. This is likely to be altered in a further PoC to include a MAC. - -Any determination that the message is indeed from a particular sender is left for a higher-level to address. This is noted through the Javascript API allowing the `to` parameter to be passed only at the point of specifying the filter. Since the signature is a part of the message and not outside in the envelope, those unable to decrypt the message data are also unable to access any signature. - -- `flags`: 1 byte -- (`signature`: 65 bytes) -- `payload`: not fixed - -Bit 0 of the flags determines whether the signature exists. All other bits are not yet given a purpose and should be set randomly. A message is invalid if bit 0 is set but the total data is less than 66 bytes (since this wouldn't allow it to contain a signature). - -Payloads are encrypted in one of two ways. If the message has a specific recipient, then by using ECIES with the specific recipient's SECP-256k1 public key. If the message has no recipient, then by AES-256 with a randomly generated key. This key is then XORed with each of the *full* topics to form a salted topic. Each salted topic is stored prior to the encrypted data *in the same order as the corresponding topics are in the envelope header*. - -As a recipient, payloads are decrypted in one of two ways. Through use of topics, it should be known whether the envelope is encrypted to a specific recipient (in which case use the private key to decrypt) or to a general multicast audience. In the latter case, we assume that at least one topic is known (since otherwise, the envelope could not be properly "identified"). In this case, we match the known *full* topic to one of the abridged topics in the envelope, determine the index and de-salt the according salted-key at the beginning of the data segment in order to retrieve the final key. - -Encryption using the full topic with "routing" using the abridged topic ensures that nodes which are merely transiently storing the message and have no interest in the contents (thus have access only to routing information via the abridged topics) have no intrinsic ability to read the content of the message. - -The signature, if provided, is the SHA3-256 hash of the unencrypted payload signed using ECDSA with the insertion-identity's secret key. - -The signature portion is formed as the concatenation of the *r*, *s* and *v* parameters of the SECP-256k1 ECDSA signature, in that order. `v` is non-normalised and should be either 27 or 28. `r` and `s` are both big-endian encoded, fixed-width 32-byte unsigned. - -The payload is otherwise unformatted binary data. - -In the Javascript API, the distinction between envelopes and messages is blurred. This is because DApps should know nothing about envelopes whose message cannot be inspected; the fact that nodes pass envelopes around regardless of their ability to decode the message (or indeed their interest in it at all) is an important component in Whisper's dark communications strategy. - -### Basic Operation - -Nodes are expected to receive and send envelopes continuously, as per the [protocol specification](https://github.com/ethereum/wiki/wiki/Whisper-Wire-Protocol). They should maintain a map of envelopes, indexed by expiry time, and prune accordingly. They should also efficiently deliver messages to the front-end API through maintaining mappings between topics and envelopes. - -When a node's envelope memory becomes exhausted, a node may drop envelopes it considers unimportant or unlikely to please its peers. Nodes should consider peers good that pass them envelopes with low TTLs and high proofs-of-work. Nodes should consider peers bad that pass then expired envelopes or, worse, those that have an implied insertion time prior to the present. - -Nodes should always keep messages that its ÐApps have created. Though not in PoC-1, later editions of this protocol may allow ÐApps to mark messages as being "archived" and these should be stored and made available for additional time. - -Nodes should retain a set of per-ÐApp topics it is interested in. - -### Inserting (Authoring) Messages - -To insert a message, little more is needed than to place the envelope containing it in the node's envelope set that it maintains; the node should, according to its normal heuristics retransmit the envelope in due course. Composing an envelope from a basic payload, possible identities for authoring and access, a number of topics, a time-to-live and some parameters concerning work-proving targets is done though a few steps: - -- Compose `data` through concatenating the relevant flag byte, a signature of the payload if the user specified a valid author identity, and the user-given payload. -- Encrypt the data if an access ("destination") identity's public key is given by the user. -- Compose `topics` from the first 4 bytes of the SHA3 of each topic. -- Set user-given attribute `ttl`. -- Set the `expiry` as the present Unix time plus the time-to-live. -- Set the `nonce` as that which provides the most work proved as per the previous definition, after some fixed amount of time of cycling through candidates or after a candidate surpasses some boundary; either should be given by the user. - -### Topic Masking and Advertising - -Nodes can advertise their topics of interest to each other. For that purpose they use a special type of Whisper message (TopicFilterPacket). The size of Bloom Filter they send to each other must be 64 bytes. Subsequently the rating system will be introduced -- peers sending useful messages will be rated higher then those sending random messages. - -A message matches the bloom filter, if any one of the topics in this message, converted to the Whisper bloom hash, will match the bloom filter. - -Whisper bloom function accepts AbridgedTopic as a parameter (size: 4 bytes), and produces a 64-byte hash, where three bits (at the most) are set to one, and the rest are set to zeros, according to the following algorithm: - -0. Set all the bits in the resulting 64-byte hash to zero. - -1. We take 9 bits form the AbridgedTopic, and convert to integer value (range: 0 - 511). - -2. This value defines the index of the bit in the resulting 512-bit hash, which should be set to one. - -3. Repeat steps 1 & 2 for the second and third bit to be set in the resulting hash. - -Thus, in order to produce the bloom, we use 27 bits out of 32 in the AbridgedTopic. For more details, please see the implementation of the function: TopicBloomFilterBase::bloom() [libwhisper/BloomFilter.h]. - -### Coming changes - -Also being considered for is support for plausible deniability through the use of session keys and a formalisation of the multicast mechanism. \ No newline at end of file diff --git a/pages/whisper/Whisper-PoC-2-Wire-Protocol.md b/pages/whisper/Whisper-PoC-2-Wire-Protocol.md deleted file mode 100644 index bbcc960b9..000000000 --- a/pages/whisper/Whisper-PoC-2-Wire-Protocol.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -name: Whisper PoC-2 Wire Protocol -category: ---- - -Peer-to-peer communications between nodes running Whisper clients run using the underlying [ÐΞVp2p Wire Protocol](https://github.com/ethereum/wiki/wiki/%C3%90%CE%9EVp2p-Wire-Protocol). - -This is a preliminary wire protocol for the Whisper subsystem. It will change. - -### Whisper Sub-protocol - -**Status** -[`+0x00`: `P`, `protocolVersion`: `P`] Inform a peer of the **whisper** status. This message should be send _after_ the initial handshake and _prior_ to any **whisper** related messages. -* `protocolVersion` is one of: - * `0x02` for PoC-7. - -**Messages** -[`+0x01`: `P`, [`expiry1`: `P`, `ttl1`: `P`, [`topic1x1`: `B_4`, `topic1x2`: `B_4`, ...], `data1`: `B`, `nonce1`: `P`], [`expiry2`: `P`, ...], ...] Specify one or more messages. Nodes should not resend the same message to a peer in the same session, nor send a message back to a peer from which it received. This packet may be empty. The packet must be sent at least once per second, and only after receiving a **Messages** message from the peer. - -**TopicFilter** -[`+0x02`: `P`, `bloom`: `B_64`] Specify the bloom filter of the topics that the sender is interested in. The bloom method is defined below. - -### Session Management - -For the Whisper sub-protocol, upon an active session, a `Status` message must be sent. Following the reception of the peer's `Status` message, the Whisper session is active. The peer with the greatest Node Id should send a **Messages** message to begin the message rally. From that point, peers take it in turns to send (possibly empty) Messages packets. - -### Topics and Abridged Topics - -*Topics* are 32-byte hashes, typically generated from ÐApp-specified data. The *abridged topic* is the first 4 bytes of the topic. Abridged topics allow the identification (within the bounds of an acceptably high probability) of a given topic, useful for determining the utility of a topic for a given peer, yet do not give away the full topic information itself, allowing it to be used as a strong encryption key whose secret is not inherently available. - -### Bloomed Topics - -The Bloom filter used in the `TopicFilter` message type is a means a identifying a number of topics to a peer without compromising (too much) privacy over precisely what topics are of interest. Precise control over the information content (and thus efficiency of the filter) may be maintained through the addition of bits. - -Blooms are formed by the bitwise OR operation on a number of bloomed topics. The bloom function takes the abridged topic (the first four bytes of the SHA3 of the ÐApp/user level topic description) and projects them onto a 512-bit slice; in total, three bits are marked for each bloomed topic. - -The projection function is defined as a mapping from a a 4-byte slice `S` to a 512-bit slice `D`; for ease of explanation, `S` will dereference to bytes, whereas `D` will dereference to bits. - -``` -LET D[*] = 0 -FOREACH i IN { 0, 1, 2 } DO -LET n = S[i] -IF S[3] & (2 ** i) THEN n += 512 -D[n] = 1 -END FOR -``` - -In formal notation: -``` -D[i] := f(0) == i || f(1) == i || f(2) == i -``` -where: -``` -f(x) := S[x] + S[3][x] * 512 -``` -(assuming a byte value `S[i]` may be further dereferenced into a bit value) - diff --git a/pages/whisper/Whisper-Wire-Protocol.md b/pages/whisper/Whisper-Wire-Protocol.md deleted file mode 100644 index 8a98baa31..000000000 --- a/pages/whisper/Whisper-Wire-Protocol.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -name: Whisper Wire Protocol -category: ---- - -Peer-to-peer communications between nodes running Whisper clients run using the underlying [ÐΞVp2p Wire Protocol](https://github.com/ethereum/wiki/wiki/%C3%90%CE%9EVp2p-Wire-Protocol). - -This is a preliminary wire protocol for the Whisper subsystem. It will change. - -### Whisper Sub-protocol - -**Status** -[`+0x00`: `P`, `protocolVersion`: `P`] Inform a peer of the **whisper** status. This message should be send _after_ the initial handshake and _prior_ to any **whisper** related messages. -* `protocolVersion` is one of: - * `0x02` for PoC-7. - -**Messages** -[`+0x01`: `P`, [`expiry1`: `P`, `ttl1`: `P`, [`topic1x1`: `B_4`, `topic1x2`: `B_4`, ...], `data1`: `B`, `nonce1`: `P`], [`expiry2`: `P`, ...], ...] Specify one or more messages. Nodes should not resend the same message to a peer in the same session, nor send a message back to a peer from which it received. This packet may be empty. The packet must be sent at least once per second, and only after receiving a **Messages** message from the peer. - -### Session Management - -For the Whisper sub-protocol, upon an active session, a `Status` message must be sent. Following the reception of the peer's `Status` message, the Whisper session is active. The peer with the greatest Node Id should send a **Messages** message to begin the message rally. From that point, peers take it in turns to send (possibly empty) Messages packets. - diff --git a/pages/whisper/Whisper.md b/pages/whisper/Whisper.md deleted file mode 100644 index 1aa067b56..000000000 --- a/pages/whisper/Whisper.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -name: Whisper -category: ---- - -### Use case - -* DApps that need to publish small amounts of information to each other and have the publication last some substantial amount of time. For example, a currency exchange DApp may use it to record an offer to sell some currency at a particular rate on an exchange. In this case, it may last anything between tens of minutes and days. The offer wouldn't be binding, merely a hint to get a potential deal started. - -* DApps that need to signal to each other in order to ultimately collaborate on a transaction. For example, a currency exchange DApp may use it to coordinate an offer prior to creating one (or two, depending on how the exchange is structured) transactions on the exchange. - -* DApps that need to provide non-real-time hinting or general communications between each other. E.g. a small chat-room app. - -* DApps that need to provide dark (plausible denial over perfect network traffic analysis) comms to two correspondents that know nothing of each other but a hash. This could be a DApp for a whistleblower to communicate to a known journalist exchange some small amount of verifiable material and arrange between themselves for some other protocol (Swarm, perhaps) to handle the bulk transfer. - -In general, think transactions, but without the eventual archival, any necessity of being bound to what is said or automated execution & state change. - -### Specs - -* **Low-level** API only exposed to DApps, never to users. -* **Low-bandwidth** Not designed for large data transfers. -* **Uncertain-latency** Not designed for RTC. -* **Dark** No reliable methods for tracing packets or -* Typical usage: - * Low-latency, 1-1 or 1-N signalling messages. - * High latency, high TTL 1-* publication messages. - -Messages less than 64K bytes, typically around 256 bytes. - -### Existing solutions - -* UDP: Similar in API-level, native multicasting. No TTL, security or privacy safeguards. -* [0MQ](http://zeromq.org/): A distributed messaging system, no inherant privacy safeguards. -* [Bitmessage](https://bitmessage.org/wiki/Main_Page): Similar in the basic approach of P2P network exchanging messages with baseline PKI for dark comms. Higher-level (e-mail replacement, only "several thousand/day", larger mails), fixed TTL and no hinting to optimise for throughput. Unclear incentivisation. -* [TeleHash](https://github.com/telehash/telehash.org/blob/master/network.md#paths): Secure connection-orientated RTC comms. Similar in approach to BitTorrent (uses modified Kademila tech), but rather than discovering peers for a given hash, it routes to the recipient given its hash. Uses DHT to do deterministic routing therefore insecure against simple statistical packet-analysis attacks against a large-scale attacker. Connection oriented, so no TTL and not designed for asynchronous data publication. -* [Tox](https://github.com/irungentoo/toxcore/blob/master/docs/updates/DHT.md): Higher-level (IM & AV chat) replacement. - -### Basic Design - -Uses the `"shh"` protocol string of ÐΞVP2P. - -Rest coming soon, once I've finished prototyping. Gav. - -### Considerations for Defeating Traffic Analysis -(from lokiverloren) All existing protocols for location obscured instant messaging have complicated problems to do with routing. - -The Bitmessage protocol propagates messages blindly across the network, and the proper recipient knows how to decrypt it and receives it (just like everyone else) but then stores it and lets its' user know it's got a new message. The problem with this of course is that it greatly increases the exposure of the whole network to a body of encrypted material that ideally should not be easily accessed at all. - -None of the others listed above particularly have any means to hide the source and destination of messages. I believe it is one of the core objectives of the Whisper protocol to hide location of sender and receiver and in transit, make it difficult if not impossible to establish one, the other or both. - -The Tor system has a protocol for enabling connections between two nodes without either knowing where the other is, it is the Rendezvous protocol used for hidden services. Most readers of this will already understand how it works, but what happens is that a hidden service (the equivalent of a server listening on a port in the TCP/IP protocol) selects at random a number (I think, usually 6) 'introducer' nodes. In order to do this it establishes the standard 3-hop chain to each of the introducers, and when a user wants to establish a connection with a hidden service, they propagate a request to connect with hidden service that is associated with a particular public key. I'm not sure about how this request is propagated, obviously it would also have to be done through a circuit or the rendezvous introducer node knows who might be about to establish a circuit. Once one's client knows a valid rendezvous node it then establishes a connection to it and requests to have traffic relayed through its' circuit to the hidden service. - -I think there really isn't a better way to implement 'dark' parts of the connection protocol, because there has to be a different identity for a relay node as a client node, the same principle applies in Ethereum. However, using the rendezvous, it again makes possible something for connections between nodes that know each other (though they don't know the account or identity of the initiator) something other than the uniform 3 hop circuit. For generating a circuit to an exit node in Tor, it is of no danger that your client knows the identity of the relays in each hop along the way, but to do that *within* the network compromises location obfuscation security, tying your ethereum identity with your router identity (I think it may need to be explicitly pointed out that routing function is something that Ethereum nodes will perform). When connecting to a rendezvous, you do not thereby reveal your location to the rendezvous, and the rendezvous does not know the location of the hidden service either, and establishing these connections only requires a public directory to be created for routers. It is not consequential information for an attacker and can be revealed directly by probing for a relevant server at your IP addresses anyway. - -The contribution I would like to make to the discussion is this: - -1. It is implied that the whisper protocol has to work through a system of location obfuscation relays like Tor. Not only this, but it must therefore also be using some form of the rendezvous protocol used in Tor for hidden services. - -2. However, as Tor was originally designed first to be a way to stop webservers logging your IP address in association with a session cookie and record, then secondarily added the ability to implement the equivalent of TCP/IP routing (listening ports) within the context of location obfuscation in the form of the rendezvous protocol, it is an artifact, a legacy of the first purpose that leads to the uniform utilisation of 3 hop nodes and connections that remain open rather than a session (connectionless) protocol like used in HTTP. What I suggest is that, depending on the needs of a particular connection, there can be occasion to mix up the obfuscation process so that it is further obscured from traffic analysis in the case of malicious nodes performing data gathering for an attacker. - -Instead of a connection like is normal between a browser and web server, for example, which is usually left open because of the latency of reestablishing such a connection, to make further requests, instead there can be a session cookie, and then you can alter the way your client sends data through the 'connection' to a hidden node. The connection, between two routing nodes, could be direct, 1 proxy intermediary, 2, or 3, it could use shared secrets instead and route fragments of datagrams across multiple heteregenous circuits, as well, and the receiver would then wait for sufficient fragments to assemble the original packets. Indeed, it could be possible in the case of (not quite related to whisper, but to the distributed data storage protocol) larger streams, break the stream up into parts and alter the obfuscation method through the process, further confusing the traffic analysis data. - -The same considerations apply, fundamentally, the only differences have to do with the size of the data being transmitted, whether it's for a messaging system or distributed filesystem. The other criteria for deciding how to scramble the routing is latency. For some purposes one wants lower latency, and other purposes, greater security is vitally important. When in the process streams are fragmented into parts, it can also increase security to apply an All Or Nothing Transform to the entire package, then if part is intercepted but not the complete message, it is impossible to assemble the data, not even for cryptanalysis purposes. \ No newline at end of file diff --git a/pages/white-paper/[english]-white-paper.md b/pages/white-paper/[english]-white-paper.md deleted file mode 100644 index 28b0258fa..000000000 --- a/pages/white-paper/[english]-white-paper.md +++ /dev/null @@ -1,500 +0,0 @@ ----gg -name: White Paper -category: Basics ---- - -### A Next-Generation Smart Contract and Decentralized Application Platform - -Satoshi Nakamoto's development of Bitcoin in 2009 has often been hailed as a radical development in money and currency, being the first example of a digital asset which simultaneously has no backing or "[intrinsic value](http://bitcoinmagazine.com/8640/an-exploration-of-intrinsic-value-what-it-is-why-bitcoin-doesnt-have-it-and-why-bitcoin-does-have-it/)" and no centralized issuer or controller. However, another, arguably more important, part of the Bitcoin experiment is the underlying blockchain technology as a tool of distributed consensus, and attention is rapidly starting to shift to this other aspect of Bitcoin. Commonly cited alternative applications of blockchain technology include using on-blockchain digital assets to represent custom currencies and financial instruments (["colored coins"](https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit)), the ownership of an underlying physical device (["smart property"](https://en.bitcoin.it/wiki/Smart_Property)), non-fungible assets such as domain names (["Namecoin"](http://namecoin.org)), as well as more complex applications involving having digital assets being directly controlled by a piece of code implementing arbitrary rules (["smart contracts"](http://szabo.best.vwh.net/smart_contracts_idea.html)) or even blockchain-based "[decentralized autonomous organizations](http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/)" (DAOs). What Ethereum intends to provide is a blockchain with a built-in fully fledged Turing-complete programming language that can be used to create "contracts" that can be used to encode arbitrary state transition functions, allowing users to create any of the systems described above, as well as many others that we have not yet imagined, simply by writing up the logic in a few lines of code. - -### Table of Contents - -* [History](#history) - * [Bitcoin As A State Transition System](#bitcoin-as-a-state-transition-system) - * [Mining](#mining) - * [Merkle Trees](#merkle-trees) - * [Alternative Blockchain Applications](#alternative-blockchain-applications) - * [Scripting](#scripting) -* [Ethereum](#ethereum) - * [Ethereum Accounts](#ethereum-accounts) - * [Messages and Transactions](#messages-and-transactions) - * [Ethereum State Transition Function](#ethereum-state-transition-function) - * [Code Execution](#code-execution) - * [Blockchain and Mining](#blockchain-and-mining) -* [Applications](#applications) - * [Token Systems](#token-systems) - * [Financial derivatives](#financial-derivatives-and-stable-value-currencies) - * [Identity and Reputation Systems](#identity-and-reputation-systems) - * [Decentralized File Storage](#decentralized-file-storage) - * [Decentralized Autonomous Organizations](#decentralized-autonomous-organizations) - * [Further Applications](#further-applications) -* [Miscellanea And Concerns](#miscellanea-and-concerns) - * [Modified GHOST Implementation](#modified-ghost-implementation) - * [Fees](#fees) - * [Computation And Turing-Completeness](#computation-and-turing-completeness) - * [Currency And Issuance](#currency-and-issuance) - * [Mining Centralization](#mining-centralization) - * [Scalability](#scalability) -* [Conclusion](#conclusion) -* [References and Further Reading](#references-and-further-reading) - -## Introduction to Bitcoin and Existing Concepts - -### History - -The concept of decentralized digital currency, as well as alternative applications like property registries, has been around for decades. The anonymous e-cash protocols of the 1980s and the 1990s, mostly reliant on a cryptographic primitive known as Chaumian blinding, provided a currency with a high degree of privacy, but the protocols largely failed to gain traction because of their reliance on a centralized intermediary. In 1998, Wei Dai's [b-money](http://www.weidai.com/bmoney.txt) became the first proposal to introduce the idea of creating money through solving computational puzzles as well as decentralized consensus, but the proposal was scant on details as to how decentralized consensus could actually be implemented. In 2005, Hal Finney introduced a concept of "[reusable proofs of work](http://www.finney.org/~hal/rpow/)", a system which uses ideas from b-money together with Adam Back's computationally difficult Hashcash puzzles to create a concept for a cryptocurrency, but once again fell short of the ideal by relying on trusted computing as a backend. In 2009, a decentralized currency was for the first time implemented in practice by Satoshi Nakamoto, combining established primitives for managing ownership through public key cryptography with a consensus algorithm for keeping track of who owns coins, known as "proof of work". - -The mechanism behind proof of work was a breakthrough in the space because it simultaneously solved two problems. First, it provided a simple and moderately effective consensus algorithm, allowing nodes in the network to collectively agree on a set of canonical updates to the state of the Bitcoin ledger. Second, it provided a mechanism for allowing free entry into the consensus process, solving the political problem of deciding who gets to influence the consensus, while simultaneously preventing sybil attacks. It does this by substituting a formal barrier to participation, such as the requirement to be registered as a unique entity on a particular list, with an economic barrier - the weight of a single node in the consensus voting process is directly proportional to the computing power that the node brings. Since then, an alternative approach has been proposed called _proof of stake_, calculating the weight of a node as being proportional to its currency holdings and not computational resources; the discussion of the relative merits of the two approaches is beyond the scope of this paper but it should be noted that both approaches can be used to serve as the backbone of a cryptocurrency. - -### Bitcoin As A State Transition System - -![statetransition.png](https://raw.githubusercontent.com/vbuterin/diagrams/master/statetransition.png) - -From a technical standpoint, the ledger of a cryptocurrency such as Bitcoin can be thought of as a state transition system, where there is a "state" consisting of the ownership status of all existing bitcoins and a "state transition function" that takes a state and a transaction and outputs a new state which is the result. In a standard banking system, for example, the state is a balance sheet, a transaction is a request to move $X from A to B, and the state transition function reduces the value in A's account by $X and increases the value in B's account by $X. If A's account has less than $X in the first place, the state transition function returns an error. Hence, one can formally define: - - APPLY(S,TX) -> S' or ERROR - -In the banking system defined above: - - APPLY({ Alice: $50, Bob: $50 },"send $20 from Alice to Bob") = { Alice: $30, Bob: $70 } - -But: - - APPLY({ Alice: $50, Bob: $50 },"send $70 from Alice to Bob") = ERROR - -The "state" in Bitcoin is the collection of all coins (technically, "unspent transaction outputs" or UTXO) that have been minted and not yet spent, with each UTXO having a denomination and an owner (defined by a 20-byte address which is essentially a cryptographic public key[1]). A transaction contains one or more inputs, with each input containing a reference to an existing UTXO and a cryptographic signature produced by the private key associated with the owner's address, and one or more outputs, with each output containing a new UTXO to be added to the state. - -The state transition function `APPLY(S,TX) -> S'` can be defined roughly as follows: - -1. For each input in `TX`: - * If the referenced UTXO is not in `S`, return an error. - * If the provided signature does not match the owner of the UTXO, return an error. -2. If the sum of the denominations of all input UTXO is less than the sum of the denominations of all output UTXO, return an error. -3. Return `S` with all input UTXO removed and all output UTXO added. - -The first half of the first step prevents transaction senders from spending coins that do not exist, the second half of the first step prevents transaction senders from spending other people's coins, and the second step enforces conservation of value. In order to use this for payment, the protocol is as follows. Suppose Alice wants to send 11.7 BTC to Bob. First, Alice will look for a set of available UTXO that she owns that totals up to at least 11.7 BTC. Realistically, Alice will not be able to get exactly 11.7 BTC; say that the smallest she can get is 6+4+2=12. She then creates a transaction with those three inputs and two outputs. The first output will be 11.7 BTC with Bob's address as its owner, and the second output will be the remaining 0.3 BTC "change", with the owner being Alice herself. - -### Mining - -![block_picture.jpg](https://raw.githubusercontent.com/vbuterin/diagrams/master/block.png) - -If we had access to a trustworthy centralized service, this system would be trivial to implement; it could simply be coded exactly as described, using a centralized server's hard drive to keep track of the state. However, with Bitcoin we are trying to build a decentralized currency system, so we will need to combine the state transaction system with a consensus system in order to ensure that everyone agrees on the order of transactions. Bitcoin's decentralized consensus process requires nodes in the network to continuously attempt to produce packages of transactions called "blocks". The network is intended to produce roughly one block every ten minutes, with each block containing a timestamp, a nonce, a reference to (ie. hash of) the previous block and a list of all of the transactions that have taken place since the previous block. Over time, this creates a persistent, ever-growing, "blockchain" that constantly updates to represent the latest state of the Bitcoin ledger. - -The algorithm for checking if a block is valid, expressed in this paradigm, is as follows: - -1. Check if the previous block referenced by the block exists and is valid. -2. Check that the timestamp of the block is greater than that of the previous block[2] and less than 2 hours into the future -3. Check that the proof of work on the block is valid. -4. Let `S[0]` be the state at the end of the previous block. -5. Suppose `TX` is the block's transaction list with `n` transactions. For all `i` in `0...n-1`, set `S[i+1] = APPLY(S[i],TX[i])` If any application returns an error, exit and return false. -6. Return true, and register `S[n]` as the state at the end of this block. - -Essentially, each transaction in the block must provide a valid state transition from what was the canonical state before the transaction was executed to some new state. Note that the state is not encoded in the block in any way; it is purely an abstraction to be remembered by the validating node and can only be (securely) computed for any block by starting from the genesis state and sequentially applying every transaction in every block. Additionally, note that the order in which the miner includes transactions into the block matters; if there are two transactions A and B in a block such that B spends a UTXO created by A, then the block will be valid if A comes before B but not otherwise. - -The one validity condition present in the above list that is not found in other systems is the requirement for "proof of work". The precise condition is that the double-SHA256 hash of every block, treated as a 256-bit number, must be less than a dynamically adjusted target, which as of the time of this writing is approximately 2187. The purpose of this is to make block creation computationally "hard", thereby preventing sybil attackers from remaking the entire blockchain in their favor. Because SHA256 is designed to be a completely unpredictable pseudorandom function, the only way to create a valid block is simply trial and error, repeatedly incrementing the nonce and seeing if the new hash matches. - -At the current target of ~2187, the network must make an average of ~269 tries before a valid block is found; in general, the target is recalibrated by the network every 2016 blocks so that on average a new block is produced by some node in the network every ten minutes. In order to compensate miners for this computational work, the miner of every block is entitled to include a transaction giving themselves 25 BTC out of nowhere. Additionally, if any transaction has a higher total denomination in its inputs than in its outputs, the difference also goes to the miner as a "transaction fee". Incidentally, this is also the only mechanism by which BTC are issued; the genesis state contained no coins at all. - -In order to better understand the purpose of mining, let us examine what happens in the event of a malicious attacker. Since Bitcoin's underlying cryptography is known to be secure, the attacker will target the one part of the Bitcoin system that is not protected by cryptography directly: the order of transactions. The attacker's strategy is simple: - -1. Send 100 BTC to a merchant in exchange for some product (preferably a rapid-delivery digital good) -2. Wait for the delivery of the product -3. Produce another transaction sending the same 100 BTC to himself -4. Try to convince the network that his transaction to himself was the one that came first. - -Once step (1) has taken place, after a few minutes some miner will include the transaction in a block, say block number 270000. After about one hour, five more blocks will have been added to the chain after that block, with each of those blocks indirectly pointing to the transaction and thus "confirming" it. At this point, the merchant will accept the payment as finalized and deliver the product; since we are assuming this is a digital good, delivery is instant. Now, the attacker creates another transaction sending the 100 BTC to himself. If the attacker simply releases it into the wild, the transaction will not be processed; miners will attempt to run `APPLY(S,TX)` and notice that `TX` consumes a UTXO which is no longer in the state. So instead, the attacker creates a "fork" of the blockchain, starting by mining another version of block 270000 pointing to the same block 269999 as a parent but with the new transaction in place of the old one. Because the block data is different, this requires redoing the proof of work. Furthermore, the attacker's new version of block 270000 has a different hash, so the original blocks 270001 to 270005 do not "point" to it; thus, the original chain and the attacker's new chain are completely separate. The rule is that in a fork the longest blockchain is taken to be the truth, and so legitimate miners will work on the 270005 chain while the attacker alone is working on the 270000 chain. In order for the attacker to make his blockchain the longest, he would need to have more computational power than the rest of the network combined in order to catch up (hence, "51% attack"). - -### Merkle Trees - -![SPV in bitcoin](https://raw.githubusercontent.com/ethereum/www/master-postsale/src/extras/gh_wiki/spv_bitcoin.png) - -_Left: it suffices to present only a small number of nodes in a Merkle tree to give a proof of the validity of a branch._ - -_Right: any attempt to change any part of the Merkle tree will eventually lead to an inconsistency somewhere up the chain._ - -An important scalability feature of Bitcoin is that the block is stored in a multi-level data structure. The "hash" of a block is actually only the hash of the block header, a roughly 200-byte piece of data that contains the timestamp, nonce, previous block hash and the root hash of a data structure called the Merkle tree storing all transactions in the block. A Merkle tree is a type of binary tree, composed of a set of nodes with a large number of leaf nodes at the bottom of the tree containing the underlying data, a set of intermediate nodes where each node is the hash of its two children, and finally a single root node, also formed from the hash of its two children, representing the "top" of the tree. The purpose of the Merkle tree is to allow the data in a block to be delivered piecemeal: a node can download only the header of a block from one source, the small part of the tree relevant to them from another source, and still be assured that all of the data is correct. The reason why this works is that hashes propagate upward: if a malicious user attempts to swap in a fake transaction into the bottom of a Merkle tree, this change will cause a change in the node above, and then a change in the node above that, finally changing the root of the tree and therefore the hash of the block, causing the protocol to register it as a completely different block (almost certainly with an invalid proof of work). - -The Merkle tree protocol is arguably essential to long-term sustainability. A "full node" in the Bitcoin network, one that stores and processes the entirety of every block, takes up about 15 GB of disk space in the Bitcoin network as of April 2014, and is growing by over a gigabyte per month. Currently, this is viable for some desktop computers and not phones, and later on in the future only businesses and hobbyists will be able to participate. A protocol known as "simplified payment verification" (SPV) allows for another class of nodes to exist, called "light nodes", which download the block headers, verify the proof of work on the block headers, and then download only the "branches" associated with transactions that are relevant to them. This allows light nodes to determine with a strong guarantee of security what the status of any Bitcoin transaction, and their current balance, is while downloading only a very small portion of the entire blockchain. - -### Alternative Blockchain Applications - -The idea of taking the underlying blockchain idea and applying it to other concepts also has a long history. In 2005, Nick Szabo came out with the concept of "[secure property titles with owner authority](http://szabo.best.vwh.net/securetitle.html)", a document describing how "new advances in replicated database technology" will allow for a blockchain-based system for storing a registry of who owns what land, creating an elaborate framework including concepts such as homesteading, adverse possession and Georgian land tax. However, there was unfortunately no effective replicated database system available at the time, and so the protocol was never implemented in practice. After 2009, however, once Bitcoin's decentralized consensus was developed a number of alternative applications rapidly began to emerge. - -* **Namecoin** - created in 2010, [Namecoin](https://namecoin.org/) is best described as a decentralized name registration database. In decentralized protocols like Tor, Bitcoin and BitMessage, there needs to be some way of identifying accounts so that other people can interact with them, but in all existing solutions the only kind of identifier available is a pseudorandom hash like `1LW79wp5ZBqaHW1jL5TCiBCrhQYtHagUWy`. Ideally, one would like to be able to have an account with a name like "george". However, the problem is that if one person can create an account named "george" then someone else can use the same process to register "george" for themselves as well and impersonate them. The only solution is a first-to-file paradigm, where the first registerer succeeds and the second fails - a problem perfectly suited for the Bitcoin consensus protocol. Namecoin is the oldest, and most successful, implementation of a name registration system using such an idea. -* **Colored coins** - the purpose of [colored coins](https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit) is to serve as a protocol to allow people to create their own digital currencies - or, in the important trivial case of a currency with one unit, digital tokens, on the Bitcoin blockchain. In the colored coins protocol, one "issues" a new currency by publicly assigning a color to a specific Bitcoin UTXO, and the protocol recursively defines the color of other UTXO to be the same as the color of the inputs that the transaction creating them spent (some special rules apply in the case of mixed-color inputs). This allows users to maintain wallets containing only UTXO of a specific color and send them around much like regular bitcoins, backtracking through the blockchain to determine the color of any UTXO that they receive. -* **Metacoins** - the idea behind a metacoin is to have a protocol that lives on top of Bitcoin, using Bitcoin transactions to store metacoin transactions but having a different state transition function, `APPLY'`. Because the metacoin protocol cannot prevent invalid metacoin transactions from appearing in the Bitcoin blockchain, a rule is added that if `APPLY'(S,TX)` returns an error, the protocol defaults to `APPLY'(S,TX) = S`. This provides an easy mechanism for creating an arbitrary cryptocurrency protocol, potentially with advanced features that cannot be implemented inside of Bitcoin itself, but with a very low development cost since the complexities of mining and networking are already handled by the Bitcoin protocol. Metacoins have been used to implement some classes of financial contracts, name registration and decentralized exchange. - -Thus, in general, there are two approaches toward building a consensus protocol: building an independent network, and building a protocol on top of Bitcoin. The former approach, while reasonably successful in the case of applications like Namecoin, is difficult to implement; each individual implementation needs to bootstrap an independent blockchain, as well as building and testing all of the necessary state transition and networking code. Additionally, we predict that the set of applications for decentralized consensus technology will follow a power law distribution where the vast majority of applications would be too small to warrant their own blockchain, and we note that there exist large classes of decentralized applications, particularly decentralized autonomous organizations, that need to interact with each other. - -The Bitcoin-based approach, on the other hand, has the flaw that it does not inherit the simplified payment verification features of Bitcoin. SPV works for Bitcoin because it can use blockchain depth as a proxy for validity; at some point, once the ancestors of a transaction go far enough back, it is safe to say that they were legitimately part of the state. Blockchain-based meta-protocols, on the other hand, cannot force the blockchain not to include transactions that are not valid within the context of their own protocols. Hence, a fully secure SPV meta-protocol implementation would need to backward scan all the way to the beginning of the Bitcoin blockchain to determine whether or not certain transactions are valid. Currently, all "light" implementations of Bitcoin-based meta-protocols rely on a trusted server to provide the data, arguably a highly suboptimal result especially when one of the primary purposes of a cryptocurrency is to eliminate the need for trust. - -### Scripting - -Even without any extensions, the Bitcoin protocol actually does facilitate a weak version of a concept of "smart contracts". UTXO in Bitcoin can be owned not just by a public key, but also by a more complicated script expressed in a simple stack-based programming language. In this paradigm, a transaction spending that UTXO must provide data that satisfies the script. Indeed, even the basic public key ownership mechanism is implemented via a script: the script takes an elliptic curve signature as input, verifies it against the transaction and the address that owns the UTXO, and returns 1 if the verification is successful and 0 otherwise. Other, more complicated, scripts exist for various additional use cases. For example, one can construct a script that requires signatures from two out of a given three private keys to validate ("multisig"), a setup useful for corporate accounts, secure savings accounts and some merchant escrow situations. Scripts can also be used to pay bounties for solutions to computational problems, and one can even construct a script that says something like "this Bitcoin UTXO is yours if you can provide an SPV proof that you sent a Dogecoin transaction of this denomination to me", essentially allowing decentralized cross-cryptocurrency exchange. - -However, the scripting language as implemented in Bitcoin has several important limitations: - -* **Lack of Turing-completeness** - that is to say, while there is a large subset of computation that the Bitcoin scripting language supports, it does not nearly support everything. The main category that is missing is loops. This is done to avoid infinite loops during transaction verification; theoretically it is a surmountable obstacle for script programmers, since any loop can be simulated by simply repeating the underlying code many times with an if statement, but it does lead to scripts that are very space-inefficient. For example, implementing an alternative elliptic curve signature algorithm would likely require 256 repeated multiplication rounds all individually included in the code. -* **Value-blindness** - there is no way for a UTXO script to provide fine-grained control over the amount that can be withdrawn. For example, one powerful use case of an oracle contract would be a hedging contract, where A and B put in $1000 worth of BTC and after 30 days the script sends $1000 worth of BTC to A and the rest to B. This would require an oracle to determine the value of 1 BTC in USD, but even then it is a massive improvement in terms of trust and infrastructure requirement over the fully centralized solutions that are available now. However, because UTXO are all-or-nothing, the only way to achieve this is through the very inefficient hack of having many UTXO of varying denominations (eg. one UTXO of 2k for every k up to 30) and having the oracle pick which UTXO to send to A and which to B. -* **Lack of state** - UTXO can either be spent or unspent; there is no opportunity for multi-stage contracts or scripts which keep any other internal state beyond that. This makes it hard to make multi-stage options contracts, decentralized exchange offers or two-stage cryptographic commitment protocols (necessary for secure computational bounties). It also means that UTXO can only be used to build simple, one-off contracts and not more complex "stateful" contracts such as decentralized organizations, and makes meta-protocols difficult to implement. Binary state combined with value-blindness also mean that another important application, withdrawal limits, is impossible. -* **Blockchain-blindness** - UTXO are blind to blockchain data such as the nonce, the timestamp and previous block hash. This severely limits applications in gambling, and several other categories, by depriving the scripting language of a potentially valuable source of randomness. - -Thus, we see three approaches to building advanced applications on top of cryptocurrency: building a new blockchain, using scripting on top of Bitcoin, and building a meta-protocol on top of Bitcoin. Building a new blockchain allows for unlimited freedom in building a feature set, but at the cost of development time, bootstrapping effort and security. Using scripting is easy to implement and standardize, but is very limited in its capabilities, and meta-protocols, while easy, suffer from faults in scalability. With Ethereum, we intend to build an alternative framework that provides even larger gains in ease of development as well as even stronger light client properties, while at the same time allowing applications to share an economic environment and blockchain security. - -## Ethereum - -The intent of Ethereum is to create an alternative protocol for building decentralized applications, providing a different set of tradeoffs that we believe will be very useful for a large class of decentralized applications, with particular emphasis on situations where rapid development time, security for small and rarely used applications, and the ability of different applications to very efficiently interact, are important. Ethereum does this by building what is essentially the ultimate abstract foundational layer: a blockchain with a built-in Turing-complete programming language, allowing anyone to write smart contracts and decentralized applications where they can create their own arbitrary rules for ownership, transaction formats and state transition functions. A bare-bones version of Namecoin can be written in two lines of code, and other protocols like currencies and reputation systems can be built in under twenty. Smart contracts, cryptographic "boxes" that contain value and only unlock it if certain conditions are met, can also be built on top of the platform, with vastly more power than that offered by Bitcoin scripting because of the added powers of Turing-completeness, value-awareness, blockchain-awareness and state. - -### Ethereum Accounts - -In Ethereum, the state is made up of objects called "accounts", with each account having a 20-byte address and state transitions being direct transfers of value and information between accounts. An Ethereum account contains four fields: - -* The **nonce**, a counter used to make sure each transaction can only be processed once -* The account's current **ether balance** -* The account's **contract code**, if present -* The account's **storage** (empty by default) - -"Ether" is the main internal crypto-fuel of Ethereum, and is used to pay transaction fees. In general, there are two types of accounts: **externally owned accounts**, controlled by private keys, and **contract accounts**, controlled by their contract code. An externally owned account has no code, and one can send messages from an externally owned account by creating and signing a transaction; in a contract account, every time the contract account receives a message its code activates, allowing it to read and write to internal storage and send other messages or create contracts in turn. - -Note that "contracts" in Ethereum should not be seen as something that should be "fulfilled" or "complied with"; rather, they are more like "autonomous agents" that live inside of the Ethereum execution environment, always executing a specific piece of code when "poked" by a message or transaction, and having direct control over their own ether balance and their own key/value store to keep track of persistent variables. - -### Messages and Transactions - -The term "transaction" is used in Ethereum to refer to the signed data package that stores a message to be sent from an externally owned account. Transactions contain: - -* The recipient of the message -* A signature identifying the sender -* The amount of ether to transfer from the sender to the recipient -* An optional data field -* A `STARTGAS` value, representing the maximum number of computational steps the transaction execution is allowed to take -* A `GASPRICE` value, representing the fee the sender pays per computational step - -The first three are standard fields expected in any cryptocurrency. The data field has no function by default, but the virtual machine has an opcode using which a contract can access the data; as an example use case, if a contract is functioning as an on-blockchain domain registration service, then it may wish to interpret the data being passed to it as containing two "fields", the first field being a domain to register and the second field being the IP address to register it to. The contract would read these values from the message data and appropriately place them in storage. - -The `STARTGAS` and `GASPRICE` fields are crucial for Ethereum's anti-denial of service model. In order to prevent accidental or hostile infinite loops or other computational wastage in code, each transaction is required to set a limit to how many computational steps of code execution it can use. The fundamental unit of computation is "gas"; usually, a computational step costs 1 gas, but some operations cost higher amounts of gas because they are more computationally expensive, or increase the amount of data that must be stored as part of the state. There is also a fee of 5 gas for every byte in the transaction data. The intent of the fee system is to require an attacker to pay proportionately for every resource that they consume, including computation, bandwidth and storage; hence, any transaction that leads to the network consuming a greater amount of any of these resources must have a gas fee roughly proportional to the increment. - -### Messages - -Contracts have the ability to send "messages" to other contracts. Messages are virtual objects that are never serialized and exist only in the Ethereum execution environment. A message contains: - -* The sender of the message (implicit) -* The recipient of the message -* The amount of ether to transfer alongside the message -* An optional data field -* A `STARTGAS` value - -Essentially, a message is like a transaction, except it is produced by a contract and not an external actor. A message is produced when a contract currently executing code executes the `CALL` opcode, which produces and executes a message. Like a transaction, a message leads to the recipient account running its code. Thus, contracts can have relationships with other contracts in exactly the same way that external actors can. - -Note that the gas allowance assigned by a transaction or contract applies to the total gas consumed by that transaction and all sub-executions. For example, if an external actor A sends a transaction to B with 1000 gas, and B consumes 600 gas before sending a message to C, and the internal execution of C consumes 300 gas before returning, then B can spend another 100 gas before running out of gas. - -### Ethereum State Transition Function - -![ethertransition.png](https://raw.githubusercontent.com/vbuterin/diagrams/master/ethertransition.png) - -The Ethereum state transition function, `APPLY(S,TX) -> S'` can be defined as follows: - -1. Check if the transaction is well-formed (ie. has the right number of values), the signature is valid, and the nonce matches the nonce in the sender's account. If not, return an error. -2. Calculate the transaction fee as `STARTGAS * GASPRICE`, and determine the sending address from the signature. Subtract the fee from the sender's account balance and increment the sender's nonce. If there is not enough balance to spend, return an error. -3. Initialize `GAS = STARTGAS`, and take off a certain quantity of gas per byte to pay for the bytes in the transaction. -4. Transfer the transaction value from the sender's account to the receiving account. If the receiving account does not yet exist, create it. If the receiving account is a contract, run the contract's code either to completion or until the execution runs out of gas. -5. If the value transfer failed because the sender did not have enough money, or the code execution ran out of gas, revert all state changes except the payment of the fees, and add the fees to the miner's account. -6. Otherwise, refund the fees for all remaining gas to the sender, and send the fees paid for gas consumed to the miner. - -For example, suppose that the contract's code is: - - if !self.storage[calldataload(0)]: - self.storage[calldataload(0)] = calldataload(32) - -Note that in reality the contract code is written in the low-level EVM code; this example is written in Serpent, one of our high-level languages, for clarity, and can be compiled down to EVM code. Suppose that the contract's storage starts off empty, and a transaction is sent with 10 ether value, 2000 gas, 0.001 ether gasprice, and 64 bytes of data, with bytes 0-31 representing the number `2` and bytes 32-63 representing the string `CHARLIE`. The process for the state transition function in this case is as follows: - -1. Check that the transaction is valid and well formed. -2. Check that the transaction sender has at least 2000 * 0.001 = 2 ether. If it is, then subtract 2 ether from the sender's account. -3. Initialize gas = 2000; assuming the transaction is 170 bytes long and the byte-fee is 5, subtract 850 so that there is 1150 gas left. -3. Subtract 10 more ether from the sender's account, and add it to the contract's account. -4. Run the code. In this case, this is simple: it checks if the contract's storage at index `2` is used, notices that it is not, and so it sets the storage at index `2` to the value `CHARLIE`. Suppose this takes 187 gas, so the remaining amount of gas is 1150 - 187 = 963 -5. Add 963 * 0.001 = 0.963 ether back to the sender's account, and return the resulting state. - -If there was no contract at the receiving end of the transaction, then the total transaction fee would simply be equal to the provided `GASPRICE` multiplied by the length of the transaction in bytes, and the data sent alongside the transaction would be irrelevant. - -Note that messages work equivalently to transactions in terms of reverts: if a message execution runs out of gas, then that message's execution, and all other executions triggered by that execution, revert, but parent executions do not need to revert. This means that it is "safe" for a contract to call another contract, as if A calls B with G gas then A's execution is guaranteed to lose at most G gas. Finally, note that there is an opcode, `CREATE`, that creates a contract; its execution mechanics are generally similar to `CALL`, with the exception that the output of the execution determines the code of a newly created contract. - -### Code Execution - -The code in Ethereum contracts is written in a low-level, stack-based bytecode language, referred to as "Ethereum virtual machine code" or "EVM code". The code consists of a series of bytes, where each byte represents an operation. In general, code execution is an infinite loop that consists of repeatedly carrying out the operation at the current program counter (which begins at zero) and then incrementing the program counter by one, until the end of the code is reached or an error or `STOP` or `RETURN` instruction is detected. The operations have access to three types of space in which to store data: - -* The **stack**, a last-in-first-out container to which values can be pushed and popped -* **Memory**, an infinitely expandable byte array -* The contract's long-term **storage**, a key/value store. Unlike stack and memory, which reset after computation ends, storage persists for the long term. - -The code can also access the value, sender and data of the incoming message, as well as block header data, and the code can also return a byte array of data as an output. - -The formal execution model of EVM code is surprisingly simple. While the Ethereum virtual machine is running, its full computational state can be defined by the tuple `(block_state, transaction, message, code, memory, stack, pc, gas)`, where `block_state` is the global state containing all accounts and includes balances and storage. At the start of every round of execution, the current instruction is found by taking the `pc`th byte of `code` (or 0 if `pc >= len(code)`), and each instruction has its own definition in terms of how it affects the tuple. For example, `ADD` pops two items off the stack and pushes their sum, reduces `gas` by 1 and increments `pc` by 1, and `SSTORE` pushes the top two items off the stack and inserts the second item into the contract's storage at the index specified by the first item. Although there are many ways to optimize Ethereum virtual machine execution via just-in-time compilation, a basic implementation of Ethereum can be done in a few hundred lines of code. - -### Blockchain and Mining - -![apply_block_diagram.png](https://raw.githubusercontent.com/vbuterin/diagrams/master/apply_block_diagram.png) - -The Ethereum blockchain is in many ways similar to the Bitcoin blockchain, although it does have some differences. The main difference between Ethereum and Bitcoin with regard to the blockchain architecture is that, unlike Bitcoin, Ethereum blocks contain a copy of both the transaction list and the most recent state. Aside from that, two other values, the block number and the difficulty, are also stored in the block. The basic block validation algorithm in Ethereum is as follows: - -1. Check if the previous block referenced exists and is valid. -2. Check that the timestamp of the block is greater than that of the referenced previous block and less than 15 minutes into the future -3. Check that the block number, difficulty, transaction root, uncle root and gas limit (various low-level Ethereum-specific concepts) are valid. -4. Check that the proof of work on the block is valid. -5. Let `S[0]` be the state at the end of the previous block. -6. Let `TX` be the block's transaction list, with `n` transactions. For all `i` in `0...n-1`, set `S[i+1] = APPLY(S[i],TX[i])`. If any applications returns an error, or if the total gas consumed in the block up until this point exceeds the `GASLIMIT`, return an error. -7. Let `S_FINAL` be `S[n]`, but adding the block reward paid to the miner. -8. Check if the Merkle tree root of the state `S_FINAL` is equal to the final state root provided in the block header. If it is, the block is valid; otherwise, it is not valid. - -The approach may seem highly inefficient at first glance, because it needs to store the entire state with each block, but in reality efficiency should be comparable to that of Bitcoin. The reason is that the state is stored in the tree structure, and after every block only a small part of the tree needs to be changed. Thus, in general, between two adjacent blocks the vast majority of the tree should be the same, and therefore the data can be stored once and referenced twice using pointers (ie. hashes of subtrees). A special kind of tree known as a "Patricia tree" is used to accomplish this, including a modification to the Merkle tree concept that allows for nodes to be inserted and deleted, and not just changed, efficiently. Additionally, because all of the state information is part of the last block, there is no need to store the entire blockchain history - a strategy which, if it could be applied to Bitcoin, can be calculated to provide 5-20x savings in space. - -A commonly asked question is "where" contract code is executed, in terms of physical hardware. This has a simple answer: the process of executing contract code is part of the definition of the state transition function, which is part of the block validation algorithm, so if a transaction is added into block `B` the code execution spawned by that transaction will be executed by all nodes, now and in the future, that download and validate block `B`. - -## Applications - -In general, there are three types of applications on top of Ethereum. The first category is financial applications, providing users with more powerful ways of managing and entering into contracts using their money. This includes sub-currencies, financial derivatives, hedging contracts, savings wallets, wills, and ultimately even some classes of full-scale employment contracts. The second category is semi-financial applications, where money is involved but there is also a heavy non-monetary side to what is being done; a perfect example is self-enforcing bounties for solutions to computational problems. Finally, there are applications such as online voting and decentralized governance that are not financial at all. - -### Token Systems - -On-blockchain token systems have many applications ranging from sub-currencies representing assets such as USD or gold to company stocks, individual tokens representing smart property, secure unforgeable coupons, and even token systems with no ties to conventional value at all, used as point systems for incentivization. Token systems are surprisingly easy to implement in Ethereum. The key point to understand is that all a currency, or token system, fundamentally is a database with one operation: subtract X units from A and give X units to B, with the proviso that (i) A had at least X units before the transaction and (2) the transaction is approved by A. All that it takes to implement a token system is to implement this logic into a contract. - -The basic code for implementing a token system in Serpent looks as follows: - - def send(to, value): - if self.storage[msg.sender] >= value: - self.storage[msg.sender] = self.storage[msg.sender] - value - self.storage[to] = self.storage[to] + value - -This is essentially a literal implementation of the "banking system" state transition function described further above in this document. A few extra lines of code need to be added to provide for the initial step of distributing the currency units in the first place and a few other edge cases, and ideally a function would be added to let other contracts query for the balance of an address. But that's all there is to it. Theoretically, Ethereum-based token systems acting as sub-currencies can potentially include another important feature that on-chain Bitcoin-based meta-currencies lack: the ability to pay transaction fees directly in that currency. The way this would be implemented is that the contract would maintain an ether balance with which it would refund ether used to pay fees to the sender, and it would refill this balance by collecting the internal currency units that it takes in fees and reselling them in a constant running auction. Users would thus need to "activate" their accounts with ether, but once the ether is there it would be reusable because the contract would refund it each time. - -### Financial derivatives and Stable-Value Currencies - -Financial derivatives are the most common application of a "smart contract", and one of the simplest to implement in code. The main challenge in implementing financial contracts is that the majority of them require reference to an external price ticker; for example, a very desirable application is a smart contract that hedges against the volatility of ether (or another cryptocurrency) with respect to the US dollar, but doing this requires the contract to know what the value of ETH/USD is. The simplest way to do this is through a "data feed" contract maintained by a specific party (eg. NASDAQ) designed so that that party has the ability to update the contract as needed, and providing an interface that allows other contracts to send a message to that contract and get back a response that provides the price. - -Given that critical ingredient, the hedging contract would look as follows: - -1. Wait for party A to input 1000 ether. -2. Wait for party B to input 1000 ether. -3. Record the USD value of 1000 ether, calculated by querying the data feed contract, in storage, say this is $x. -4. After 30 days, allow A or B to "reactivate" the contract in order to send $x worth of ether (calculated by querying the data feed contract again to get the new price) to A and the rest to B. - -Such a contract would have significant potential in crypto-commerce. One of the main problems cited about cryptocurrency is the fact that it's volatile; although many users and merchants may want the security and convenience of dealing with cryptographic assets, they many not wish to face that prospect of losing 23% of the value of their funds in a single day. Up until now, the most commonly proposed solution has been issuer-backed assets; the idea is that an issuer creates a sub-currency in which they have the right to issue and revoke units, and provide one unit of the currency to anyone who provides them (offline) with one unit of a specified underlying asset (eg. gold, USD). The issuer then promises to provide one unit of the underlying asset to anyone who sends back one unit of the crypto-asset. This mechanism allows any non-cryptographic asset to be "uplifted" into a cryptographic asset, provided that the issuer can be trusted. - -In practice, however, issuers are not always trustworthy, and in some cases the banking infrastructure is too weak, or too hostile, for such services to exist. Financial derivatives provide an alternative. Here, instead of a single issuer providing the funds to back up an asset, a decentralized market of speculators, betting that the price of a cryptographic reference asset (eg. ETH) will go up, plays that role. Unlike issuers, speculators have no option to default on their side of the bargain because the hedging contract holds their funds in escrow. Note that this approach is not fully decentralized, because a trusted source is still needed to provide the price ticker, although arguably even still this is a massive improvement in terms of reducing infrastructure requirements (unlike being an issuer, issuing a price feed requires no licenses and can likely be categorized as free speech) and reducing the potential for fraud. - -### Identity and Reputation Systems - -The earliest alternative cryptocurrency of all, [Namecoin](http://namecoin.org/), attempted to use a Bitcoin-like blockchain to provide a name registration system, where users can register their names in a public database alongside other data. The major cited use case is for a [DNS](http://en.wikipedia.org/wiki/Domain_Name_System) system, mapping domain names like "bitcoin.org" (or, in Namecoin's case, "bitcoin.bit") to an IP address. Other use cases include email authentication and potentially more advanced reputation systems. Here is the basic contract to provide a Namecoin-like name registration system on Ethereum: - - def register(name, value): - if !self.storage[name]: - self.storage[name] = value - -The contract is very simple; all it is is a database inside the Ethereum network that can be added to, but not modified or removed from. Anyone can register a name with some value, and that registration then sticks forever. A more sophisticated name registration contract will also have a "function clause" allowing other contracts to query it, as well as a mechanism for the "owner" (ie. the first registerer) of a name to change the data or transfer ownership. One can even add reputation and web-of-trust functionality on top. - -### Decentralized File Storage - -Over the past few years, there have emerged a number of popular online file storage startups, the most prominent being Dropbox, seeking to allow users to upload a backup of their hard drive and have the service store the backup and allow the user to access it in exchange for a monthly fee. However, at this point the file storage market is at times relatively inefficient; a cursory look at various [existing solutions](http://online-storage-service-review.toptenreviews.com/) shows that, particularly at the "uncanny valley" 20-200 GB level at which neither free quotas nor enterprise-level discounts kick in, monthly prices for mainstream file storage costs are such that you are paying for more than the cost of the entire hard drive in a single month. Ethereum contracts can allow for the development of a decentralized file storage ecosystem, where individual users can earn small quantities of money by renting out their own hard drives and unused space can be used to further drive down the costs of file storage. - -The key underpinning piece of such a device would be what we have termed the "decentralized Dropbox contract". This contract works as follows. First, one splits the desired data up into blocks, encrypting each block for privacy, and builds a Merkle tree out of it. One then makes a contract with the rule that, every N blocks, the contract would pick a random index in the Merkle tree (using the previous block hash, accessible from contract code, as a source of randomness), and give X ether to the first entity to supply a transaction with a simplified payment verification-like proof of ownership of the block at that particular index in the tree. When a user wants to re-download their file, they can use a micropayment channel protocol (eg. pay 1 szabo per 32 kilobytes) to recover the file; the most fee-efficient approach is for the payer not to publish the transaction until the end, instead replacing the transaction with a slightly more lucrative one with the same nonce after every 32 kilobytes. - -An important feature of the protocol is that, although it may seem like one is trusting many random nodes not to decide to forget the file, one can reduce that risk down to near-zero by splitting the file into many pieces via secret sharing, and watching the contracts to see each piece is still in some node's possession. If a contract is still paying out money, that provides a cryptographic proof that someone out there is still storing the file. - -### Decentralized Autonomous Organizations - -The general concept of a "decentralized autonomous organization" is that of a virtual entity that has a certain set of members or shareholders which, perhaps with a 67% majority, have the right to spend the entity's funds and modify its code. The members would collectively decide on how the organization should allocate its funds. Methods for allocating a DAO's funds could range from bounties, salaries to even more exotic mechanisms such as an internal currency to reward work. This essentially replicates the legal trappings of a traditional company or nonprofit but using only cryptographic blockchain technology for enforcement. So far much of the talk around DAOs has been around the "capitalist" model of a "decentralized autonomous corporation" (DAC) with dividend-receiving shareholders and tradable shares; an alternative, perhaps described as a "decentralized autonomous community", would have all members have an equal share in the decision making and require 67% of existing members to agree to add or remove a member. The requirement that one person can only have one membership would then need to be enforced collectively by the group. - -A general outline for how to code a DAO is as follows. The simplest design is simply a piece of self-modifying code that changes if two thirds of members agree on a change. Although code is theoretically immutable, one can easily get around this and have de-facto mutability by having chunks of the code in separate contracts, and having the address of which contracts to call stored in the modifiable storage. In a simple implementation of such a DAO contract, there would be three transaction types, distinquished by the data provided in the transaction: - -* `[0,i,K,V]` to register a proposal with index `i` to change the address at storage index `K` to value `V` -* `[0,i]` to register a vote in favor of proposal `i` -* `[2,i]` to finalize proposal `i` if enough votes have been made - -The contract would then have clauses for each of these. It would maintain a record of all open storage changes, along with a list of who voted for them. It would also have a list of all members. When any storage change gets to two thirds of members voting for it, a finalizing transaction could execute the change. A more sophisticated skeleton would also have built-in voting ability for features like sending a transaction, adding members and removing members, and may even provide for [Liquid Democracy](http://en.wikipedia.org/wiki/Delegative_democracy)-style vote delegation (ie. anyone can assign someone to vote for them, and assignment is transitive so if A assigns B and B assigns C then C determines A's vote). This design would allow the DAO to grow organically as a decentralized community, allowing people to eventually delegate the task of filtering out who is a member to specialists, although unlike in the "current system" specialists can easily pop in and out of existence over time as individual community members change their alignments. - -An alternative model is for a decentralized corporation, where any account can have zero or more shares, and two thirds of the shares are required to make a decision. A complete skeleton would involve asset management functionality, the ability to make an offer to buy or sell shares, and the ability to accept offers (preferably with an order-matching mechanism inside the contract). Delegation would also exist Liquid Democracy-style, generalizing the concept of a "board of directors". - -### Further Applications - -**1. Savings wallets**. Suppose that Alice wants to keep her funds safe, but is worried that she will lose or someone will hack her private key. She puts ether into a contract with Bob, a bank, as follows: - -* Alice alone can withdraw a maximum of 1% of the funds per day. -* Bob alone can withdraw a maximum of 1% of the funds per day, but Alice has the ability to make a transaction with her key shutting off this ability. -* Alice and Bob together can withdraw anything. - -Normally, 1% per day is enough for Alice, and if Alice wants to withdraw more she can contact Bob for help. If Alice's key gets hacked, she runs to Bob to move the funds to a new contract. If she loses her key, Bob will get the funds out eventually. If Bob turns out to be malicious, then she can turn off his ability to withdraw. - -**2. Crop insurance**. One can easily make a financial derivatives contract but using a data feed of the weather instead of any price index. If a farmer in Iowa purchases a derivative that pays out inversely based on the precipitation in Iowa, then if there is a drought, the farmer will automatically receive money and if there is enough rain the farmer will be happy because their crops would do well. This can be expanded to natural disaster insurance generally. - -**3. A decentralized data feed**. For financial contracts for difference, it may actually be possible to decentralize the data feed via a protocol called "[SchellingCoin](http://blog.ethereum.org/2014/03/28/schellingcoin-a-minimal-trust-universal-data-feed/)". SchellingCoin basically works as follows: N parties all put into the system the value of a given datum (eg. the ETH/USD price), the values are sorted, and everyone between the 25th and 75th percentile gets one token as a reward. Everyone has the incentive to provide the answer that everyone else will provide, and the only value that a large number of players can realistically agree on is the obvious default: the truth. This creates a decentralized protocol that can theoretically provide any number of values, including the ETH/USD price, the temperature in Berlin or even the result of a particular hard computation. - -**4. Smart multisignature escrow**. Bitcoin allows multisignature transaction contracts where, for example, three out of a given five keys can spend the funds. Ethereum allows for more granularity; for example, four out of five can spend everything, three out of five can spend up to 10% per day, and two out of five can spend up to 0.5% per day. Additionally, Ethereum multisig is asynchronous - two parties can register their signatures on the blockchain at different times and the last signature will automatically send the transaction. - -**5. Cloud computing**. The EVM technology can also be used to create a verifiable computing environment, allowing users to ask others to carry out computations and then optionally ask for proofs that computations at certain randomly selected checkpoints were done correctly. This allows for the creation of a cloud computing market where any user can participate with their desktop, laptop or specialized server, and spot-checking together with security deposits can be used to ensure that the system is trustworthy (ie. nodes cannot profitably cheat). Although such a system may not be suitable for all tasks; tasks that require a high level of inter-process communication, for example, cannot easily be done on a large cloud of nodes. Other tasks, however, are much easier to parallelize; projects like SETI@home, folding@home and genetic algorithms can easily be implemented on top of such a platform. - -**6. Peer-to-peer gambling**. Any number of peer-to-peer gambling protocols, such as Frank Stajano and Richard Clayton's [Cyberdice](http://www.cl.cam.ac.uk/~fms27/papers/2008-StajanoCla-cyberdice.pdf), can be implemented on the Ethereum blockchain. The simplest gambling protocol is actually simply a contract for difference on the next block hash, and more advanced protocols can be built up from there, creating gambling services with near-zero fees that have no ability to cheat. - -**7. Prediction markets**. Provided an oracle or SchellingCoin, prediction markets are also easy to implement, and prediction markets together with SchellingCoin may prove to be the first mainstream application of [futarchy](http://hanson.gmu.edu/futarchy.html) as a governance protocol for decentralized organizations. - -**8. On-chain decentralized marketplaces**, using the identity and reputation system as a base. - -## Miscellanea And Concerns - -### Modified GHOST Implementation - -The "Greedy Heaviest Observed Subtree" (GHOST) protocol is an innovation first introduced by Yonatan Sompolinsky and Aviv Zohar in [December 2013](http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf). The motivation behind GHOST is that blockchains with fast confirmation times currently suffer from reduced security due to a high stale rate - because blocks take a certain time to propagate through the network, if miner A mines a block and then miner B happens to mine another block before miner A's block propagates to B, miner B's block will end up wasted and will not contribute to network security. Furthermore, there is a centralization issue: if miner A is a mining pool with 30% hashpower and B has 10% hashpower, A will have a risk of producing a stale block 70% of the time (since the other 30% of the time A produced the last block and so will get mining data immediately) whereas B will have a risk of producing a stale block 90% of the time. Thus, if the block interval is short enough for the stale rate to be high, A will be substantially more efficient simply by virtue of its size. With these two effects combined, blockchains which produce blocks quickly are very likely to lead to one mining pool having a large enough percentage of the network hashpower to have de facto control over the mining process. - -As described by Sompolinsky and Zohar, GHOST solves the first issue of network security loss by including stale blocks in the calculation of which chain is the "longest"; that is to say, not just the parent and further ancestors of a block, but also the stale descendants of the block's ancestor (in Ethereum jargon, "uncles") are added to the calculation of which block has the largest total proof of work backing it. To solve the second issue of centralization bias, we go beyond the protocol described by Sompolinsky and Zohar, and also provide block rewards to stales: a stale block receives 87.5% of its base reward, and the nephew that includes the stale block receives the remaining 12.5%. Transaction fees, however, are not awarded to uncles. - -Ethereum implements a simplified version of GHOST which only goes down seven levels. Specifically, it is defined as follows: - -* A block must specify a parent, and it must specify 0 or more uncles -* An uncle included in block `B` must have the following properties: - * It must be a direct child of the `k`-th generation ancestor of `B`, where `2 <= k <= 7`. - * It cannot be an ancestor of `B` - * An uncle must be a valid block header, but does not need to be a previously verified or even valid block - * An uncle must be different from all uncles included in previous blocks and all other uncles included in the same block (non-double-inclusion) -* For every uncle `U` in block `B`, the miner of `B` gets an additional 3.125% added to its coinbase reward and the miner of `U` gets 93.75% of a standard coinbase reward. - -This limited version of GHOST, with uncles includable only up to 7 generations, was used for two reasons. First, unlimited GHOST would include too many complications into the calculation of which uncles for a given block are valid. Second, unlimited GHOST with compensation as used in Ethereum removes the incentive for a miner to mine on the main chain and not the chain of a public attacker. - -### Fees - -Because every transaction published into the blockchain imposes on the network the cost of needing to download and verify it, there is a need for some regulatory mechanism, typically involving transaction fees, to prevent abuse. The default approach, used in Bitcoin, is to have purely voluntary fees, relying on miners to act as the gatekeepers and set dynamic minimums. This approach has been received very favorably in the Bitcoin community particularly because it is "market-based", allowing supply and demand between miners and transaction senders determine the price. The problem with this line of reasoning is, however, that transaction processing is not a market; although it is intuitively attractive to construe transaction processing as a service that the miner is offering to the sender, in reality every transaction that a miner includes will need to be processed by every node in the network, so the vast majority of the cost of transaction processing is borne by third parties and not the miner that is making the decision of whether or not to include it. Hence, tragedy-of-the-commons problems are very likely to occur. - -However, as it turns out this flaw in the market-based mechanism, when given a particular inaccurate simplifying assumption, magically cancels itself out. The argument is as follows. Suppose that: - -1. A transaction leads to `k` operations, offering the reward `kR` to any miner that includes it where `R` is set by the sender and `k` and `R` are (roughly) visible to the miner beforehand. -2. An operation has a processing cost of `C` to any node (ie. all nodes have equal efficiency) -3. There are `N` mining nodes, each with exactly equal processing power (ie. `1/N` of total) -4. No non-mining full nodes exist. - -A miner would be willing to process a transaction if the expected reward is greater than the cost. Thus, the expected reward is `kR/N` since the miner has a `1/N` chance of processing the next block, and the processing cost for the miner is simply `kC`. Hence, miners will include transactions where `kR/N > kC`, or `R > NC`. Note that `R` is the per-operation fee provided by the sender, and is thus a lower bound on the benefit that the sender derives from the transaction, and `NC` is the cost to the entire network together of processing an operation. Hence, miners have the incentive to include only those transactions for which the total utilitarian benefit exceeds the cost. - -However, there are several important deviations from those assumptions in reality: - -1. The miner does pay a higher cost to process the transaction than the other verifying nodes, since the extra verification time delays block propagation and thus increases the chance the block will become a stale. -2. There do exist nonmining full nodes. -3. The mining power distribution may end up radically inegalitarian in practice. -4. Speculators, political enemies and crazies whose utility function includes causing harm to the network do exist, and they can cleverly set up contracts where their cost is much lower than the cost paid by other verifying nodes. - -(1) provides a tendency for the miner to include fewer transactions, and (2) increases `NC`; hence, these two effects at least partially cancel each other out. (3) and (4) are the major issue; to solve them we simply institute a floating cap: no block can have more operations than `BLK_LIMIT_FACTOR` times the long-term exponential moving average. Specifically: - - blk.oplimit = floor((blk.parent.oplimit * (EMA_FACTOR - 1) + floor(parent.opcount * BLK_LIMIT_FACTOR)) / EMA_FACTOR) - -`BLK_LIMIT_FACTOR` and `EMA_FACTOR` are constants that will be set to 65536 and 1.5 for the time being, but will likely be changed after further analysis. - -There is another factor disincentivizing large block sizes in Bitcoin: blocks that are large will take longer to propagate, and thus have a higher probability of becoming stales. In Ethereum, highly gas-consuming blocks can also take longer to propagate both because they are physically larger and because they take longer to process the transaction state transitions to validate. This delay disincentive is a significant consideration in Bitcoin, but less so in Ethereum because of the GHOST protocol; hence, relying on regulated block limits provides a more stable baseline. - -### Computation And Turing-Completeness - -An important note is that the Ethereum virtual machine is Turing-complete; this means that EVM code can encode any computation that can be conceivably carried out, including infinite loops. EVM code allows looping in two ways. First, there is a `JUMP` instruction that allows the program to jump back to a previous spot in the code, and a `JUMPI` instruction to do conditional jumping, allowing for statements like `while x < 27: x = x * 2`. Second, contracts can call other contracts, potentially allowing for looping through recursion. This naturally leads to a problem: can malicious users essentially shut miners and full nodes down by forcing them to enter into an infinite loop? The issue arises because of a problem in computer science known as the halting problem: there is no way to tell, in the general case, whether or not a given program will ever halt. - -As described in the state transition section, our solution works by requiring a transaction to set a maximum number of computational steps that it is allowed to take, and if execution takes longer computation is reverted but fees are still paid. Messages work in the same way. To show the motivation behind our solution, consider the following examples: - -* An attacker creates a contract which runs an infinite loop, and then sends a transaction activating that loop to the miner. The miner will process the transaction, running the infinite loop, and wait for it to run out of gas. Even though the execution runs out of gas and stops halfway through, the transaction is still valid and the miner still claims the fee from the attacker for each computational step. -* An attacker creates a very long infinite loop with the intent of forcing the miner to keep computing for such a long time that by the time computation finishes a few more blocks will have come out and it will not be possible for the miner to include the transaction to claim the fee. However, the attacker will be required to submit a value for `STARTGAS` limiting the number of computational steps that execution can take, so the miner will know ahead of time that the computation will take an excessively large number of steps. -* An attacker sees a contract with code of some form like `send(A,contract.storage[A]); contract.storage[A] = 0`, and sends a transaction with just enough gas to run the first step but not the second (ie. making a withdrawal but not letting the balance go down). The contract author does not need to worry about protecting against such attacks, because if execution stops halfway through the changes get reverted. -* A financial contract works by taking the median of nine proprietary data feeds in order to minimize risk. An attacker takes over one of the data feeds, which is designed to be modifiable via the variable-address-call mechanism described in the section on DAOs, and converts it to run an infinite loop, thereby attempting to force any attempts to claim funds from the financial contract to run out of gas. However, the financial contract can set a gas limit on the message to prevent this problem. - -The alternative to Turing-completeness is Turing-incompleteness, where `JUMP` and `JUMPI` do not exist and only one copy of each contract is allowed to exist in the call stack at any given time. With this system, the fee system described and the uncertainties around the effectiveness of our solution might not be necessary, as the cost of executing a contract would be bounded above by its size. Additionally, Turing-incompleteness is not even that big a limitation; out of all the contract examples we have conceived internally, so far only one required a loop, and even that loop could be removed by making 26 repetitions of a one-line piece of code. Given the serious implications of Turing-completeness, and the limited benefit, why not simply have a Turing-incomplete language? In reality, however, Turing-incompleteness is far from a neat solution to the problem. To see why, consider the following contracts: - - C0: call(C1); call(C1); - C1: call(C2); call(C2); - C2: call(C3); call(C3); - ... - C49: call(C50); call(C50); - C50: (run one step of a program and record the change in storage) - -Now, send a transaction to A. Thus, in 51 transactions, we have a contract that takes up 250 computational steps. Miners could try to detect such logic bombs ahead of time by maintaining a value alongside each contract specifying the maximum number of computational steps that it can take, and calculating this for contracts calling other contracts recursively, but that would require miners to forbid contracts that create other contracts (since the creation and execution of all 26 contracts above could easily be rolled into a single contract). Another problematic point is that the address field of a message is a variable, so in general it may not even be possible to tell which other contracts a given contract will call ahead of time. Hence, all in all, we have a surprising conclusion: Turing-completeness is surprisingly easy to manage, and the lack of Turing-completeness is equally surprisingly difficult to manage unless the exact same controls are in place - but in that case why not just let the protocol be Turing-complete? - -### Currency And Issuance - -The Ethereum network includes its own built-in currency, ether, which serves the dual purpose of providing a primary liquidity layer to allow for efficient exchange between various types of digital assets and, more importantly, of providing a mechanism for paying transaction fees. For convenience and to avoid future argument (see the current mBTC/uBTC/satoshi debate in Bitcoin), the denominations will be pre-labelled: - -* 1: wei -* 1012: szabo -* 1015: finney -* 1018: ether - -This should be taken as an expanded version of the concept of "dollars" and "cents" or "BTC" and "satoshi". In the near future, we expect "ether" to be used for ordinary transactions, "finney" for microtransactions and "szabo" and "wei" for technical discussions around fees and protocol implementation; the remaining denominations may become useful later and should not be included in clients at this point. - -The issuance model will be as follows: - -* Ether will be released in a currency sale at the price of 1000-2000 ether per BTC, a mechanism intended to fund the Ethereum organization and pay for development that has been used with success by other platforms such as Mastercoin and NXT. Earlier buyers will benefit from larger discounts. The BTC received from the sale will be used entirely to pay salaries and bounties to developers and invested into various for-profit and non-profit projects in the Ethereum and cryptocurrency ecosystem. -* 0.099x the total amount sold (60102216 ETH) will be allocated to the organization to compensate early contributors and pay ETH-denominated expenses before the genesis block. -* 0.099x the total amount sold will be maintained as a long-term reserve. -* 0.26x the total amount sold will be allocated to miners per year forever after that point. - -| Group | At launch | After 1 year | After 5 years -| ------------- | ------------- |-------------| ----------- | -| Currency units | 1.198X | 1.458X | 2.498X | -| Purchasers | 83.5% | 68.6% | 40.0% | -| Reserve spent pre-sale | 8.26% | 6.79% | 3.96% | -| Reserve used post-sale | 8.26% | 6.79% | 3.96% | -| Miners | 0% | 17.8% | 52.0% | - -**Long-Term Supply Growth Rate (percent)** - -_Despite the linear currency issuance, just like with Bitcoin over time the supply growth rate nevertheless tends to zero_ - -The two main choices in the above model are (1) the existence and size of an endowment pool, and (2) the existence of a permanently growing linear supply, as opposed to a capped supply as in Bitcoin. The justification of the endowment pool is as follows. If the endowment pool did not exist, and the linear issuance reduced to 0.217x to provide the same inflation rate, then the total quantity of ether would be 16.5% less and so each unit would be 19.8% more valuable. Hence, in the equilibrium 19.8% more ether would be purchased in the sale, so each unit would once again be exactly as valuable as before. The organization would also then have 1.198x as much BTC, which can be considered to be split into two slices: the original BTC, and the additional 0.198x. Hence, this situation is _exactly equivalent_ to the endowment, but with one important difference: the organization holds purely BTC, and so is not incentivized to support the value of the ether unit. - -The permanent linear supply growth model reduces the risk of what some see as excessive wealth concentration in Bitcoin, and gives individuals living in present and future eras a fair chance to acquire currency units, while at the same time retaining a strong incentive to obtain and hold ether because the "supply growth rate" as a percentage still tends to zero over time. We also theorize that because coins are always lost over time due to carelessness, death, etc, and coin loss can be modeled as a percentage of the total supply per year, that the total currency supply in circulation will in fact eventually stabilize at a value equal to the annual issuance divided by the loss rate (eg. at a loss rate of 1%, once the supply reaches 26X then 0.26X will be mined and 0.26X lost every year, creating an equilibrium). - -Note that in the future, it is likely that Ethereum will switch to a proof-of-stake model for security, reducing the issuance requirement to somewhere between zero and 0.05X per year. In the event that the Ethereum organization loses funding or for any other reason disappears, we leave open a "social contract": anyone has the right to create a future candidate version of Ethereum, with the only condition being that the quantity of ether must be at most equal to `60102216 * (1.198 + 0.26 * n)` where `n` is the number of years after the genesis block. Creators are free to crowd-sell or otherwise assign some or all of the difference between the PoS-driven supply expansion and the maximum allowable supply expansion to pay for development. Candidate upgrades that do not comply with the social contract may justifiably be forked into compliant versions. - -### Mining Centralization - -The Bitcoin mining algorithm works by having miners compute SHA256 on slightly modified versions of the block header millions of times over and over again, until eventually one node comes up with a version whose hash is less than the target (currently around 2192). However, this mining algorithm is vulnerable to two forms of centralization. First, the mining ecosystem has come to be dominated by ASICs (application-specific integrated circuits), computer chips designed for, and therefore thousands of times more efficient at, the specific task of Bitcoin mining. This means that Bitcoin mining is no longer a highly decentralized and egalitarian pursuit, requiring millions of dollars of capital to effectively participate in. Second, most Bitcoin miners do not actually perform block validation locally; instead, they rely on a centralized mining pool to provide the block headers. This problem is arguably worse: as of the time of this writing, the top three mining pools indirectly control roughly 50% of processing power in the Bitcoin network, although this is mitigated by the fact that miners can switch to other mining pools if a pool or coalition attempts a 51% attack. - -The current intent at Ethereum is to use a mining algorithm where miners are required to fetch random data from the state, compute some randomly selected transactions from the last N blocks in the blockchain, and return the hash of the result. This has two important benefits. First, Ethereum contracts can include any kind of computation, so an Ethereum ASIC would essentially be an ASIC for general computation - ie. a better CPU. Second, mining requires access to the entire blockchain, forcing miners to store the entire blockchain and at least be capable of verifying every transaction. This removes the need for centralized mining pools; although mining pools can still serve the legitimate role of evening out the randomness of reward distribution, this function can be served equally well by peer-to-peer pools with no central control. - -This model is untested, and there may be difficulties along the way in avoiding certain clever optimizations when using contract execution as a mining algorithm. However, one notably interesting feature of this algorithm is that it allows anyone to "poison the well", by introducing a large number of contracts into the blockchain specifically designed to stymie certain ASICs. The economic incentives exist for ASIC manufacturers to use such a trick to attack each other. Thus, the solution that we are developing is ultimately an adaptive economic human solution rather than purely a technical one. - -### Scalability - -One common concern about Ethereum is the issue of scalability. Like Bitcoin, Ethereum suffers from the flaw that every transaction needs to be processed by every node in the network. With Bitcoin, the size of the current blockchain rests at about 15 GB, growing by about 1 MB per hour. If the Bitcoin network were to process Visa's 2000 transactions per second, it would grow by 1 MB per three seconds (1 GB per hour, 8 TB per year). Ethereum is likely to suffer a similar growth pattern, worsened by the fact that there will be many applications on top of the Ethereum blockchain instead of just a currency as is the case with Bitcoin, but ameliorated by the fact that Ethereum full nodes need to store just the state instead of the entire blockchain history. - -The problem with such a large blockchain size is centralization risk. If the blockchain size increases to, say, 100 TB, then the likely scenario would be that only a very small number of large businesses would run full nodes, with all regular users using light SPV nodes. In such a situation, there arises the potential concern that the full nodes could band together and all agree to cheat in some profitable fashion (eg. change the block reward, give themselves BTC). Light nodes would have no way of detecting this immediately. Of course, at least one honest full node would likely exist, and after a few hours information about the fraud would trickle out through channels like Reddit, but at that point it would be too late: it would be up to the ordinary users to organize an effort to blacklist the given blocks, a massive and likely infeasible coordination problem on a similar scale as that of pulling off a successful 51% attack. In the case of Bitcoin, this is currently a problem, but there exists a blockchain modification [suggested by Peter Todd](https://web.archive.org/web/20140623061815/http://sourceforge.net/p/bitcoin/mailman/message/31709140/) which will alleviate this issue. - -In the near term, Ethereum will use two additional strategies to cope with this problem. First, because of the blockchain-based mining algorithms, at least every miner will be forced to be a full node, creating a lower bound on the number of full nodes. Second and more importantly, however, we will include an intermediate state tree root in the blockchain after processing each transaction. Even if block validation is centralized, as long as one honest verifying node exists, the centralization problem can be circumvented via a verification protocol. If a miner publishes an invalid block, that block must either be badly formatted, or the state `S[n]` is incorrect. Since `S[0]` is known to be correct, there must be some first state `S[i]` that is incorrect where `S[i-1]` is correct. The verifying node would provide the index `i`, along with a "proof of invalidity" consisting of the subset of Patricia tree nodes needing to process `APPLY(S[i-1],TX[i]) -> S[i]`. Nodes would be able to use those nodes to run that part of the computation, and see that the `S[i]` generated does not match the `S[i]` provided. - -Another, more sophisticated, attack would involve the malicious miners publishing incomplete blocks, so the full information does not even exist to determine whether or not blocks are valid. The solution to this is a challenge-response protocol: verification nodes issue "challenges" in the form of target transaction indices, and upon receiving a node a light node treats the block as untrusted until another node, whether the miner or another verifier, provides a subset of Patricia nodes as a proof of validity. - -## Conclusion - -The Ethereum protocol was originally conceived as an upgraded version of a cryptocurrency, providing advanced features such as on-blockchain escrow, withdrawal limits, financial contracts, gambling markets and the like via a highly generalized programming language. The Ethereum protocol would not "support" any of the applications directly, but the existence of a Turing-complete programming language means that arbitrary contracts can theoretically be created for any transaction type or application. What is more interesting about Ethereum, however, is that the Ethereum protocol moves far beyond just currency. Protocols around decentralized file storage, decentralized computation and decentralized prediction markets, among dozens of other such concepts, have the potential to substantially increase the efficiency of the computational industry, and provide a massive boost to other peer-to-peer protocols by adding for the first time an economic layer. Finally, there is also a substantial array of applications that have nothing to do with money at all. - -The concept of an arbitrary state transition function as implemented by the Ethereum protocol provides for a platform with unique potential; rather than being a closed-ended, single-purpose protocol intended for a specific array of applications in data storage, gambling or finance, Ethereum is open-ended by design, and we believe that it is extremely well-suited to serving as a foundational layer for a very large number of both financial and non-financial protocols in the years to come. - -## Notes and Further Reading - -#### Notes - -1. A sophisticated reader may notice that in fact a Bitcoin address is the hash of the elliptic curve public key, and not the public key itself. However, it is in fact perfectly legitimate cryptographic terminology to refer to the pubkey hash as a public key itself. This is because Bitcoin's cryptography can be considered to be a custom digital signature algorithm, where the public key consists of the hash of the ECC pubkey, the signature consists of the ECC pubkey concatenated with the ECC signature, and the verification algorithm involves checking the ECC pubkey in the signature against the ECC pubkey hash provided as a public key and then verifying the ECC signature against the ECC pubkey. -2. Technically, the median of the 11 previous blocks. -3. Internally, 2 and "CHARLIE" are both numbers, with the latter being in big-endian base 256 representation. Numbers can be at least 0 and at most 2256-1. - -#### Further Reading - -1. Intrinsic value: http://bitcoinmagazine.com/8640/an-exploration-of-intrinsic-value-what-it-is-why-bitcoin-doesnt-have-it-and-why-bitcoin-does-have-it/ -2. Smart property: https://en.bitcoin.it/wiki/Smart_Property -3. Smart contracts: https://en.bitcoin.it/wiki/Contracts -4. B-money: http://www.weidai.com/bmoney.txt -5. Reusable proofs of work: http://www.finney.org/~hal/rpow/ -6. Secure property titles with owner authority: http://szabo.best.vwh.net/securetitle.html -7. Bitcoin whitepaper: http://bitcoin.org/bitcoin.pdf -8. Namecoin: https://namecoin.org/ -9. Zooko's triangle: http://en.wikipedia.org/wiki/Zooko's_triangle -10. Colored coins whitepaper: https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit -11. Mastercoin whitepaper: https://github.com/mastercoin-MSC/spec -12. Decentralized autonomous corporations, Bitcoin Magazine: http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/ -13. Simplified payment verification: https://en.bitcoin.it/wiki/Scalability#Simplifiedpaymentverification -14. Merkle trees: http://en.wikipedia.org/wiki/Merkle_tree -15. Patricia trees: http://en.wikipedia.org/wiki/Patricia_tree -16. GHOST: http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf -17. StorJ and Autonomous Agents, Jeff Garzik: http://garzikrants.blogspot.ca/2013/01/storj-and-bitcoin-autonomous-agents.html -18. Mike Hearn on Smart Property at Turing Festival: http://www.youtube.com/watch?v=Pu4PAMFPo5Y -19. Ethereum RLP: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP -20. Ethereum Merkle Patricia trees: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree -21. Peter Todd on Merkle sum trees: http://sourceforge.net/p/bitcoin/mailman/message/31709140/ From d43c1ad3aa5ff86ad7df19daf40a0932a394f04f Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Sun, 7 Jan 2018 16:29:53 +1100 Subject: [PATCH 07/22] Add license, introduction, dapps --- Decentralized-apps-(dapps).md | 83 ++++++++++ Ethereum-introduction.md | 277 ++++++++++++++++++++++++++++++++++ LICENSE | 5 + 3 files changed, 365 insertions(+) create mode 100644 Decentralized-apps-(dapps).md create mode 100644 Ethereum-introduction.md create mode 100644 LICENSE diff --git a/Decentralized-apps-(dapps).md b/Decentralized-apps-(dapps).md new file mode 100644 index 000000000..1dbed731b --- /dev/null +++ b/Decentralized-apps-(dapps).md @@ -0,0 +1,83 @@ +Any good, service, governance or economic activity can be decentralized and tokenized with and transacted via Ethereum. The token represents the dapp (an abbreviation for decentralized app) while it uses the Ethereum blockchain, but the price of the token is different. Activity that has any economic or governance aspect, conceived or as of yet inconceived, can be done via Ethereum, provided that the right code is written and the necessary hardware is used (such as computers running an Ethereum node, and in some special cases, a measurement device to measure a resource flow for additional verification/auditable purposes, like a meter for electricity ⚡🔌, water 🚰 or gas 🔥; or a waste 🗑️ volume detector). Here's a challenge: keep an eye out for activity that has not been implemented on Ethereum (or could be implemented in a better way; check this article and research to check whether it's implementeId and if so, how well) and then: +
    +
  • develop a dapp for the idea yourself (after learning Solidity, if you don't already know it); or
  • +
  • sign an NDA with someone who is interested in developing dapps, share the idea, and form some agreement if they want to proceed with it (which could be proposed in the NDA itself), e.g. a founder's stake in an ICO, a salary, equity in the venture (although a community model more like Ethereum's non-profit foundation is better for a more equitable solution), royalties, a fee for every transaction, etc.
  • +
+ +This platform aspect of Ethereum has been referred to as a 'fat protocol' here, as opposed to the 'thin protocols' of Web 1.0 and 2.0 with HTTP, SMTP, etc., with the take home point (in bold) being: +
the market cap of the protocol always grows faster than the combined value of the applications built on top, since the success of the application layer drives further speculation at the protocol layer.
+One kind of application that is particularly intriguing is decentralized autononous organisations (DAOs, this includes entities as large as, or even larger than nation-states 🇦🇺🇺🇸🇮🇳🇬🇧🇨🇳🇧🇷🇷🇺🇯🇵, social networks, multinational public companies, etc.). Note that having complete autonomy is probably not a good idea, since code may not be able to handle new issues that arise, so human intervention should probably always be an option, but preferably in the hands of a small, non-profit entity or some decentralized solution (perhaps similar to the Aragon Network). By analogy, you wouldn't want a nuclear power plant to be completely automated with no possible means of human intervention. As a precaution, you'd want several safeguards including, for example, an off button 😉. As explained in this Ethereum Wiki here, the first DAO, known as The DAO, resulted in many funds being stolen, and Ethereum hard forking into Ethereum and Ethereum Classic. + +The following list is sourced from [Coin Market Cap tokens (you can sort by market cap)](https://coinmarketcap.com/tokens/) and State of the Dapps, both of which lists many more, as well as elsewhere, e.g. Gitter research room chats. (There are 854 dapps on State of the Dapps as of Dec 1 2017; then [909 on Jan 1 2018] (https://web.archive.org/web/20180101114436/https://www.stateofthedapps.com/). 😯 You can search by tags.) Other examples are also presented e.g. on day 4 of [Devcon 3](http://www.ryanyosua.me/devcon-3-talks/), as well as outlined in the Ethereum whitepaper in the introduction and applications section. Note also that while most of the dapps in the following list run on the Ethereum platform, some examples do not, and where they don't run on Ethereum, it is generally noted as what they do run on. This is not a big deal, as any dapp could theoretically run on another blockchain, (or indirectly via inter-blockchains like Cosmos or Polkadot) provided that the host blockchain has the required features. Also note that the below list is not an endorsement, and is not exhaustive or necessarily well-maintained. At worst, it's included because it was briefly looked into and it seemed like a good idea, while more time may have been spent doing due diligence on some ideas and can therefore have a better idea of its usefulness. Dapps that have been implemented, or are under development, or have been publicly conceptualised, includes: +* a stable coin, e.g. [Dai](https://makerdao.com/whitepaper/DaiDec17WP.pdf) +* smart contracts for the legally enforceable and/or liquid transfer of assets, plus related services e.g. [Mattereum](https://mattereum.com/) and [Sweetbridge](https://sweetbridge.com), e.g. settlement, accounting, risk management, resource sharing, and Optimization & Liquid Talent. Also, asset-based lending: secure loans with holding of assets e.g cryptocurrenices (locking them up) in exchange for cash (fiat currencies), such as Sweetbridge and [SALT](https://coinmarketcap.com/currencies/salt/); +* [Veritaseum](http://veritas.veritaseum.com/), which "enables software-driven P2P capital markets without brokerages, banks and traditional exchanges". +* [invoice financing with Populous](https://populous.co/) +* decentralized exchanges to buy and sell cryptos and fiat, e.g. localethereum; for cryptos only there is DecentrexOmega One and NVO, where the latter two have not been launched as of November 30. +* non-decentralized exchanges such as [Coinbase](https://www.coinbase.com/) (US), [BTCmarkets](https://btcmarkets.net/) (Australia), while more are below, or ones that only exchange cryptocurrencies like Poloniex; +* other exchanges like [OmiseGo](https://omisego.network/). "OmiseGO is a public Ethereum-based financial technology for use in mainstream digital wallets, that enables real-time, peer-to-peer value exchange and payment services agnostically across jurisdictions and organizational silos, and across both fiat money and decentralized currencies. Designed to enable financial inclusion and disrupt existing institutions, access will be made available to everyone via the OmiseGO network and digital wallet framework."; +* exchange platforms like [Binance](https://www.binance.com/aboutUs.html); +* asset exchanges like [WAX](https://wax.io/). +* the Brave browser (which the author uses) which uses the Basic Attention Token, which provides a better solution for users, publishers and advertisers; +* [MaidSafe](https://maidsafe.net/), which has another browser that actually runs on the [Omni](http://www.omnilayer.org/) layer that runs on Bitcoin, not Ethereum. It is also claiming to be: "The World's First Autonomous Data Network". [Currently you have to receive an invite which requires roughly an hour of interaction on their Discourse forum/site.](https://web.archive.org/web/20171230003420/https://invite.maidsafe.net/) +* [ZeroNet](https://zeronet.io/), another decentralized internet network that runs on Bitcoin cryptography and the [BitTorrent network](http://www.bittorrent.com/). [It on Ubuntu 17.10](http://127.0.0.1:43110/Talk.ZeroNetwork.bit/?Topic:1514631579_13fVMZu2wTNAykEvkYHYfGmTBMSFxz9gFG/It+would+be+good+if+you+could+link+to+a+comment). You can make [your own site](http://127.0.0.1:43110/1zz1z8YPFQizJshGkgHq7GVtBSPCyQM5W/), although [you may have issues with following a tutorial](http://127.0.0.1:43110/Blog.ZeroNetwork.bit/?Post:99:ZeroChat+tutorial#comment_1_13fVMZu2wTNAykEvkYHYfGmTBMSFxz9gFG). Note that this link won't work unless you are running ZeroNet.sh) by clicking the download button on the homepage (then as detailed concisely below the button) extracting it and running (in bash) `./ZeroNet.sh` while `cd`ed to the extracted folder that ZeroNet.sh is located in. +* storage, e.g. Swarm and a distributed hypermedia protocol, IPFS [website](https://ipfs.io/), [doc](https://github.com/ipfs/ipfs); +* communication protocols, e.g. Whisper (also see here for code), which allows dapps (you don't need to capitalize this since it is an abbreviation of decentralized applications) to communicate with each other; +* multi-chain networks/tools like [Polkadot](https://polkadot.io/) and [BTCRelay](http://btcrelay.org/) +* Ethereum Name Service (names like jamesray.eth map to an address); +* mesh networking e.g. implemented here and as voted for here on Twitter (which also has other ideas posted in the comments); +* social networks e.g. Akasha (news here), +* Status: "A Mobile Ethereum OS: Browse, chat and make payments securely on the decentralized web."; +* decentralized search engines, e.g. Weipoint (a news post is here); +* reputation and ratings network e.g. as used by [Etheal](https://etheal.com/), which is described below (CTRL+F); +* identity (e.g. as provided by uPort, as well as [in-blockchain proposal](https://www.ethnews.com/erc725-a-self-sovereign-identity-standard-for-ethereum and [Shyft](https://www.shyft.network/)); +* decentralized electricity trading and other decentralized energy economic applications, which would allow renewable energy to be more economical and accelerate the transition to a clean, renewable energy and safe climate future. + +Sun on Twitter Twemoji 2.3Wind Face on Twitter Twemoji 2.3Deciduous Tree on Twitter Twemoji 2.3Water Wave on Twitter Twemoji 2.3 + +Examples of local electricity trading include: Grid+, LO3/Transactive Grid, Power Ledger, Nexergy, Local Volts and Divvi. Grid+ uses Ethereum and they have open source code. Power Ledger has closed source code and runs on the Ethereum Enterprise Alliance, rather than the public Ethereum blockchain. They had a token sale in early October. Both Power Ledger and Grid+ also detail more unique applications in their pipeline, such as renewable energy asset generation (Power Ledger) and Grid+'s in-home computer, an "intelligent agent" that pays for a customers electricity in real-time, using stable tokens, stores cryptocurrency like the hardware wallet functions of Ledger and Trezor; providing Casper proof-of-stake signing, and provide an Ethereum API for IoT ([pp. 26 and 34-36, white paper](https://drive.google.com/file/d/0Bz90riPGRHquNDVXVE81RmppaUk/view)). Transactive Grid uses Ethereum and it has been rolled out in Brooklyn with a microgrid, however LO3 hasn't released any code or details for its Transactive Grid application. The others are still all under development (as of August 2017), and they have been scant on the details of how they would implement their application, at the least not releasing their code. Divvi say on its website that they will use the blockchain. Local Volts and Nexergy do not. +* electricity tokenization: e.g. SolarCoin, EnergyCoin, although both are altcoins rather than Ethereum tokens; +* governance of any organisation, e.g. Democracy.Earth; and also governance of DAOs, e.g. Aragon; +* decentralized search engines like [BitClave](https://www.bitclave.com/en/), [Weipoint](https://www.weipoint.com/) and [Epocum](https://www.stateofthedapps.com/dapps/epocum); +* wallets like MyEtherWallet or hardware wallets Trezor or Ledger; +* blockchain explorers like [Etherscan](https://etherscan.io/); +* a gateway to decentralized services such as [Infura](https://infura.io/); +* visit dapps in your browser with [Metamask](https://metamask.io/); +* decentralized media; +* asset titles (such as land titles). Read more on that here: "Having so far built the software and tested it with a couple dozen land title registrations, Bitfury and the Georgian National Agency of Public Registry have now signed a new memorandum of understanding to expand the service to purchases and sales of land titles, registration of new land titles, demolition of property, mortgages and rentals, as well as notary services". Nottar.io also provides notary services. A similar, more specific application is for academic certificates with [Smart Diploma](https://www.stateofthedapps.com/dapps/smart-diploma); +* Debit card 💳 transactions 🤝 (done on several exchanges 💱, e.g. Coinjar Swipe (but it accepts BTC only), Coinbase, while others which I've mentioned elsewhere in this article have plans to do this e.g. [OmiseGO](https://www.omise.co/go); +* co-ownership of real assets e.g. the [Swarm Fund](https://www.swarm.fund/how-swarm-works/index.html) +* crowdsales, e.g. an Initial Coin Offering (ICO) as compared with an Intial Public Offering (IPO), or for tokens with Ethereum: an Initial Token Offering (ITO). Note that this is not so much a business model in itself, per se, rather it is more of a fundraising method (which has also led to scams, e.g. here); +* crowd development (but not as part of the blockchain, e.g. here), e.g. for infrastructure and other public assets; +* think of public companies being remodelled into communities with tokens instead of shares, governance using a platform like Democracy.Earth (which can be tailored to have voting anywhere between one vote one person like direct democracy, or conventionally more hierarchical like a board of directors and token-holders instead of or in addition to—and probably eventually superceding—shareholders); +* dividend payouts and secure email-based transactions with [Dividend](https://www.dividend.cloud/). For sending ETH via email there is also [You've Got ETH](https://www.stateofthedapps.com/dapps/you-ve-got-eth); +* prediction 🔮 🦉 markets like GNOSIS, Augur and [WINGS DAO](https://www.stateofthedapps.com/dapps/wings-dao); +* [Built-in price discovery and a liquidity mechanism for tokens with Bancor](https://www.bancor.network/); +* labour/recruitment/freelance markets like Chronobank and [Ethlance](https://ethlance.com/); +* permissioned distributed ledgers like [Hydrachain](http://www.brainbot.com/projects#hydrachain); +* trust-based models like the [Trustlines Network](http://trustlines.network/) +* Secure distributed computing, e.g. Golem. Ethereum needs to be faster e.g. with EWASM and parallelizability. +* accountability, e.g. for non-profits (e.g. "how do I know how badly you need a donation unless I can see your net liabilities, net assets, and balance sheet, and how you plan to use the funds?") and aid (also see here) +* Self Learning, Autonomous, Decentralized Artificial Intelligence (this could be used for many things such as self-driving cars, robots, or anything else that is owned by a contract; bots; and art); +* decentralised financial services like [WeTrust](https://www.wetrust.io); +* futures-like dapps such as [TimeBank](https://www.stateofthedapps.com/dapps/timebank) and [hodlethereum](https://hodlethereum.com/); +* sharing car refueling stations with [Share&Charge](https://www.stateofthedapps.com/dapps/share-charge); +* health, e.g. [Etheal](https://etheal.com/), a healthcare service comparison site with a content platform, trust and review / reputation system; an anonymous marketing platform for surveys, ads and communication research where users are paid by pharmaceutical companies; and a platform for building health apps; +* examples of contracts are [here](https://solidity.readthedocs.io/en/develop/solidity-by-example.html) and [here](https://viper.readthedocs.io/en/latest/viper-by-example.html), e.g. voting, auctions (open or blind), safe remote purchases, micropayment channels, crowdfunding and company stock. Many more can be found on Github, which may be referenced from the whitepaper and the website of a dapp. +* [insurance](https://www.stateofthedapps.com/tagged/insurance/); + + +Examples that have been conceptualized, but not implemented (at least as far as the creator of this wiki is aware of) include: +* reducing transaction costs for existing business models (here is a good read about that). However, to tokenize online centric business models, the network model should change from client-server to peer-to-peer, to avoid a conflict of interest. This is more difficult to achieve since a server is a piece of infrastructure, and transferring to a peer-to-peer model would cause it to be a sunk cost. Additionally, it may be difficult to build a replacement dapp for a successful website, because it is hard to get a network of engaged users to change to using something else (inertia). Centralized web apps (not just mobile apps but websites, and use the word to contrast with dapps) include: +* * Google (although note [Weipoint](https://www.weipoint.com/) as mentioned previously), +* * social networks like [Facebook](http://www.trustnodes.com/2018/01/04/zuckerberg-studying-cryptocurrency-implementation-facebook), Twitter, (although note [Akasha](https://akasha.world/) above); +* * online marketplaces e.g. Amazon, eBay and Alibaba (decentralized alternatives include [Soma for products or services](https://soma.co/), [Canya for services](https://canya.io/) also note this simple implementation and subreddit [here](https://www.reddit.com/r/ethmarket/), as well as more specific or niche marketplaces like [Cryptokitties](https://www.cryptokitties.co/), [Hamster](https://hmstr.io/)). For more info see [here](https://www.forbes.com/sites/rogeraitken/2017/10/24/whats-the-future-of-online-marketplaces-blockchains-technology-impact/#3f6bde2a63a0) +* making economically viable other business models that have seen low uptake or aren't economically viable without blockchain tech. So-called sharing economy business models (which are more aptly called tasker or rentier capitalism models) like Airbnb, Uber, AirTasker, Fiverr, Upwork, TaskRabbit, and Menulog are particularly ripe for transformation (the term transformation is preferrable to disruption, since it should be a net positive change, while negative effects are manageable or solvable), since no trusted third party for a transaction is needed, such as banks 🏦, credit card 💳 companies or PayPal, just a smart contract; and +* mortgage brokers; +* More examples are here—scroll to the examples—they have bold headings and are about two thirds of the way down, or search for "Dank meme trading". Note that the Basic Attention Token has already been mentioned, and the creator of this wiki is skeptical that AI will create truly beautiful art, since no AI can have any feeling. CryptoKitties is an example of meme trading and has taken up [a lot of the transactions on the Ethereum network](https://etherscan.io/address/0x06012c8cf97bead5deae237070f9587f8e7a266d). +* curation markets, which is part of what [Steemit](https://steemit.com/@jamesray/feed) does (which runs on the STEEM network), and which curators, social networks and wiki authors would all benefit from. More info is [here](https://medium.com/@simondlr/introducing-curation-markets-trade-popularity-of-memes-information-with-code-70bf6fed9881); +* [P2P Decentralised Autonomous Transportation Network](http://www.flyingcarpet.network/) +* [Waste collection management](https://twitter.com/JamesCRay01/status/936992945173020672). Other ideas include plus generally thinking of existing business models running on the blockchain, like real estate developers and investment trusts (with which blockchains could be used e.g. for crowdfunding). +* legally enforceable wills running on the blockchain, as well as being able to appoint an executor in a legally enforceable way on the blockchain. + +More examples are e.g. [here in a blog post](https://medium.com/@Ethereum_AI/ethereum-introduction-what-exactly-is-it-why-care-how-to-invest-9a627ab04408) and [here on Wikipedia](https://github.com/Ethereum-community/Ethereum-introduction/wiki/Decentralised-apps-(dapps)) diff --git a/Ethereum-introduction.md b/Ethereum-introduction.md new file mode 100644 index 000000000..8d6a862fb --- /dev/null +++ b/Ethereum-introduction.md @@ -0,0 +1,277 @@ +![Ethereum Homestead gold ingots](https://sustergy.files.wordpress.com/2017/05/ethereum-homestead-background-17.jpg?w=1000) + +Note that due to the lightning-fast pace of development in the Ethereum space with core development and dapps continually being launched, certain parts of this article may be outdated. You can help by keeping it up to date! + + + +Table of Contents +================= + + * [Table of Contents](#table-of-contents) + * [About Ethereum](#about-ethereum) + * [Uses](#uses) + * [List of dapps](#list-of-dapps) + * [Market analysis](#market-analysis) + * [Issues](#issues) + * [Scalability](#scalability) + * [Proof of work / proof of stake / other proving methods](#proof-of-work--proof-of-stake--other-proving-methods) + * [Public permissionless blockchains vs. private permissioned blockchains](#public-permissionless-blockchains-vs-private-permissioned-blockchains) + * [No technological artefacts can be a panacea](#no-technological-artefacts-can-be-a-panacea) + * [How do you buy and sell Ether, the currency of Ethereum?](#how-do-you-buy-and-sell-ether-the-currency-of-ethereum) + * [Table of exchanges](#table-of-exchanges) + * [More details about what I've tried (not very necessary to know)](#more-details-about-what-ive-tried-not-very-necessary-to-know) + * [Development](#development) + * [Concluding remarks](#concluding-remarks) + * [Further reading](#further-reading) + +# About Ethereum +Ethereum is a [decentralized](https://medium.com/@VitalikButerin/the-meaning-of-decentralization-a0c92b76a274) blockchain platform for "building unstoppable applications", while Ether is the cryptocurrency used on this platform. Ethereum has been described in several ways, such as (the first and third resources are more general introductions, while the second is a technical introduction, although all are outdated. +Another introduction is available [here](https://bitsonblocks.net/2016/10/02/a-gentle-introduction-to-ethereum/), but again, it is outdated. Despite being outdated, Ethereum has maintained backwards compatibility thus far up till January 1 2018, so the info is still relevant.): + +Let's briefly breakdown what those terms mean. + +**Decentralized** technology uses [peer-to-peer computer networks](https://en.wikipedia.org/wiki/Peer-to-peer) (there's a picture below), and are not subject to the whims of a central authority such as a government or server administrator (like Google or Facebook) which can help to achieve better decision making for public good. **Blockchain** means that the currency is built and secured by adding and verifying blocks of transactions to blocks made previously, thus forming a "chain". Blocks added to the chain become harder and harder to crack over time, as they are verified by more nodes in the blockchain peer-to-peer network. Blockchain technology has been referred to as the **Web 3.0**. The world wide web (retroactively the Web 1.0) consisted of websites publishing content and users passively reading/viewing it. The Web 2.0 used user interaction, such as forums (with upvoting and commenting), reaction buttons (e.g. the Facebook reactions: likes 👍, love ❤️ , laughter 😆, wow 😲, sad 😢, angry 😠), sharing (republishing), however these interactions have no direct economic effect on the host website; users do not share in the value generated from the website. The Web 3.0 is starting to be defined as the movement away from centralisation of computation power in servers which provide services to clients (known as the client-server network model) to peer-to-peer networks and blockchains, and from centralisation of authority and sovereignty from nation-states and corporations to the networked individual. + +![server-based-network](https://sustergy.files.wordpress.com/2017/05/200px-server-based-network-svg.png) +![p2p-network](https://sustergy.files.wordpress.com/2017/05/200px-p2p-network-svg.png) + +**Cryptocurrency** refers to a a digital currency that secures transactions with cryptographic code, which is solved through hardware computational power (known as mining or proof of work) or other less energy-intensive ways such as proof-of-stake. (There are more details on that below.) + +Zero knowledge proofs like ZK SNARKs can also be used to make cryptocurrency transactions more private 🕵️ or secret 🤐 (which is different to being secure 🔒), thus negating the need to run applications on a permissioned private network like the [Ethereum Enterprise Alliance](https://entethalliance.org/). Ethereum uses [precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128](https://github.com/ethereum/EIPs/pull/213), for [pairing checks](https://github.com/ethereum/EIPs/pull/212), which permit [zk-SNARKs](https://blog.ethereum.org/2017/10/12/byzantium-hf-announcement/), also see [here](https://medium.com/@VitalikButerin/zk-snarks-under-the-hood-b33151a013f6), [as implemented](https://github.com/ethereum/EIPs#finalized-eips-standards-that-have-been-adopted) in the [Byzantium hard fork](https://blog.ethereum.org/2017/10/12/byzantium-hf-announcement/). There is also the Zerocoin protocol which is demonstrated by Zcoin (which plans to integrate Ethereum). + +# Uses +The platform part of Ethereum makes it much more useful than just a cryptocurrency. With it, you can create any decentralized application (known as a dapp, which works over a peer-to- peer network rather than a centralized client-server network 💻🕸️), so the functionality is only limited by what programs could potentially do and not do, and by consequence, what programmers develop, 👨‍💻 but it can theoretically be used for any economic or governance activity. + +## List of dapps + +For a list of dapps, visit [here](https://github.com/Ethereum-community/Ethereum-introduction/wiki/Decentralised-apps-(dapps)). + + +*** + + +However, there are several issues that will need to be resolved to help Ethereum be used to its full potential, which are described below. + +## Market analysis +As of the 1st of December 2017, [the market capitalisation of Ethereum is $32.6 billion USD](https://cryptolization.com/ethereum) (refer to the link for the latest figure), and [it has been in circulation possibly since 30 July 2015](https://github.com/jamesray1/homestead-guide/blob/32d2fa4ccfa3d45f8493a673a08247450d55fea0/source/introduction/the-homestead-release.rst#milestones-of-the-ethereum-development-roadmap), with the [first transaction using Ethereum on 8 August 2015](https://www.etherchain.org/account/0x5abfec25f74cd88437631a7731906932776356f9). Compare this with the next largest and the current largest cryptocurrency, [Bitcoin, with a market cap of $41.0 b. US](https://cryptolization.com/ethereum), where [it has been in circulation since January 2009](http://www.newyorker.com/reporting/2011/10/10/111010fa_fact_davis). Technically, Ethereum has had a much faster growth rate, while more importantly for long term investment (I do not encourage speculation as that only causes volatility as has been seen) the fundamentals are much better than Bitcoin. While it is true that Bitcoin has more of a market and currency, e.g. in terms of more entities that will accept it as a form of payment, the creator of this wiki expects that time will change that (indeed the market cap of Ethereum recently surpassed half that of Bitcoin, around May 2017). Also, [the number of transactions of Ethereum surpassed that of several cryptocurrencies combined on 22 Nov 2017](https://www.reddit.com/r/ethereum/comments/7est9k/ethereum_is_now_processing_more_transactions_a/). However, note [this retort](https://www.reddit.com/r/ethereum/comments/7est9k/ethereum_is_now_processing_more_transactions_a/dq7a31u/). + +# Issues +There also several issues with Ethereum, such as not being scalable enough, not being full decentralized, energy consumption with mining, if quantum computing advances it would be insecure (but this is being fixed). With its [large storage database](https://www.reddit.com/r/ethtrader/comments/7axn5g/ethereum_blockchain_sizewe_have_a_problem/) (I have to provide a [Reddit link](https://www.reddit.com/r/ethtrader/comments/7axn5g/ethereum_blockchain_sizewe_have_a_problem/) as a source as the [original link](https://etherscan.io/chart/chaindatasizefull) doesn't have the graph any more, while [Wayback doesn't render it either](https://web.archive.org/web/20171211015955/https://etherscan.io/chart/chaindatasizefull).), mining and architecture requiring to run a full node to mine or validate transactions, it is not decentralized enough. More (outdated but still applicable) info on that is e.g. [here](https://ethereum.stackexchange.com/questions/143/what-are-the-ethereum-disk-space-needs#826), as well as [here](https://github.com/ethereum/go-ethereum#full-node-on-the-main-ethereum-network). + +## Scalability + +Ethereum will need to scale to process far more transactions per second (to become a "world computer") than Visa, Mastercard and American Express combined (which process on the order of [tens of thousands of transactions per second](https://usa.visa.com/run-your-business/small-business-tools/retail.html) [in the link, CTRL+F 24,000]), while Ethereum 1.0, the current version as of December 30 2017, processed [a record of 1103523 transactions on Friday, December 22, 2017, or 12.77 transactions per second](https://web.archive.org/web/20171230005127/https://etherscan.io/chart/tx). + +Note that [Ripple claims that it's Consensus Ledger can process a thousand transactions per second](https://ripple.com/dev-blog/ripple-consensus-ledger-can-sustain-1000-transactions-per-second/), while it could process more with payment channels. "Although payment channels achieve practically infinite scalability by decoupling payment from settlement, they do so without incurring the risk typically associated with delayed settlement." Further note that Ripple achieves this by trading off on decentralization, through a [distributed network of validators or distributed servers](https://ripple.com/build/xrp-ledger-consensus-process/), while it has been described as a [federation protocol](https://wiki.ripple.com/Federation_protocol). + +There are even more scalable blockchains that use a delegated proof of stake (DPOS) consensus protocol, such as Bitshares and Steem. [Bitshares can apparently process 100,000 TPS](https://bitshares.org/technology/industrial-performance-and-scalability/). + +More generally, in order to have faster payments or higher transaction throughput, you need to reduce the number of validators (miners are a kind of validator that perform energy intensive computational work, finding a random nonce or sequence number in a large set of numbers) in the consensus protocol, or reduce the other (i.e. for faster payments you can reduce transaction throughput or reduce validators, while for higher transaction throughput you can reduce validators or have payments take longer to finalize). This is [a trade-off triangle](https://twitter.com/VladZamfir/status/932319930363494400). You could potentially have one blockchain with [heterogeneous sharding](https://twitter.com/VladZamfir/status/932320997021171712), with different shards with a different degree of balance between these properties. Ethereum is working on [sharding](https://github.com/ethereum/sharding/blob/develop/docs/doc.md), which includes using [stateless clients](https://github.com/ethereum/sharding/blob/develop/docs/doc.md#stateless-clients) (while more on that is [here](https://ethresear.ch/t/the-stateless-client-concept/172/14)). + +If you increase scalability in an instant via some blockchain or shard, while keeping latency constant (or reducing it) you need to reduce decentralization, which reduces the number of points of attack needed to compromise the whole network, i.e. reducing decentralization reduces security. + +## Proof of work / proof of stake / other proving methods +The mining process to crack cryptographic code (specifically to discover the nonce, a very large number, for each block by trial and error) requires a lot of computation power. Nevertheless, I'm guessing that the computation power should be less when you consider the energy consumption of incumbent financial systems. (Think of extracting and processing resources to make coins and notes, minting and printing, energy consumption of banks and tiers of related energy consumption in the life cycle of fiat money.) Still, developers of some cryptocurrencies such as Ethereum are transitioning to (as is the case for Ethereum), or already using, a different way of maintaining and creating blocks, known as proof of stake. For more information, you can see this Proof of Stake Wikipedia article here (although note the header warning about the article potentially not being verifiable or neutral due to relying heavily on sources too closely associated to the subject). The tricky part is in getting proof methods to work better than proof of work, as outlined here in the criticism section of the PoS Wiki. + +## No technological artefacts can be a panacea +For the continual improvement of humanity, there needs to be balance in life between things that benefit us materially and things that benefit us on higher levels, particularly spiritually. There is a risk that technology can make some people better off, and others worse off. So there needs to be consideration for how technology can be implemented to maximise [utility](https://en.wikipedia.org/wiki/Utilitarianism). One consideration of that is [here](https://medium.com/@RhysLindmark/co-evolving-the-phase-shift-to-cryptocapitalism-by-founding-the-ethereum-commons-co-op-f4771e5f0c83). + +## There's a risk of attacks from quantum computing, if it becomes performant enough + + + +# How do you buy and sell Ether, the currency of Ethereum? + +Summary: compare deals with buying and sell through different exchanges such as P2P ones with an arbitrator like [**LocalEthereum**](https://localethereum.com), or with centralized exchanges (which vary with your local jurisdiction, e.g. in Australia there is [BTCmarkets](https://btcmarkets.net/fees) and in the US plus worldwide there is [Coinbase](https://www.coinbase.com), which also allows you to spend cryptocurrencies e.g. with a debit card. For more see the table below, [here](https://github.com/jamesray1/Ethereum-introduction/wiki/Ethereum-introduction#table-of-exchanges)). + +The simplest way may be to use [**LocalEthereum**](https://localethereum.com), where you don't need to go through KYC processes. The creator of this wiki has found that "I can **sell Ether for a better deal** than I can find with an exchange, without any trading or withdrawal fees, apart from those associated with different payment methods". I like that it has lower fees compared to exchanges. I also read about how the localethereum platform works, and it seems pretty secure. The maker fee (which is what the party of the trade that puts up the offer) is 0.25% while the taker fee is 0.75%. [BTCmarkets](https://btcmarkets.net/fees) has higher fees compared to the maker fee, and higher than the taker fee if the amount is below $3000. Additionally, there have been hacks with exchanges like Mt. Gox and Bithumb. That's harder to achieve with localethereum since they can't get access to your funds, they can only settle disputes (if they arise) by sending the funds in the escrow to the buyer or the seller. However, I have been able to find a **better deal**, at least at certain times, with buying Ether if I buy through [**BTCmarkets**](https://btcmarkets.net/fees), although that would be slower via BPAY with bank transfer than paying via cash deposit via an ATM or bank." + +More information about Ether is [here](http://ethdocs.org/en/latest/ether.html). + +Disclaimer from the creator of this wiki: I have put most of my funds in Ether, the currency of Ethereum. Does that shock you? 😲 Yep, it's risky, but I've done due diligence 🔍 with fundamental analysis, and a little bit of sentiment and technical analysis, and I think that the market cap of Ether will continue to grow 🌱🌳 and increase, albeit with some volatility 📈. I consider it a digital currency that is in a pioneering, rapid growth stage of development (fuelled by a lot of genuine uptake of the currency as well as speculation about its future value, if not its current value), not just an asset. I hope my post will outline why investing in Ether is a good idea (and not just investing a small percentage of your cash, unless you are tied up with a mortgage 🏠 or have other monetary or non-monetary ties or circumstances that limit your investable capital). However, if you don't want to risk the downside volatility, e.g. if you don't have any risk capital, then you may want to consider buying a stable coin like [Dai Coin](https://makerdao.com/) instead. + +Based on my research below, if you're in Australia 🇦🇺 (otherwise skip to the next paragraph), I recommend creating an account with BTCmarkets.net, verifying your ID, and using BPAY or PoliPayments to deposit AUD. Note that the rest of the following info in this paragraph is outdated since MEBank used to not support BPAY publicly, but now they do. If your bank doesn't support PoliPayments and you want to use that instead of BPAY, although I can't think of any good reason why you'd want to use PoliPayments over BPAY, then you can set up a bank account with BOQ (or any other bank that supports POLi Payments, doesn't invest in fossil fuels and has no fees for transaction and savings accounts [note that Bendigo doesn't have an Ultimate Everyday account any more]. You can probably ignore the interest rate since it is so marginal compared to other bank's rates and the gains that you are likely to make by holding funds with Ether instead. However, when I did research for interest rates I found that ME Bank savings rates were second only to UBank, which invests in fossil fuels indirectly as it is owned by NAB. + +## Table of exchanges + +You can use [localethereum](https://localethereum.com) anywhere, but in my experience you may not get as good a deal as buying it on a local exchange. + +If you're not in Australia 🇦🇺, then here's a comparison of exchange rates 💱 for fiat to crypto- and crypto- to crypto- currencies (note that there is still a focus on Australia, but you can click on the links to get more information of the fees): + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 Exchange link (may go to a fees page)Fiat to crypto exchange fee buy/sell spread
BTCmarketsAUD is the only fiat currency. 0.85% trading fee. Funds available to deposit, withdraw, buy and sell are: AUD, ETH, ETC, BTC and LTC. To deposit AUD, you need to verify your account and then use POLi Payments (available banks are here. My bank is ME Bank, which doesn't support POLi Payments. I applied with BOQ because they do support POLi Payments, they don't invest in fossil fuels [like ME Bank] and they have transaction and savings accounts with no fees [like ME Bank].)
GDAX0.25/.3% maker fee low volume, 0% taker fee BTC for USD/EUR/GBP, ETH/LTC for USD/BTC/EUR
Coinjar, has a debit card with accounts for Ether, BTC, XRP and LTC.1.00% AUD/BTC (and only AUD/BTC)
CoinbaseIn Aus: 3.99% credit/debit card only (no other transaction method accepted). Other fiat and crypto currencies are available.
CEX7% BTC/ETH for USD/EUR/GBP/RUB
ice3x1% ZAR/BTC
LunoZAR/BTC fee not easy to find
okcoinCNY/USD for BTC/LTC, fee not easy to find
MaicoinTN/BTC Fee not shown, claimed none
+ + + + + + + + + + + + + + + + + + + + + + + +
Crypto to crypto exchange fee / buy/sell spread
Poloniex0.15/.25% BTC/ETH “maker-taker” (presumably the same as buy-sell)
gdax.com/fees/0.25/.3% maker fee low volume, 0% taker fee ETH/LTC for BTC
Exodus~0.4720–.528% BTC/ETH variable. Desktop app. Sometimes currencies are not available for exchange!
NVODecentralised. ICO 05/27/17 02:00 UTC to 06/27/17 02:00 UTC
+ +Exchanges are listed in [this article](https://medium.com/@Ethereum_AI/ethereum-introduction-what-exactly-is-it-why-care-how-to-invest-9a627ab04408), which I've copied and pasted (repetition is OK): + +**America, US dollars** + +https://www.coinbase.com + +https://gemini.com/ + +**Australian Dollar** + +https://btcmarkets.net/ + +**Canadian Dollar** + +https://www.quadrigacx.com + +**Chinese Yuan** + +https://www.huobi.com + +https://www.okcoin.com + +https://yunbi.com + +**European Euros** + +https://www.kraken.com + +**India** + +https://duckduckgo.com/?q=Ethereum+exchange+india&t=brave&ia=web + +**Mexican Peso** + +https://bitso.com + +**South Korean Won** + +https://coinone.co.kr/ + +https://www.bithumb.com/ + +## More details about what I've tried (not very necessary to know) + +I bought BTC in a different way. Step 2 worked for me. I will try step 1 next time I buy more BTC. + +I created an account on btcmarkets.net, verified my email address, tried to login, but couldn't. I tried to disable two factor authentication, but it asked for my mobile number, which I didn't enter when I created my account. I tried to reset my password and log in again, but that didn't work. I entered my email address correctly. I sent a message to support to ask for help. I figured out that my password was too long, and have notified btcmarkets.net. After creating a password of 23 characters, I was able to log in. I created another password of 56 characters using Chinese characters, emojis and ASCII characters, and was able to log in. (Incidentally, it is a hassle to do this, so a decentralised, private password generator would be wonderful.) + +The following steps are what I have tried so far, in detail. +
    +
  1. Convert AUD to Bitcoin (BTC) via an exchange like Coinjar. I left a review of Coinjar here. Fee: 1%. While this step is tailored for Australia, it can be adapted to any country that has a bitcoin exchange.
  2. +
  3. I created a Poloniex account, sent funds from got the Bitcoin deposit address, then sent my BitGo funds to that address. Once the transaction completed, I then used Poloniex Exchange to convert to Eth, with a maker-taker fee of: 0.15/0.25%.
  4. +
+Before step 2 above, I tried the following: +
    +
  1. Create an Ethereum Wallet 👛 like MyEtherWallet. Unfortunately Mist, a program being developed by Ethereum that has a browser and a wallet is still a pre-release, so it may not be very suitable for end users just yet.
  2. +
  3. Convert BTC to Ether (ETH) via a cryptocurrency exchange like Shapeshift. Use a precise transaction, make sure the amount is within the min. and max. deposit. Copy and paste the bitcoin address in Coinjar by signing in (if you aren't already) and going to Accounts > Everyday Bitcoin > View address. Put this address as the refundable address. Copy and paste the address from MyEtherWallet. Put this as the destination address. Tick the box to save the destination address for future payments. However, this didn't work.
  4. +
+I also sent an email to Coinjar to suggest that they develop functionality for purchasing Ether directly using AUD. You can do the same with the exchange of your choice. + +I have been able to deposit funds into Coinjar (needing to be less than the transaction limits) but have not been able to get Eth funds as of yet. I have also tried to create an account on BitGo, send coins from Coinjar to BitGo, and use Shapeshift with that account and still with MyEtherWallet, however that didn't work. + +I will not discuss trading (which I mean buying with the intention to sell most or all of the purchase at any future time particularly in the short term in order to realize a profit) as I am not very interested in trying to guess the short-term direction of markets (although I admit that trading helps to provide liquidity). + +# Development +Are you interested in learning to develop smart contracts with Ethereum, and maybe develop a really useful dapp and become a millionaire? + +Check out the [Ethereum website](https://www.ethereum.org/)! Then, you can [read the Solidity docs](https://solidity.readthedocs.io/en/develop/). + +If you want to help contribute to core development, there is also: +* the [Yellow Paper](https://github.com/ethereum/yellowpaper/pull/376) (make sure that you read the [EIPs](https://github.com/ethereum/EIPs) too since as of Dec 8 it is not up-to-date with the last commit on August 8, while the Constantinople EIPs were implemented in October). Instead I recommend ; +* Learn Python first, e.g. with [Learn Python the Hard Way](https://www.learnpythonthehardway.org/) (I learnt using this, it's pretty good), [Codecademy](https://www.codecademy.com/learn/learn-python), [Pydocs](https://docs.python.org/3/), [Coursera](https://www.coursera.org/courses?languages=en&query=learn+python), etc. Knowing Python is useful for [pyethereum](https://github.com/ethereum/pyethereum), which is being used as an Ethereum client, to implement Serenity and sharding, as well as [vyper](https://github.com/ethereum/Vyper), an experimental, secure smart contract programming language; +* [LLL](https://media.consensys.net/an-introduction-to-lll-for-ethereum-smart-contract-development-e26e38ea6c23) (also see [here](https://github.com/ethereum/solidity/tree/develop/liblll) and [here](https://github.com/ethereum/solidity/tree/develop/lllc)); +* [JULIA](https://solidity.readthedocs.io/en/develop/julia.html), an intermediate language for different Ethereum virtual machines; +* clients such as [Geth](https://github.com/ethereum/go-ethereum), [Parity](https://github.com/paritytech/parity) which is under [Parity Tech](https://github.com/paritytech) a separate organization to the Ethereum Foundation, [C++ Ethereum](https://github.com/ethereum/cpp-ethereum), [Pyethereum](https://github.com/ethereum/pyethereum); +* [Serenity](https://github.com/ethereum/pyethereum/tree/serenity); +* [sharding](https://github.com/ethereum/sharding/blob/develop/docs/doc.md); +* [research](https://github.com/ethereum/research) such as stateless clients, sharding, scalability improvements, Casper and more; +* [EWasM](https://github.com/ewasm); +* if you're interested in testing, see the documentation [here](https://ethereum-tests.readthedocs.io/en/latest/), as well as [the Github tests repo](https://github.com/ethereum/tests), [a Gist here (it is outdated)](https://gist.github.com/Souptacular/fd197b1fac7c6d2660b0bef27a33ed40#lll-and-evm-stack-resources), and [Gitter here](https://gitter.im/ethereum/tests) ; and +* [many other repositories](https://github.com/ethereum). + +# Concluding remarks + +Ether certainly seems like a good investment, and a good alternative to using fiat currencies, as well as an enabler for otherwise uneconomical business, due to lower transaction costs. It's more decentralized nature than central banks has advantages for trade from a local to global scale. With governance applications and systems on top Ethereum, it is even possible to do away with the hindering borders surmounted by nation-states. By doing away with these borders, society can be more open, inclusive and equitable. + +However, all technology can only help mankind and the world to a certain extent. What is more important is for each and every person to become increasingly blissful. Each person must go within and enter a stillness of body and mind, which is when that bliss starts to manifest, and practice balanced living. Practicing certain techniques such as those given by Self-Realization Fellowship, such as daily Kriya yoga meditation, developing unconditional love that starts in the heart, keeping the mind at the point between the eyebrows, and moral living, helps each person manifest that bliss within, and from there, express that bliss outwardly at all times. + +# Further reading + +* [Another introduction](https://github.com/jamesray1/Ethereum-introduction/wiki/Ethereum-introduction) +* [MyEtherWallet knowledge base (good for issues with wallets)](https://myetherwallet.github.io/knowledge-base/) +* [An introduction (Frontier first release, outdated)](https://ethereum.gitbooks.io/frontier-guide/content/ethereum.html) +* [Here's another introduction, made in November 2017](https://medium.com/@Ethereum_AI/ethereum-introduction-what-exactly-is-it-why-care-how-to-invest-9a627ab04408) +* [Ethereum community on Gitter](https://gitter.im/ethereum) +* [Ethereum research forum](https://ethresear.ch/) +* [Correct by construction Casper prototype](https://ethresear.ch/t/the-correct-by-construction-casper-paper-prototype-published-at-devcon-tear-it-apart/196) +* [Casper the Friendly Finality Gadget](https://ethresear.ch/t/latest-casper-basics-tear-it-apart/151/57) +* [The stateless client concept](https://ethresear.ch/t/the-stateless-client-concept/172) +* [Ethereum 2 and alternative PoS implementations](https://ethresear.ch/t/ethereum-2-and-alternative-pos-implementations/190/7) +* [Ethereum wiki](https://en.wikipedia.org/wiki/Ethereum) +* [Ethereum and the hodlers that love them](https://www.reddit.com/r/ethtrader/comments/6jyn9y/ethereum_the_hodlors_that_love_them/) + + +This article was originally created here in May 2017, and has been regularly updated since then: https://sustergy.wordpress.com/2017/05/18/why-buy-ether-and-how/. Feel free to send a donation to the initial author at jamesray.eth, or make edits to it yourself, or fork it! diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..40d9af62e --- /dev/null +++ b/LICENSE @@ -0,0 +1,5 @@ +The license for this repository is CC BY-SA 4.0. + +A human-readable summary (and not a substitute) of the license is [here](https://creativecommons.org/licenses/by-sa/4.0/). + +The license is [here](https://creativecommons.org/licenses/by-sa/4.0/legalcode). From 57544526099cb3911a7f9b7db21f62c93acd0c8e Mon Sep 17 00:00:00 2001 From: jamesray1 <16969914+jamesray1@users.noreply.github.com> Date: Tue, 29 May 2018 18:23:05 +1000 Subject: [PATCH 08/22] Update the README to only refer to wiki/wiki, and delete everything else. --- Adaptive-Message-IDs.md | 70 - Adaptive-Peer-Time.md | 25 - Bad-Block-Reporting.md | 126 - Bad-Chain-Canary.md | 19 - Block-Protocol-2.0.md | 255 -- Blockchain-import-and-export-instructions.md | 39 - Brain-Wallet.md | 38 - CLL.md | 166 -- Chain-Fibers-Redux.md | 121 - Clearinghouse.md | 63 - Contract-Metadata-Docs-(NatSpec,-ABI).md | 92 - Dagger-Hashimoto.md | 338 --- Dagger.md | 96 - Dapp-Developer-Resources.md | 17 - Dapp-using-Meteor.md | 209 -- Decentralized-apps-(dapps).md | 83 - Default-Extra-Data-Standard.md | 16 - Deterministic_Wallet_Spec.md | 22 - Distributed-Preimage-Archive.md | 86 - EVM-JIT-Binary-Interface.md | 79 - Ethash-C-API.md | 59 - Ethash-DAG-Disk-Storage-Format.md | 26 - Ethash-Design-Rationale.md | 26 - Ethash.md | 998 ------- Ethash_revision_11.md | 249 -- Ethereum-Contract-ABI.md | 383 --- Ethereum-Development-Tutorial.md | 166 -- Ethereum-Natural-Specification-Format.md | 138 - Ethereum-Wire-Protocol.md | 116 - Ethereum-introduction.md | 277 -- Exchange-Integration.md | 14 - FAQ.md | 263 -- First-steps-with-ethereum-JSON-RPC.md | 82 - Fortnight-In-Ethereum-Template.md | 412 --- Generalized_Merkle_DHT.md | 33 - Geth-Dapp-loading-proposal.md | 27 - Gitter-Channels.md | 44 - Glossary.md | 82 - HPOC_2015.md | 92 - Home.md | 30 - ...-Inter-exchange-Client-Address-Protocol.md | 116 - IPv6.md | 20 - JSON-RPC-Error-Codes-Improvement-Proposal.md | 63 - JSON-RPC.md | 2381 ---------------- JavaScript-API.md | 2416 ----------------- Javascript-Development-Deficiencies.md | 20 - Kademlia-Peer-Selection.md | 46 - LICENSE | 5 - Layers.md | 80 - Licensing.md | 34 - Light-client-protocol.md | 39 - Middleware-and-Dapp-Project-Ideas.md | 112 - Mining.md | 81 - Mix-Features.md | 183 -- Mix-improvement-proposal.md | 24 - Mix:-The-DApp-IDE.md | 181 -- Morden.md | 61 - NatSpec-Determination.md | 17 - Natspec-Example.md | 48 - Network-Status.md | 101 - NewBlock-Message.md | 23 - Node-discovery-protocol.md | 13 - Open-positions-&-Schemes.md | 45 - Parallel-Block-Downloads.md | 37 - Problems.md | 388 --- Proposal:-BlockHashesFromNumbers.md | 20 - ...-Extend-GetBlockHashes-with-target-hash.md | 47 - Proposal:-NewBlockHashes.md | 21 - Proposal:-Reversion-Notification.md | 109 - Proposal:-Transaction-Proxy-Hooks.md | 55 - README.md | 1 + RPC-Testing.md | 17 - Raspberry-Pi-instructions.md | 120 - Readme.md | 14 - Registrar-ABI.md | 48 - Security-Categorization.md | 105 - Security-Issue-Process.md | 48 - Serenity_Wishlist.md | 70 - Serpent-1.0-(old).md | 281 -- Serpent.md | 494 ---- Serpent_3.0.md | 33 - Solidity,-Docs-and-ABI.md | 231 -- Solidity-Changelog.md | 6 - Solidity-Features.md | 1084 -------- Solidity-Tutorial.md | 18 - Solidity-standard-library.md | 156 -- Solidity.md | 128 - Standardized_Contract_APIs.md | 295 -- Subtleties.md | 74 - Swarm-Hash.md | 42 - Tags-for-Solidity-in-code-documentation.md | 1 - Template:-This-Week-in-Ethereum-w-YY.md | 26 - The-Solidity-Programming-Language.md | 239 -- This Week In Ethereum 47.2014.md | 60 - Todo-before-alpha.md | 10 - URL-Hint-Protocol.md | 49 - "Useful-\303\220app-Patterns.md" | 17 - Web3-Secret-Storage-Definition.md | 172 -- What-is-Ethereum.md | 66 - Which-Client?.md | 6 - Whisper-Overview.md | 112 - Whisper-PoC-2-Protocol-Spec.md | 141 - Whisper-PoC-2-Wire-Protocol.md | 57 - Whisper-Wire-Protocol.md | 23 - Whisper.md | 63 - [German]-Clearinghaus.md | 47 - ...l-proprio-ambiente-di-sviluppo-Ethereum.md | 36 - ...-Introduzione-allo-sviluppo-su-Ethereum.md | 64 - [Italian]-Libro-Bianco.md | 503 ---- [Japanese]-Cryptocurrency-Current-Problems.md | 512 ---- [Japanese]-Ethereum-Development-Tutorial.md | 249 -- [Japanese]-Ethereum-TOC.md | 25 - [Japanese]-HPOC_2015.md | 201 -- [Japanese]-Javascript-API.md | 2040 -------------- [Japanese]-License.md | 51 - [Japanese]-Solidity-Tutorial.md | 954 ------- ...71\343\203\221\343\203\274\357\274\211.md" | 127 - [Japenese]-Ethereum-TOC.md | 34 - [Persian]-Ethereum-TOC.md | 8 - [Romanian]-Block-Protocol-2.0.md | 205 -- [Romanian]-CLL.md | 151 -- [Romanian]-Cuprins.md | 26 - [Romanian]-Dagger.md | 58 - [Romanian]-Layers.md | 66 - [Romanian]-Limbajul-de-programare-Serpent.md | 79 - [Romanian]-Wire-Protocol.md | 82 - ...6\207]-Serpent\346\214\207\345\215\227.md" | 487 ---- ...45\235\212Wiki\347\233\256\345\275\225.md" | 11 - ...00\345\217\221\350\256\241\345\210\222.md" | 278 -- ...12\346\234\257\350\257\255\350\241\250.md" | 128 - ...12\347\231\275\347\232\256\344\271\246.md" | 475 ---- ...346\230\216\346\251\237\345\210\266FAQ.md" | 239 -- ...21\347\273\234\347\212\266\346\200\201.md" | 93 - _Sidebar.md | 75 - drafts/[english]-old-ethereum-whitepaper.md | 639 ----- drafts/[english]-patricia-tree-draft.md | 7 - enode-url-format.md | 21 - "e\317\200-Programme.md" | 21 - images/natspec1.png | Bin 82697 -> 0 bytes images/natspec2.png | Bin 83621 -> 0 bytes images/natspec3.png | Bin 93201 -> 0 bytes images/natspec4.png | Bin 90201 -> 0 bytes images/natspec5.png | Bin 103151 -> 0 bytes libp2p-Whitepaper.md | 42 - newBlockFilter-Improvement-Proposal.md | 57 - .../[english]-design-rationale.md | 223 -- .../[japanese]-design-rationale.md | 610 ----- pages/ethereum-toc/[chinese]-ethereum-toc.md | 16 - pages/ethereum-toc/[french]-ethereum-toc.md | 93 - pages/ethereum-toc/[german]-ethereum-toc.md | 24 - pages/ethereum-toc/[italian]-ethereum-toc.md | 30 - pages/ethereum-toc/[spanish]-ethereum-toc.md | 24 - .../patricia-tree/[english]-patricia-tree.md | 141 - .../patricia-tree/[japanese]-patricia-tree.md | 139 - .../patricia-tree/[romanian]-patricia-tree.md | 137 - pages/rlp/[chinese]-rlp.md | 68 - pages/rlp/[english]-rlp.md | 68 - pages/rlp/[german]-rlp.md | 66 - pages/rlp/[japanese]-rlp.md | 70 - pages/rlp/[romanian]-rlp.md | 62 - pages/white-paper/[chinese]-white-paper.md | 477 ---- pages/white-paper/[english]-white-paper.md | 500 ---- pages/white-paper/[german]-white-paper.md | 630 ----- pages/white-paper/[japanese]-white-paper.md | 1315 --------- pages/white-paper/[korean]-white-paper.md | 553 ---- pages/white-paper/[persian]-white-paper.md | 14 - pages/white-paper/[romanian]-white-paper.md | 559 ---- sendTransaction-return-value-proposal.md | 22 - web.js-0.9.md | 50 - "\303\220\316\236Vp2p-Wire-Protocol.md" | 90 - ...\262\320\276-\320\277\320\276-Solidity.md" | 1256 --------- 171 files changed, 1 insertion(+), 31897 deletions(-) delete mode 100644 Adaptive-Message-IDs.md delete mode 100644 Adaptive-Peer-Time.md delete mode 100644 Bad-Block-Reporting.md delete mode 100644 Bad-Chain-Canary.md delete mode 100644 Block-Protocol-2.0.md delete mode 100644 Blockchain-import-and-export-instructions.md delete mode 100644 Brain-Wallet.md delete mode 100644 CLL.md delete mode 100644 Chain-Fibers-Redux.md delete mode 100644 Clearinghouse.md delete mode 100644 Contract-Metadata-Docs-(NatSpec,-ABI).md delete mode 100644 Dagger-Hashimoto.md delete mode 100644 Dagger.md delete mode 100644 Dapp-Developer-Resources.md delete mode 100644 Dapp-using-Meteor.md delete mode 100644 Decentralized-apps-(dapps).md delete mode 100644 Default-Extra-Data-Standard.md delete mode 100644 Deterministic_Wallet_Spec.md delete mode 100644 Distributed-Preimage-Archive.md delete mode 100644 EVM-JIT-Binary-Interface.md delete mode 100644 Ethash-C-API.md delete mode 100644 Ethash-DAG-Disk-Storage-Format.md delete mode 100644 Ethash-Design-Rationale.md delete mode 100644 Ethash.md delete mode 100644 Ethash_revision_11.md delete mode 100644 Ethereum-Contract-ABI.md delete mode 100644 Ethereum-Development-Tutorial.md delete mode 100644 Ethereum-Natural-Specification-Format.md delete mode 100644 Ethereum-Wire-Protocol.md delete mode 100644 Ethereum-introduction.md delete mode 100644 Exchange-Integration.md delete mode 100644 FAQ.md delete mode 100644 First-steps-with-ethereum-JSON-RPC.md delete mode 100644 Fortnight-In-Ethereum-Template.md delete mode 100644 Generalized_Merkle_DHT.md delete mode 100644 Geth-Dapp-loading-proposal.md delete mode 100644 Gitter-Channels.md delete mode 100644 Glossary.md delete mode 100644 HPOC_2015.md delete mode 100644 Home.md delete mode 100644 ICAP:-Inter-exchange-Client-Address-Protocol.md delete mode 100644 IPv6.md delete mode 100644 JSON-RPC-Error-Codes-Improvement-Proposal.md delete mode 100644 JSON-RPC.md delete mode 100644 JavaScript-API.md delete mode 100644 Javascript-Development-Deficiencies.md delete mode 100644 Kademlia-Peer-Selection.md delete mode 100644 LICENSE delete mode 100644 Layers.md delete mode 100644 Licensing.md delete mode 100644 Light-client-protocol.md delete mode 100644 Middleware-and-Dapp-Project-Ideas.md delete mode 100644 Mining.md delete mode 100644 Mix-Features.md delete mode 100644 Mix-improvement-proposal.md delete mode 100644 Mix:-The-DApp-IDE.md delete mode 100644 Morden.md delete mode 100644 NatSpec-Determination.md delete mode 100644 Natspec-Example.md delete mode 100644 Network-Status.md delete mode 100644 NewBlock-Message.md delete mode 100644 Node-discovery-protocol.md delete mode 100644 Open-positions-&-Schemes.md delete mode 100644 Parallel-Block-Downloads.md delete mode 100644 Problems.md delete mode 100644 Proposal:-BlockHashesFromNumbers.md delete mode 100644 Proposal:-Extend-GetBlockHashes-with-target-hash.md delete mode 100644 Proposal:-NewBlockHashes.md delete mode 100644 Proposal:-Reversion-Notification.md delete mode 100644 Proposal:-Transaction-Proxy-Hooks.md create mode 100644 README.md delete mode 100644 RPC-Testing.md delete mode 100644 Raspberry-Pi-instructions.md delete mode 100644 Readme.md delete mode 100644 Registrar-ABI.md delete mode 100644 Security-Categorization.md delete mode 100644 Security-Issue-Process.md delete mode 100644 Serenity_Wishlist.md delete mode 100644 Serpent-1.0-(old).md delete mode 100644 Serpent.md delete mode 100644 Serpent_3.0.md delete mode 100644 Solidity,-Docs-and-ABI.md delete mode 100644 Solidity-Changelog.md delete mode 100644 Solidity-Features.md delete mode 100644 Solidity-Tutorial.md delete mode 100644 Solidity-standard-library.md delete mode 100644 Solidity.md delete mode 100644 Standardized_Contract_APIs.md delete mode 100644 Subtleties.md delete mode 100644 Swarm-Hash.md delete mode 100644 Tags-for-Solidity-in-code-documentation.md delete mode 100644 Template:-This-Week-in-Ethereum-w-YY.md delete mode 100644 The-Solidity-Programming-Language.md delete mode 100644 This Week In Ethereum 47.2014.md delete mode 100644 Todo-before-alpha.md delete mode 100644 URL-Hint-Protocol.md delete mode 100644 "Useful-\303\220app-Patterns.md" delete mode 100644 Web3-Secret-Storage-Definition.md delete mode 100644 What-is-Ethereum.md delete mode 100644 Which-Client?.md delete mode 100644 Whisper-Overview.md delete mode 100644 Whisper-PoC-2-Protocol-Spec.md delete mode 100644 Whisper-PoC-2-Wire-Protocol.md delete mode 100644 Whisper-Wire-Protocol.md delete mode 100644 Whisper.md delete mode 100644 [German]-Clearinghaus.md delete mode 100644 [Italian]-Impostare-il-proprio-ambiente-di-sviluppo-Ethereum.md delete mode 100644 [Italian]-Introduzione-allo-sviluppo-su-Ethereum.md delete mode 100644 [Italian]-Libro-Bianco.md delete mode 100644 [Japanese]-Cryptocurrency-Current-Problems.md delete mode 100644 [Japanese]-Ethereum-Development-Tutorial.md delete mode 100644 [Japanese]-Ethereum-TOC.md delete mode 100644 [Japanese]-HPOC_2015.md delete mode 100644 [Japanese]-Javascript-API.md delete mode 100644 [Japanese]-License.md delete mode 100644 [Japanese]-Solidity-Tutorial.md delete mode 100644 "[Japanese]-Whisper-\357\274\210\343\202\246\343\202\243\343\202\271\343\203\221\343\203\274\357\274\211.md" delete mode 100644 [Japenese]-Ethereum-TOC.md delete mode 100644 [Persian]-Ethereum-TOC.md delete mode 100644 [Romanian]-Block-Protocol-2.0.md delete mode 100644 [Romanian]-CLL.md delete mode 100644 [Romanian]-Cuprins.md delete mode 100644 [Romanian]-Dagger.md delete mode 100644 [Romanian]-Layers.md delete mode 100644 [Romanian]-Limbajul-de-programare-Serpent.md delete mode 100644 [Romanian]-Wire-Protocol.md delete mode 100644 "[\344\270\255\346\226\207]-Serpent\346\214\207\345\215\227.md" delete mode 100644 "[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212Wiki\347\233\256\345\275\225.md" delete mode 100644 "[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\345\274\200\345\217\221\350\256\241\345\210\222.md" delete mode 100644 "[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\346\234\257\350\257\255\350\241\250.md" delete mode 100644 "[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\347\231\275\347\232\256\344\271\246.md" delete mode 100644 "[\344\270\255\346\226\207]-\346\254\212\347\233\212\350\255\211\346\230\216\346\251\237\345\210\266FAQ.md" delete mode 100644 "[\344\270\255\346\226\207]-\347\275\221\347\273\234\347\212\266\346\200\201.md" delete mode 100644 _Sidebar.md delete mode 100644 drafts/[english]-old-ethereum-whitepaper.md delete mode 100644 drafts/[english]-patricia-tree-draft.md delete mode 100644 enode-url-format.md delete mode 100644 "e\317\200-Programme.md" delete mode 100644 images/natspec1.png delete mode 100644 images/natspec2.png delete mode 100644 images/natspec3.png delete mode 100644 images/natspec4.png delete mode 100644 images/natspec5.png delete mode 100644 libp2p-Whitepaper.md delete mode 100644 newBlockFilter-Improvement-Proposal.md delete mode 100644 pages/design-rationale/[english]-design-rationale.md delete mode 100644 pages/design-rationale/[japanese]-design-rationale.md delete mode 100644 pages/ethereum-toc/[chinese]-ethereum-toc.md delete mode 100644 pages/ethereum-toc/[french]-ethereum-toc.md delete mode 100644 pages/ethereum-toc/[german]-ethereum-toc.md delete mode 100644 pages/ethereum-toc/[italian]-ethereum-toc.md delete mode 100644 pages/ethereum-toc/[spanish]-ethereum-toc.md delete mode 100644 pages/patricia-tree/[english]-patricia-tree.md delete mode 100644 pages/patricia-tree/[japanese]-patricia-tree.md delete mode 100644 pages/patricia-tree/[romanian]-patricia-tree.md delete mode 100644 pages/rlp/[chinese]-rlp.md delete mode 100644 pages/rlp/[english]-rlp.md delete mode 100644 pages/rlp/[german]-rlp.md delete mode 100644 pages/rlp/[japanese]-rlp.md delete mode 100644 pages/rlp/[romanian]-rlp.md delete mode 100644 pages/white-paper/[chinese]-white-paper.md delete mode 100644 pages/white-paper/[english]-white-paper.md delete mode 100644 pages/white-paper/[german]-white-paper.md delete mode 100644 pages/white-paper/[japanese]-white-paper.md delete mode 100644 pages/white-paper/[korean]-white-paper.md delete mode 100644 pages/white-paper/[persian]-white-paper.md delete mode 100644 pages/white-paper/[romanian]-white-paper.md delete mode 100644 sendTransaction-return-value-proposal.md delete mode 100644 web.js-0.9.md delete mode 100644 "\303\220\316\236Vp2p-Wire-Protocol.md" delete mode 100644 "\320\240\321\203\320\272\320\276\320\262\320\276\320\264\321\201\321\202\320\262\320\276-\320\277\320\276-Solidity.md" diff --git a/Adaptive-Message-IDs.md b/Adaptive-Message-IDs.md deleted file mode 100644 index b73396415..000000000 --- a/Adaptive-Message-IDs.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -name: Message IDs -category: ---- - -### Goal - -Dynamic numeric identities for the sub protocol message types rather than the current fixed id system. This way we don't have to reserve parts of the message ID space up front and have a central entity to police this space to prevent clashes. - -### Overview - -All sub-protocol message IDs begin at 0x10 and count only those messages in the shared protocols, in alphabetical order. Sub-protocol versioning is provided in the base protocol to allow guarantees that there is consensus over the number and order of messages for each sub-protocol between peers. - -### Needed Changes - -Wire protocol Hello package changed to (*note protocol version has changed to 1*): - -**Hello** -[`0x00`: `P`, `p2pVersion`: `P`, `clientId`: `B`, [[`cap1`: `B_3`, `capVersion1`: `P`], [`cap2`: `B_3`, `capVersion2`: `P`], ...], `listenPort`: `P`, `nodeId`: `B_64`] First packet sent over the connection, and sent once by both sides. No other messages may be sent until a Hello is received. -* `p2pVersion` Specifies the implemented version of the P2P protocol. Now must be 1. -* `clientId` Specifies the client software identity, as a human-readable string (e.g. "Ethereum(++)/1.0.0"). -* `cap` Specifies a peer capability name as a length-3 ASCII string. Current supported capabilities are `eth`, `shh`. -* `capVersion` Specifies a peer capability version as a positive integer. Current supported versions are 35 for `eth`, and 2 for `shh`. -* `listenPort` specifies the port that the client is listening on (on the interface that the present connection traverses). If 0 it indicates the client is not listening. -* `nodeId` is the Unique Identity of the node and specifies a 512-bit hash that identifies this node. - -All `eth` sub-protocol message ids are lowered by `0x10` and have a `+` prepended to them to denote that the given ID is offset by some dynamic amount. - -### Conversation overview - -``` -[23:11:29] gavofyork: for each shared sub protocol, in alphabetic order, you deploy the subprotocol's messages -[23:11:40] gavofyork: (after the basic p2p messages) -[23:12:42] gavofyork: so for two whisper-only peers, defined message types are Hello = 0x00, Disconnect, Ping, Pong, GetPeers, Peers = 0x05, WhisperMessage1 = 0x06, ... -[23:13:50] gavofyork: but for two peers that have eth and shh, you'd get: Hello = 0x00, Disconnect, Ping, Pong, GetPeers, Peers = 0x05, Status = 0x06, GetTransactions = 0x07, Transactions = 0x08, GetBlockHashes = 0x09, BlockHashes = 0x0a, GetBlocks = 0x0b, Blocks = 0x0c, NewBlock = 0x0d, WhisperMessage1 = 0x0e, ... -[23:14:28] Jeffrey Wilcke: so what you mean is that you negotiate which message type gets what number -[23:14:34] gavofyork: exactamundo -[23:14:45] Jeffrey Wilcke: right interesting -[23:15:12] gavofyork: no arguing over what protocol gets what message-id space -[23:15:25] gavofyork: avoids any central registry or anything -[23:15:33] Jeffrey Wilcke: so receiving and sending might be completely different "numbers" but have the same meaning -[23:15:40] gavofyork: yup -[23:15:56] gavofyork: will make wire protocol analysis slightly harder -[23:16:02] gavofyork: though that's not necessarily a bad thing -[23:16:33] Jeffrey Wilcke: Ok so you tell a node that GetBlockHahses = 0x09 -[23:17:37] Jeffrey Wilcke: GetBlockHashes internally is say 0x03. We give it an array with [0x03, 0x09] meaning "map GetBlockHashes to 0x09" or "when you receive 0x09 I mean GetBlockHashes". -[23:18:12] gavofyork: don't even need to do that -[23:18:21] gavofyork: so we'll need a map internally -[23:18:28] gavofyork: but there's no need to ever serialise it -[23:18:46] Jeffrey Wilcke: No, well you have to let the other know how you understand messages -[23:18:54] Jeffrey Wilcke: meaning that get hashes = 9 -[23:19:01] gavofyork: "for each shared sub protocol, in alphabetic order, you deploy the subprotocol's messages" -[23:19:22] gavofyork: both form natural consensus on the alphabetic order of the shared subprotocols -[23:19:28] gavofyork: just from both Hello packets -[23:20:03] gavofyork: the one thing we should bring in is subprotocol versioning -[23:20:33] Jeffrey Wilcke: but how do we negotiate over the numbering? -[23:20:43] gavofyork: that is the negotiation :) -[23:21:04] gavofyork: you know the exact message type set & order in each subprotocol -[23:21:14] gavofyork: and you know the order they should be counted in -[23:21:26] gavofyork: and you know where to count from -[23:21:28] Jeffrey Wilcke: of course, but how do negotiate over the subprotocol -[23:21:33] gavofyork: oh -[23:21:36] gavofyork: that's in the Hello packet -[23:21:45] gavofyork: that contains the supported subprotocols -[23:21:52] gavofyork: e.g. A <=> B: -[23:21:53] Jeffrey Wilcke: aaah i follow -[23:21:56] gavofyork: ok -[23:22:11] Jeffrey Wilcke: right ok. i thought you meant alphabetical in the _messages_ -[23:22:19] Jeffrey Wilcke: ok makes sense -``` \ No newline at end of file diff --git a/Adaptive-Peer-Time.md b/Adaptive-Peer-Time.md deleted file mode 100644 index 0405c26da..000000000 --- a/Adaptive-Peer-Time.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -name: Adaptive Peer Time -category: ---- - -### Goals - -At present, a single mining peer with its clock substantially (> 25% of the expected block time) ahead of the other peers will cause problems on the network. Forks are common as peers are inconsistently forced to ignore the future blocks. - -A system with multiple peers should be robust to a few peers having substantially fast clocks. - -### Basic Overview - -Each peer does a ping-sequence, each message timestamped with the hardware clock (H) directly after handshake to determine both the network traversal distance ("ping time") and an estimate of the peer's hardware clock (Hp). - -The clock-offset (D) of the peer then becomes its hardware clock (H) corrected to become the median of the peer hardware clocks (median({H1, H2, ...}) = M). - -The clock offset (D) is dynamically evaluated as the peer set changes. - -### Required Changes - -Protocol changes: -* Ping & Pong packets include a timestamp. - -Rest to be implemented lazily. \ No newline at end of file diff --git a/Bad-Block-Reporting.md b/Bad-Block-Reporting.md deleted file mode 100644 index 82750d998..000000000 --- a/Bad-Block-Reporting.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -name: Bad Block Reporting -category: ---- - -Send a JSONRPC request to `https://badblocks.ethdev.com`: - -Call `eth_badBlock(BADBLOCK)`, with `BADBLOCK` the object described below: - -## BADBLOCK Object Format - -NOTE: All hex is lower-case. - -#### Types -- `DATA`: freeform byte array as a string of hex, *no 0x prefix*. -- `DATA_20`: like DATA, always of length 40. -- `HEX`: string of hex-encoded big-endian integer, used for VM stack/memory/storage items, *no 0x prefix*, *no leading zeroes*. -- `INT`: simple JS integer. -- `BIGINT`: string of decimal-encoded integer, used for potentially bigints. -- `TAG_ERROR`: described later. -- `TAG_INST`: string of an EVM instruction mnemonic, uppercase e.g. `"PUSH4"` or `"STOP"`. -- `VMTRACE`: described later. - -#### Type modifiers -- `SOMETIMES`: field is omitted under certain circumstances. -- `NONSTANDARD`: field may safely be omitted. - -#### BADBLOCKS object - -```json -{ - "block": DATA - "errortype": TAG_ERROR - "hints": { (all items OPTIONAL) - "receipts": [ DATA, ... ], OPTIONAL - "vmtrace": VMTRACE, OPTIONAL - }, OPTIONAL -} -``` - -Where: - -`receipts` is simply the array of RLP-encoded receipts. - -`TAG_ERROR` is a string containing one of (specified roughly in order of ability to detect): - -#### Generic: -- `RLPError`: One of the following: - - `BadRLP`: Generally invalid RLP (e.g. 0x8100). - - `BadCast`: Given RLP is of an incorrect type (e.g. 0x00 being interpreted as an integer). - - `OversizeRLP`: Additional bytes trailing an otherwise valid RLP fragment (e.g. 0x8000). - - `UndersizeRLP`: Bytes missing from the end of an otherwise valid RLP fragment (e.g. 0x81). - -#### Block-specific: -- `InvalidBlock`: One of the following: - - `InvalidBlockFormat`: Block format is wrong (!= array, != 3 items &c.). - - `TooManyUncles`: More than 2 uncles mentioned. - - `InvalidTransactionsRoot`: Transactions root is different to that derived from transactions given in block. - - `InvalidUnclesHash`: Uncles hash is different to that derived from uncles given in block. - - `InvalidGasUsed`: Gas used is not equal to the gasUsed in the last receipt (or previous block if no transactions). - - `InvalidStateRoot`: State root mentioned is different to that calculated (i.e. reward application is incorrect). - - `InvalidReceiptsRoot`: Receipts root mentioned is different to that calculated (i.e. appliaction of a transaction resulted in different logs, gas-used or state-root). "receipts" and "vmtrace" should be hinted. - -#### Block-header-specific -- `InvalidHeader`: One of the following: - - `InvalidBlockHeaderItemCount`: Wrong item count in header. - - `TooMuchGasUsed`: Header states gas used as bigger than gas limit. - - `ExtraDataTooBig`: Header's extra data is greater than limit. - - `InvalidDifficulty`: Difficulty is incorrect given previous block's difficulty and timestamp. - - `InvalidGasLimit`: Gas limit does not fall within bounds given previous block's gas limit. - - `InvalidBlockNonce`: Nonce does not result in a proof of work which satisfies the given difficulty. - - `InvalidNumber`: Number is not equal to parent number + 1. - - `InvalidTimestamp`: Timestamp is not greater than parent's. - - `InvalidLogBloom`: LogBloom is not equal to the bitwise-OR of all receipts' LogBlooms. - -#### Transaction-specific -- `InvalidTransaction`: One of the following: - - `OutOfGasIntrinsic`: GAS below amount required for any transaction. - - `BlockGasLimitReached`: Too much gas being used for the transaction within this block. - - `InvalidSignature`: Transaction's signature is invalid. - - `OutOfGasBase`: GAS below amount required for this transaction. - - `NotEnoughCash`: Balance of sender too low. - - `InvalidNonce`: Transaction nonce is wrong. - -#### Uncle-specific -- `InvalidUncle`: One of the following: - - `UncleInChain`: Uncle has already been included in the current chain (either as a direct ancestor or one of its included uncles). - - `UncleTooOld`: Uncle is older than the 6th generation uncle. - - `UncleIsBrother`: Uncle is newer than the 1st generation uncle. - - -and `VMTRACE` is the object: - -```json -[ - { - "stack": [ HEX, ... ] - "memory": HEX, SOMETIMES - "sha3memory": DATA_32, SOMETIMES - "storage": { HEX: HEX }, SOMETIMES - "gas": BIGINT - "pc": BIGINT - "inst": INT - "depth": INT, OPTIONAL - "steps": INT - "address": DATA_20, SOMETIMES - "memexpand": BIGINT, NONSTANDARD - "gascost": BIGINT, NONSTANDARD - "instname": STRING, NONSTANDARD - }, - ... -] -``` - -- `stack`: The stack, prior to execution. -- `memory`: The memory, prior to execution. Omitted when previous operation was not memory-dependent (MLOAD/MSTORE/MSTORE8/SHA3/CALL/CALLCODE/CREATE/CALLDATACOPY/CODECOPY/EXTCODECOPY), not first operation of CALL/CREATE context or when memory >= 1024 bytes large. -- `sha3memory`: The Keccak hash of the memory, prior to execution. Omitted when previous operation was not memory-dependent (MLOAD/MSTORE/MSTORE8/SHA3/CALL/CALLCODE/CREATE/CALLDATACOPY/CODECOPY/EXTCODECOPY), not first operation of CALL/CREATE context or when memory < 1024 bytes large. -- `storage`: The contents of storage that SSTOREs operate on (RE-READ THAT!), prior to execution. Omitted when previous operation is not storage-dependent (SLOAD/SSTORE) and not first operation of CALL/CREATE context. -- `gas`: The amount of gas available prior to this instruction. -- `pc`: The program counter, immediately prior to execution. -- `inst`: The instruction opcode index that is to be executed (e.g. STOP would be 0). -- `depth`: The depth of in present context in CALL/CREATE stack. Omitted when no change since previous operation and not first operation of CALL/CREATE context. -- `steps`: The number of steps taken so far in present CALL/CREATE context prior to executing the current instruction. -- `address`: The address of account that would be returned by `MYADDRESS` opcode. Omitted when no change since previous operation and not first operation of CALL/CREATE context. -- `memexpand`: The size that memory is to be expanded by in words for this operation. Omitted when zero. -- `gascost`: The total cost of gas for executing this instruction (technically the /maximum/ total cost of gas - CALL/CREATE may return gas). \ No newline at end of file diff --git a/Bad-Chain-Canary.md b/Bad-Chain-Canary.md deleted file mode 100644 index 22ca3949f..000000000 --- a/Bad-Chain-Canary.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -name: Bad Chain Canary -category: ---- - -There will be a canary contract to notify that a given chain is bad. It's very easy to use; check storage location 0 of contract at the given address (see below). If non-zero, client should not mine (at least without a non-default option being given to ignore the canary and mine on a known-bad chain). - -Specifically there are three modes it can be in: - -- `0` All fine. Carry on. -- `1` Bad chain. Client should not mine on it. Client upgrade not yet available. -- `2` Update required. Just as for `1`; additionally, an update to your client is available and would be prudent. - -Clients implementing this protocol should display a message to the user to make any non-zero status clear. For a status of 2, the user should be notified than an immediate upgrade is required, regardless of whether mining is enabled. - -#### Addresses - -- For Olympic: `0x6879392ee114f8a4e133f0ff3dc4bc1717fe9344` -- For Frontier: TBC diff --git a/Block-Protocol-2.0.md b/Block-Protocol-2.0.md deleted file mode 100644 index f60f0fb7d..000000000 --- a/Block-Protocol-2.0.md +++ /dev/null @@ -1,255 +0,0 @@ ---- -name: Block Protocol 2.0 -category: ---- - -One of the main criticisms that has been made of Ethereum, and Bitcoin-like blockchain protocols in general, is the issue of scalability. Although Bitcoin's core developers, and other platforms such as Ripple, have continued to make iterative improvements to the way that the blockchain is stored, including innovations such as separating the state ("ledger" or "UTXO set") from the transaction list or using separate data structures to store the two on disk/memory, fundamentally no one has successfully implemented any way to improve upon the fundamental limitation that every full node must process every transaction. At this point, Ethereum also does not solve this problem. However, the block protocol described here, and specifically the stack trace mechanism, allows for secure "light nodes" to exist, which download only the headers of every block and not the full transaction set but maintain the same security level for their users as full nodes under the much weaker assumption that at least one node with non-negligible (ie. >0.01%) mining power or ether inside the system is honest. - -### Data definitions - -A full block is stored as: - - [ - block_header, - transaction_list, - uncle_list, - stack_trace - ] - -Where: - - transaction_list = [ - transaction 0, - transaction 1, - ... - ] - - uncle list = [ - uncle_block_header_1, - uncle_block_header_2, - ... - ] - - block_header = [ - parent hash, - number, - TRIEHASH(transaction_list), - TRIEHASH(uncle_list), - TRIEHASH(stack_trace), - coinbase address, - state_root, - difficulty, - timestamp, - extra_data, - nonce - ] - - stack_trace = [ - [ medhash 0, stkhash 0 ], - [ medhash 1, stkhash 1 ], - ... - ] - -Each transaction and uncle block header is itself provided directly in the form of a list, not in a serialized form. `uncle_list` and `transaction_list` are the lists of the uncle block headers and transactions in the block, respectively. Note that the block number, difficulty and timestamp are integers, and therefore cannot have leading zeroes; `extra_data` and `nonce` can be byte arrays of at most 32 bytes, NOT lists, although this particular check should not be performed for the genesis block where the `extra_data` field will take up many kilobytes. - -The `state_root` is the root of a [Patricia Tree](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree) containing (key, value) pairs for all accounts where each address is represented as a 20-byte binary string. At the address of each account, the value stored in the Merkle Patricia tree is a string which is the RLP-serialized form of an object of the form: - - [ balance, nonce, contract_root ] - -The `nonce` is the number of transactions made from the account, and is incremented every time a transaction is made. The purpose of this is to (1) make each transaction valid only once to prevent replay attacks, and (2) to make it impossible (more precisely, cryptographically infeasible) to construct a contract with the same hash as a pre-existing contract. `balance` refers to the account's balance, denominated in wei. `contract_root` is the root of yet another Patricia tree, containing the contract's memory, if that account is controlled by a contract. If an account is not controlled by a contract, the contract root will simply be the empty string. - -In order to understand all of what is above, we also need a few function definitions: - - def H(x): - if len(rlp.encode(x)) < 32: return x - else: return sha3(rlp.encode(x)) - - def H20(x): - if len(rlp.encode(x)) < 20: return x - else: return sha3(rlp.encode(x))[:12] - - def adjust_difficulty(pdiff,ptime,ntime): - if ntime > ptime + 42: return pdiff - int(pdiff / 1024) - else: return pdiff + int(pdiff / 1024) - - def int_to_bin(n,bytes): - return '' if bytes == 0 else int_to_bin(int(n / 256),bytes - 1) + chr(n % 256) - - def TRIE(objs): - t = Trie() - for i in range(len(objs)): - t.insert(int_to_bin(i,32),rlp.encode(objs[i])) - return t - - def TRIEHASH(objs): - return TRIE(objs).root - - -We also want a few methods for dealing with tries as stacks: - - def TRIELEN(trie): - i = 0 - while trie.get(int_to_bin(i,32)): i += 1 - return i - - def TRIETOP(trie): - return trie.get(int_to_bin(TRIELEN(trie)-1,32)) - - def TRIEPOP(trie): - trie.update(int_to_bin(TRIELEN(trie)-1,32),'') - - def TRIEPUSH(trie,node): - trie.update(int_to_bin(TRIELEN(trie),3),node) - -The mining function is tentative, and will be replaced once we know that we have better alternatives: - - def compute_valid_nonce(header): - header[10] = 0 - while not verify_pow(header): - header[10] += 1 - return header[10] - - def verify_pow(header): - return sha3(sha3(header[:10]) + header[10]) * header[7] <= 2**256 - - -### Mining Process - -![Mining Process](https://www.ethereum.org/gh_wiki/500px-Minerchart3.png) - - -When mining a block, a miner goes through the following process: - -1- Take as inputs: - -* `uncle_headers` to be the list of known unused valid uncle headers -* `timestamp` to be the current timestamp -* `parent` to be the parent block -* `extra_data` to be the extra data desired to be added to the block -* `coinbase` to be the desired coinbase address -* `txlist` to be the list of transactions to be added - -2- Set: - -* `difficulty = adjust_difficulty(parent.difficulty,timestamp,parent.timestamp)` -* `reward = 15 * 10^18` (tentatively) -* `block_header = [ parent.hash, parent.number + 1, TRIEHASH(txlist), TRIEHASH(uncle_headers), 0, coinbase, 0, difficulty, timestamp, extra_data, 0 ]` - -3- Initialize: - -* `state` to be the parent block state -* `txstack = TRIE(txlist)` -* `stacktrace = TRIE([])` - -4- While `stacktrace.root != ''`: - -* `TRIEPUSH(stacktrace,[state.root,txstack.root])` -* Apply the transaction `TRIETOP(txstack)` to `state`. -* `TRIEPOP(txstack)` -* Let `L[0] ... L[m-1]` be the list of new transactions spawned by that transaction via `MKTX`, in the order that they were produced during script execution. -* Initialize `j = m-1`. While `j >= 0`, `TRIEPUSH(txstack,L[j])` and `j -= 1` - -5- Make the following modifications to the state tree: - -* Increase the balance of `coinbase` by `reward` -* For each uncle `u` in `uncle_headers`, increase the balance of `u.coinbase` by `reward * 13/16` and increase the balance of `coinbase` by `reward * 1/16` - -6- Fill in the first two zeroes in `block_header` with `state.root` and `TRIEHASH(stack_trace)` - -7- Set `nonce = compute_valid_nonce(block_header)`, and fill in the remaining zero in the block header with this value - -### Block Validation Algorithm - -![Mining Process](https://www.ethereum.org/gh_wiki/500px-Minerchart2.png) - -1- Take as inputs: - -* `block` to be the block header -* `uncle_list` to be the block's uncle list -* `transaction_list` to be the block's transaction list -* `stacktrace` to be the block's stack trace -* `now` to be the current time as measured by the miner's CPU - -2- Check the following: - -* Is there an object, which is a block, in the database with `block.prevhash` as its hash? Let `parent` be that block. -* Is the proof of work on the block valid? -* Is the proof of work on all uncle headers valid? -* Are all uncles unique and actually uncles (ie. children of the parent of the parent, but not the parent)? -* Is `block.timestamp <= now + 900` and is `block.timestamp >= parent.timestamp`? -* Is `block.number == parent.number + 1`? -* Is `block.difficulty == adjust_difficulty(parent.difficulty,timestamp,parent.timestamp)`? -* Is `block.transaction_hash = TRIEHASH(transaction_list)`? -* Is `block.stacktrace_hash = TRIEHASH(stacktrace)`? -* Is `block.uncle_hash = H(uncle_list)`? - -3- Initialize: - -* `state` to be block parent block's state -* `txstack = TRIE(transaction_list)` -* `i = 0` - -4- Let `stacktrace[k] = [ M[k], H[k] ]`, defaulting to '' if `k` is out of bounds. While `i < len(stacktrace)`: - -* Check that `state.root == M[i]` and `txstack.root == H[i]` -* Apply `transaction_list[i]` to `state`. -* Apply the transaction `TRIETOP(txstack)` to `state`. -* `TRIEPOP(txstack)` -* Let `L[0] ... L[m-1]` be the list of new transactions spawned by that transaction via `MKTX`, in the order that they were produced during script execution. -* Initialize `j = m-1`. While `j >= 0`, `TRIEPUSH(txstack,L[j])` and `j -= 1` -* Set `i += 1` - -5- Make the following modifications to `state`: - -* Increase the balance of `coinbase` by `reward` -* For each uncle `u` in `uncle_headers`, increase the balance of `u.coinbase` by `reward * 13/16` and increase the balance of `coinbase` by `reward * 1/16` - -6- Check that `txstack.root == ''` - -7- Check that `state.root == block.state_root` - -8- If any check failed, return FALSE. Otherwise, return TRUE. - -If a block is valid, determine TD(block) ("total difficulty") for the new block. TD is defined recursively by `TD(genesis_block) = 0` and `TD(B) = TD(B.parent) + sum([u.difficulty for u in B.uncles]) + B.difficulty`. If the new block has higher TD than the current block, set the current block to the new block and continue to the next step. Otherwise, exit. - -### Semi-collaborative Block Validation Via Challenge-Response Protocol - -In Ethereum, a ''light node'' can be defined as a node that accepts block headers, and performs the verifications in (2) with the exception of the transaction and stacktrace trie hash verifications but does not perform the verifications in (4) and (6), similar to the headers-only verification that light nodes do in Bitcoin. Light nodes would thus store the state roots, and perhaps some portion of the state, but not the entire state. If a light node wants to know the balance or contract state of a given account, it can request the value from other nodes in the network alongside the minimal subset of Patricia tree nodes that prove that the given key/value pair is actually in the state. - -Although Ethereum cannot run without at least some full nodes processing and verifying every transaction that takes place in the network, this block protocol is designed to provide a somewhat weaker assurance: as long as at least one honest full node exists, light clients can be just as secure and provide the same incentives toward decentralization that full nodes do. The mechanism relies on a challenge-response protocol in which a full node can, subject to certain conditions, submit a challenge that a certain part of a block is invalid, and it would be up to the miner (or another good samaritan node) to provide a response which light nodes can then efficiently verify. If a challenge goes uncontested, then light nodes would distrust the block. - -In the validation algorithm described in the previous section, note that there are a few specific places where a block can fail: - -1. One of the checks in (2), aside from the transaction list trie hash or stack trace trie hash check, fails. -2. The transaction list trie hash check fails. -3. The stack trace trie hash check fails. -4. One of the checks in (4) fails for `i=0` -5. One of the checks in (4) succeeds for all `i= k`, everything must be blank. - -A challenge of invalidity consists of either (1) an index `i` pointing to a potential invalid transaction, or (2) an index `i` pointing to a blank space and an index `j > i` pointing to a transaction. A response should contain (1) `i`, (2) `j` if applicable, (3) the subset of Patricia tree nodes needed to verify the values at `i` and `j` in the trie. - -For (5), a challenge of invalidity consists of an index `k` such that everything up to index `k` is valid but index `k` is not. A response consists of (1) `k`, (2) the stack trace entries at `k-1` and `k` along with a subset of Patricia tree nodes to verify them, (3) a subset of Patricia tree nodes from the state tree needed to verify the computation. For (4), a response consists simply of a subset of Patricia tree nodes to prove the stack trace entry at index 0, from which the two components can be checked against the transaction list hash in the block header and the parent block state. For (6), a response functions in the same way as in (4), except verifying the response requires both processing the last transaction and giving the block rewards to the coinbase and the uncles. - -### Economics - -There is one flaw in the protocol as described above: it is vulnerable to denial of service attacks. Specifically, because challenges are much easier to produce than responses are to produce or verify, it is possible for nodes to pollute the network with false challenges, forcing light nodes to reject every block as other nodes are unable to catch up with verification. To remedy this, we introduce a simple fix: a challenge must be signed by a node that either (1) mined one of the last 10000 blocks, or (2) owns at least 0.01% of all ether. Light nodes would then keep quality scores for all peers, and downgrade peers if they submit a challenge that is successfully countered. Because this method is not anonymous, requiring nodes to submit proof of ownership of an identity tied to the blockchain, it cannot be countered by reconnecting under a new IP address or other such mechanisms. - -The protocol altogether can be shown to be incentive-compatible as follows: - -1. Miners have the incentive to submit challenges to blocks mined by other nodes because if a challenge is successful and then they mine the next block they will have the opportunity to gain an extra 0.0625X reward by including the header of the invalid block as an uncle. -2. The miner of a block, and all uncles inside the block, at the very least have the incentive to respond to challenges. -3. Light nodes have the incentive to respect the block validity rules because everyone else does, an argument advanced in http://themonetaryfuture.blogspot.ca/2011/07/bitcoin-decentralization-and-nash.html. Without the challenge-response protocol, this argument does not apply because the cost of determining whether or not a block is valid is prohibitively high; with the protocol, this reasoning no longer applies. -4. Substantial stakeholders have the incentive to promote the perceived integrity of the system to maximize the value of their currency units, and thus may want to help actively submit both challenges and responses where possible. -5. Statistically speaking, far more than 0.01% of agents inside of real-world economic agents, whether or not weighted by economic power, tend to be motivated by altruistic/ideological considerations. The market share of charities around the world is sufficient evidence of this. - -### Comparison with Bitcoin - -In Bitcoin, one can create a challenge-response protocol to achieve similar functionality along very similar principles, but there is one key way in which such a protocol in Bitcoin would be inadequate: miner fees. Because Bitcoin does not include a Merkle-tree mechanism for adding up transaction fees, the only way to prove that a block has a certain quantity of transaction fees is to process every transaction. Furthermore, in Bitcoin transaction fees all go to the miner. Thus, in Bitcoin a light node has no way of knowing if a given block is valid or if it gives its creator excessive fees, and can only rely on the computational majority as a source of information for this. In Ethereum, all changes to the state are incorporated into the stacktrace, so this weakness does not exist and, given the weak security assumption that at least one full node with at least 0.01% mining power or stake is honest, have 100% of the security properties that full nodes have. diff --git a/Blockchain-import-and-export-instructions.md b/Blockchain-import-and-export-instructions.md deleted file mode 100644 index ef530c0d4..000000000 --- a/Blockchain-import-and-export-instructions.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -name: Blockchain Import/Export -category: ---- - -_**Note:** Binary format is concatenated RLP-encoded blocks_ - -## C++ -### Import: -``` -eth --import -``` -_Formats supported: binary_ - -### Export: -``` -eth --export Myfile --format binary --from 45 --to latest -``` -_Formats supported: hex (newlines separating), binary or JSON_ -`--from` and `--to` also support blockhashes - -## Go -### Import -``` -geth import -``` -_Formats supported: binary_ - -### Genesis block: -``` -geth --genesis --genesisnonce -``` -_Formats supported: json_ -### Export -``` -geth export -``` -_Formats supported: binary_ -## Python \ No newline at end of file diff --git a/Brain-Wallet.md b/Brain-Wallet.md deleted file mode 100644 index 3a98efc25..000000000 --- a/Brain-Wallet.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -name: Brain Wallet -category: ---- - -Ethereum brain wallets are formed through applying the SHA3 to a seed to get a result `R`, then using `R` as an accumulator for 16384 repeat SHA3 operations. This process is continued until the result, when used as a private key, forms a valid Direct ICAP (34 digit) address, defined as the first byte of the address being 0. - -``` -FUNCTION toBrain(STRING seed) RETURNS SECRET - A = SHA3(seed) - REPEAT 16384 TIMES - A = SHA3(A) - END REPEAT - WHILE SECRET_TO_ADDRESS(A)[0] != 0 DO - A = SHA3(A) - END WHILE - RETURN A -END FUNCTION -``` - -See [C++ implementation](https://github.com/ethereum/cpp-ethereum/blob/develop/libethcore/KeyManager.cpp#L215-L225) for an example. - - -### **Comments (Gustav):** - -Recent advancement in brain wallet cracking [1] show how vulnerable brain wallets are to weak passwords. Applying a KDF hardens brain wallets by reducing number of passwords an attacker can generate per second. - -Even though the seed in AZ is generated for people and can thus be designed to have enough entropy, it is desirable to configure a KDF to be as strong as possible without impacting usability. - -Benchmarking SHA3 in Go [2] on a i5-4278U CPU @ 2.60GHz gives 16384 hashes in 30ms. A C implementation on a high-end CPU would be significantly faster. - -I would recommend we configure a KDF that is much harder (even up to 1-2s CPU time) and also has a memory cost. Scrypt comes to mind, which we already specify in for the key storage [3]. - -This would make our brainwallets much harder to crack, and perhaps even allowing the seed to be shorter, improving usability. - -1. https://rya.nc/cracking_cryptocurrency_brainwallets.pdf -2. https://github.com/ethereum/go-ethereum/blob/master/crypto/crypto_test.go#L65 -3. https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition \ No newline at end of file diff --git a/CLL.md b/CLL.md deleted file mode 100644 index c0e4dfb8f..000000000 --- a/CLL.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -name: CLL -category: ---- - -### ECLL: Ethereum C-Like Language - -The purpose of ECLL is to provide a language that will be simple and friendly for users to write contracts in, but at the same time easily and efficiently compile into Ethereum script code. ECLL abstracts away concepts like pointers, direct memory access and jumping in favor of a more traditional syntax of conditionals, loops, arrays and variables. Function support, including first-class-function support, will be left to a future more powerful, but less efficient, language that will be denoted EHLL ("Ethereum High Level Language") - -The specification will be in three parts. The first part will define the language as an abstract syntax tree, formalized using LISP-style S-expression syntax, the second part will provide specifications for what each operation does, and the third will show how the AST is to be rendered in text. - -### Abstract Syntax Tree - -An **expression** is defined as follows: - -* A number is an expression -* A variable name is an expression -* `("arr" a b)` is an expression, where `a` and `b` are expressions. This is the equivalent of C's `a[b]`. -* `(OP a b)` is an expression, where `OP` is in the set `(+ - * / % s/ s% ^ < > <= >= ==)` -* `(OP a)` is an expression, where `a` is in the set `(- !)` -* The special values `tx.datan`, `tx.value`, `tx.sender`, `contract.address`, `block.number`, `block.difficulty`, `block.timestamp`, `block.parenthash` and `block.basefee` are expressions -* `("pseudo" a b)` is an expression, where `a` is a pseudoarray and `b` is an expression -* `("fun" a b...)` is an expression, where `a` is a returning function and `b...` contains the valid number of arguments - -A **pseudofunction** is defined as follows: - -* `block.contract_storage` is a pseudofunction - -A **pseudoarray** is defined as follows: - -* `tx.data` and `contract.storage` are pseudoarrays -* `("pfun" a b...)` where `a` is a pseudofunction and `b...` contains the valid number of arguments is a pseudoarray - -`contract.storage` is a **mutable pseudoarray**, and the other two are **immutable pseudoarrays**. - -A **returning function** is defined as follows: - -* `block.account_balance`, `sha256`, `sha3`, `ripemd160`, `ecvalid` are returning functions -* `array` is a returning function - -A **multireturning function** is defined as follows: - -* `ecsign` and `ecrecover` are multireturning functions - -A **multiexpression** is defined as follows: - -* `("mfun" a b...)` where `a` is a multireturning function and `b...` contains the valid number of arguments is a multiexpression - -An **acting function** is defined as follows: - -* `mktx` is an acting function - -A **left-hand-side expression** is defined as follows: - -* A variable is a left-hand-side expression. -* `("arr" a b)` is a left-hand-side expression, where `a` is a left-hand-side expression and `b` is an expression. -* `("pseudo" a b)` is a left-hand-side expression, where `a` is a mutable pseudoarray and `b` is an expression. - -A **statement** is defined as follows: - -* `("afun" a b...)` where `a` is an acting function and `b...` contains the valid number of arguments is a statement -* `("set" a b)` where `a` is a left-hand-side expression and `b` is an expression is a statement -* `("mset" a... b)` where `a...` is a list of left-hand-side expressions with the valid number of arguments and `b` is a multiexpression is a statement -* `("seq" a...)` where `a...` are statements -* `("if" a b)` where `a` is an expression and `b` is a statement -* `("if" a1 b1 "elif" a2 b2 "elif" a3 b3 ...)` where `ak` are expressions and `bk` are statements -* `("if" a1 b1 "elif" a2 b2 "elif" a3 b3 ... "else" c)` where `ak` are expressions and `bk` and `c` are statements -* `("while" a b)` where `a` is an expression and `b` is a statement -* `"exit"` - -### Definitions - -Pre-compilation, if there are `n` variables, each variable will be assigned an index in `[0,n-1]`. Let `ind(x)` be the index of variable `x`, and let `M[x]` be the contract memory at index `x` - -In the context of a right-hand-side expression: - -* Arithmetic works in the obvious way. `(* (+ 3 5) (+ 4 8))`, for example, returns 96. -* `a && b` is a shortcut for `!(!(a) + !(b))` -* `a || b` is a shortcut for `!(!(a + b))` -* A variable `x` should become `M[ind(x)]` -* `("arr" a b)` returns `M[M[ind(a)]+b]` -* `tx.datan` returns the number of data fields in the transaction -* `("pseudo" "tx.data" i)` returns the ith data field in the transaction or zero if `i >= tx.datan` -* `tx.sender`, `tx.value`, `block.basefee`, `block.difficulty`, `block.timestamp`, `block.parenthash` and `contract.address` return the obvious values. -* `("pseudo "contract.storage" i)` returns the contract storage at index `i`. -* `("fun" "block.account_balance" a)` returns the balance of address `a` -* `("pseudo" ("pfun" "block.contract_storage" a) b)` returns the contract storage of account `a` at index `b` -* `("mfun" "ecsign" hash key)` returns the `v,r,s` triple from the signature -* `("mfun" "ecrcover" h v r s)` returns the `x,y` public key -* `("mfun" "sha256" len arr)` returns the SHA256 hash of the string of length `len` starting from `M[ind(arr)]`. `sha3` and `ripemd160` work similarly -* `("fun" "array")` returns `2^160 + M[2^256 - 1]` and sets `M[2^256 - 1] <- 2^160 + M[2^256 - 1]` - -In the context of a left-hand-side expression: - -* A variable `x` returns `ind(x)` -* `("arr" a b)` returns `a + b` where `a` and `b` have already been evaluated -* `("pseudo" a b)` returns an object which, if set, modifies the value of the pseudoarray referent at index `a` to `b` instead of doing a memory set - -In the context of a statement: - -* `("afun" "mktx" dest value dn ds)` creates a transaction sending `value` ether to `dest` with `dn` data fields starting from `M[ind(ds)]` -* `("set" a b)` sets `M[a] <- b` where `a` and `b` have already been evaluated -* `("mset" a... b)` sequentially sets the memory index at each of the values in `a...` to a value from the multiexpression `b` -* `("if" a b)`, `("while" a b)` and derivatives will work as they do in other languages - -### Syntax - -* Arithmetic is done using infix notation using the [C++ operator precedence](http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B#Operator_precedence ): `^` then `* / % s/ s%` then `+ -` then `< <= > >=` then `==` then `&&` then `||`. That is to say, arithmetic formulas will behave as they normally do; for example, `(+ (* 3 5) (* x y))` would be (3 * 5 + x * y) and `(* (+ 3 5) (+ x y))` would be `((3 + 5) * (x + y))` -* `("arr" a b)` and `("pseudo" a b)` will both be represented as `a[b]` -* `("fun" a b...)`, `("mfun" a b...)`, `("afun" a b...)` and `("pfun" a...)` will all be represented as `a(b1,b2, ... ,bn)` -* Multiexpressions will be represented as `a1, a2, ... an` -* `("set" a b)` and `("mset a... b)` will be represented as `a = b` and `a1, a2 ... ,an = b`, respectively. -* `("seq" a...)` consists of each of the statements on their own separate line -* `("if" a b)` and `("while" a b)` will be represented as in Python, using the keyword directly followed by the expression for `a` and the indented statement for `b` -* Values can be represented either as integers or inside string quotes, in which case they will be treated as hexadecimal -* `exit` exits. - -**Examples:** - -Factorial: - - x = 1 - n = 1 - while x < 10: - n = n * x - x = x + 1 - -Fibonacci sequence: - - a = array() - a[0] = 1 - a[1] = 1 - i = 2 - while i < 70: - a[i] = a[i-1] + a[i-2] - i = i + 1 - mktx("0676d13c8d2cf5e9e988cc3b5f6dfb5a6a3938fa",a[69],70,a) - -A real example - simple forwarding contract to create a transferable account: - - if tx.value < tx.basefee * 200: - exit - else: - a = contract.storage[2^256 - 1] - if !(tx.sender == a) && (tx.sender > 0): - exit - if tx.data[0] == 2^160: - contract.storage[2^256 - 1] = tx.data[1] - else: - if a == 0: - contract.storage[2^256 - 1] = tx.sender - o = array() - i = 0 - while i < tx.datan - 1: - o[i] = tx.data[i+1] - i = i + 1 - mktx(tx.data[0],tx.value - tx.basefee * 250,i,o) - -### Alternative Syntax: C++ style - -* `("seq" a...)` is implemented by separating the statements with semicolons. Newlines are ignored. -* `("if" a b)` and `("while" a b)` will be represented as in C++, storing `a` inside brackets and `b` inside curly brackets - -### Alternative Syntax: Lisp style - -The AST is used as the code directly, with the minor modification that `("fun" a b...)`, `("pfun" a b...)` and `("mfun" a b...)` are replaced with `(a b...)`. diff --git a/Chain-Fibers-Redux.md b/Chain-Fibers-Redux.md deleted file mode 100644 index 75b067fbc..000000000 --- a/Chain-Fibers-Redux.md +++ /dev/null @@ -1,121 +0,0 @@ ---- -name: Chain Fibers Redux -category: ---- - -# Blockchain Scalability: Chain-Fibers Redux - -## History - -I came up with the first seed of this idea while chatting to Janislav Malahov in Berlin in Spring 2014. Unfortunately, the original article I wrote was lost along with my laptop when it was stolen in Vienna. After chatting over the principles with Vitalik more recently, we made a number of alterations and formalisations, mainly to the validation and the sub-state cutting mechanisms. What follows is a fairly complete picture of one particular possible plan for block chain scalability in a later version of Ethereum. - - -## Overview - -The basic idea of Chain-Fibers is unchanged from a year ago; split the state-space up into strata and have separate transaction collators specialising in one or a number of state sub-spaces. Transactions requiring interactions from many a subspace would be accordingly more expensive (since collators would have to maintain presence on multiple chains) and take longer to execute (since there is a lesser chance that any given block would contain a superset of the transaction's subspaces). Validity of a transaction is verifiable in isolation through the provision of comprehensive Merkle proofs to its inputs alongside it in the block in which it is included. - -The subtleties lie in precisely what governs the division of subspaces (my original proposal included the automated splitting, merging and rotation of subspace-divisions in order to best deliver internal coherency), how security is maintained within comparatively worthless subspaces and how this can play well with Proof-of-Stake (the original was based upon a master PoW chain, feeding off an idea put forward by Max Kaye in early 2014 to disassociate block chain archival from transition semantics). - -Basic idea is to have a number of chains (e.g. N), each detailing the state-transitions for only a strata of the entire system state (i.e. a state subspace). Following from programming terminology, these might be termed "fibers". Accounts thus belong to a subspace and as such a single fiber; the fiber to which they belong can be determined simply from the first log2(N) bits of the address. N can increase or decrease, and is a value maintained within the housekeeping information on the "Master Chain". - -The Master Chain in maintained by a set of bonded Validators V, with the number of validators proportional to N. A random selection of validators validate each block produced, and validators ultimately vote to form consensus over the Master Chain. Each block of the Master Chain maintains a reference to the header of each fiber. - -Transaction collators produce blocks (accepting fees from transactors), and pay Validators some of the fees collected to include the hash of their block in the main chain. Blocks are produced across a particular "home set" of fibers; this is basically just the set of fibers of which they maintain the State Trie. Their blocks may involve transactions over one or many of these fibers, though none outside their "home set". - -"Fishermen" is a term given to freelance checkers. Since block validation and availability are both important, and since it is possible that sets of validators may be contractually bribed, it is important to have a mechanism to involve additional rational individuals in acting as "whistle-blowers" to avoid bogging the other validators needlessly checking all blocks. The fishermen basically pay to attempt to convince a quorum of validators that a previously validated block is invalid (or unavailable, which we assume is equivalent). If a fisherman demonstrates a validator (or, more likely, set of validators) acted in a dishonourable fashion, then they get to claim all of their bonds. To avoid DoSing the validators with spurious challenges, a fee is payable. - - -## Schematic - -Sorry for the not-quite ASCII-art. I'm not quite as 1337 at Inkscape as Vitalik. - -``` -Transactors ==TX+FEE==> Collators ==BLOCK+FEE==> Validators -make transaction validate transaction, random selection chosen to audit - produce Comprehensive Merkle TX/PSR/CMP contents & availability, - Proof and Post State Root, all placed in PoS-consensus master block - collate into X-fiber Block - - Fishermen ==CHALLENGE+FEE==> Validators - search for invalid or a selection adjudicate challenge - unavailable X-fiber blocks -``` - - -## Transactors - -Transactors are pretty much exactly the same as in Ethereum 1.0 - they are the users of the system. - -### Transactors: make transaction - -Transactors make a transaction much like they do in the existing Ethereum system. One or two minor differences - addresses can be used as a distance metric; those sharing the same number of initial bits are considered "closer", which means a greater certainty into the future that they will continue to be contained in the same state subspace. Contracts are naturally created in the same state subspace as the creator. - -Transactions, like Collators, operate over a number of fibers; perhaps one perhaps all, probably somewhere in between. Submission to collators may be directed through fiber sub-network overlays. - -Submission and payment to the collators happens much as existing transaction submission to miners happens in Ethereum 1.0. - - -## Collators - -Collators maintain presence on at least two peer sub-network overlays; the Validators overlay, and one or more fiber overlays. The fiber overlays may provide directed transaction propogation. Collators "collate" on a set of fibers. They maintain a full fiber-chain for each fiber they collate over, and can accept all transactions that involve any combination of their fiber set. The greater this combination, then the greater their "transaction net", but the greater their overall disk/memory footprint. - -### Collators: validate transaction - -On receipt of a transaction, they go through the usual Ethereum 1.0 rites of checking payment is enough, initial balances &c. Once basic validation is done, they attempt to execute it, throwing it out if it touches any fiber that is not part of collator's fiber set. - -### Collators: produce Comprehensive Merkle Proof and Post State Root - -Collators provide each post-state-root (as is found in the transaction receipt of Ethereum 1.0) and append to the block Merkle proofs and associated hints (e.g. contract code) for all inputs (balance, nonce, state, code) from all subspaces that are required for the evaluation of each transaction from a previously known post-state-root. - -This allows an auditor to, without anything other than the previous post-state-root for each fiber, determine the validity of the block. - -### Collators: collate into X-fiber Block - -A Cross Fiber Block is created from the total information collated. This includes transactions, transaction receipts (post-state-roots), Comprehensive Merkle-Proofs and associated hash-hints. This block does not include any consensus-specific information such as timestamping, uncles &c. - - -## Validators - -Validators (who might be better named auditors) are bonded particpants, chosen regularly from the highest bidders, who take a small fee for the ultimate maintenence of the network. Their job, as a whole, is to form a judiciary and ultimate authority over the validity and transaction contents of the chain. We generally assume that they are mostly benevolent and cannot all be bribed. Being bonded, validators may also be called to audit and stake their bond on an opinion over validity or information-availability. - -### Validators: all placed in PoS-consensus master block - -They maintain signing control over the Master Chain. The Master Chain (MC) encodes all PoS/consensus stuff like timestamping and includes its own little state root for recording validator's bond balances, ongoing challenges, fiber block header-hashes and any other housekeeping information. - -Each master block (MB), a set of collated X-Fiber Blocks (XBs) are taken; these must be non-overlapping, so that each fiber belongs to only a single XB. - -### Validators: random selection chosen to audit TX/PSR/CMP contents & availability - -For each MB we have a number of XSBs referenced from the MB's Trie. Each fiber is assigned a randomly selected set of validators, and the validators must review whatever XB contains their assigned fiber. Validation includes attaining the XB, finding the previous PSRs for each of the fibers (placed in the MB) and checking that the proofs in its CMP, cover all required inputs to the transactions collated within and that the PSR is indeed the final state root when all are executed. - -The block is considered valid iff all assigned validators sign it. Signing it is considered an assertion that the block contents are both valid and available for a probabilistically long "challenge period" in which a Fisherman may challenge. Any challenge to the block's validity which is ultimately upheld by a full consensus of a randomly selected set of validators (ultimately ending with a majority vote, should it be doggedly contested) will mean the instant loss of the bond. - - -## Fishermen - -Fishermen (who might be called bounty hunters) are the freelance error-checkers of the system. The watch the validators in the hope that they can find wrong-doing. To help guarantee presence, payouts are designed to be huge. The costs of challenging are small but not insignificant. - -### Fishermen: search for invalid or unavailable X-fiber blocks - -They check the X-fiber blocks looking for validity errors and/or inavailability of data. When they find an invalid block or unavailable data, they launch a challenge (for a small fee, paid to validators) in the hope that a sufficiently large portion of validators will concur. If they succeed and validators ultimately uphold the challenge, then they receive the bonds of all validators who had previously asserted validity/availability of the information. - -### Fishermen's Challenge: - -1. Fisherman finds an invalid/unavailable block not yet outside its "challenge period" (10-30 blocks); pays a fee, submits a challenge transaction into the master chain; -2. A randomly selected set of validators (e.g. of order e.g. sqrt(N)) ++ any validators that self-select (through doubling their bond), check the block that was challenged; each votes Y or N to the block's validity; - - If N, the validator receives a small payment Pn. - - If Y, the validator stakes their bond, though receives a larger payment Py (perhaps Py = 2Pn). -3. The outcome of the challenge (probably accumulated into the following block) is: - - If more than 66% of validators vote Y (valid), then the challenge ends. The Fisherman loses their fee, but may reinitiate a challenge. - - If at least one validator votes Y (valid), then the challenge continues with a second, larger set of randomly selected validators. All bonds are staked. - - If all validators vote N (invalid), then the block is recorded as invalid and the Fishermen receives the bond of all validators that have asserted the blocks validity. This is a very large payoff. - - NOTE: If the set includes all validators, then it's a simple majority-carries rule. - - -## Other differences - -- All addresses are contained in a lookup table unique to each state subspace; this means they can be referenced through a small number of bits and avoid large amounts of wasted entropy in the RLP for proofs &c. - -## Notes - -- Once a block is out of the challenge period, it is considered unassailable. If it does turn out to be bad, then it must be fixed in the same way as a protocol upgrade. As such it is likely that validators and other large stakeholder would act as Fishermen to protect their investment. diff --git a/Clearinghouse.md b/Clearinghouse.md deleted file mode 100644 index 18b429c07..000000000 --- a/Clearinghouse.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -name: Clearinghouse -category: ---- - -### Introduction - -In some type of financial instruments like Futures (but not Forwards), parties are guaranteed against credit losses resulting from the counterparty default by a "clearinghouse". Essentially, a clearinghouse provides this guarantee via a procedure in which the gains and losses that accrue on daily basis throughout the life of a contract are converted into actual cash (daily settlement of gains or losses). - -### Daily Settlement - -As explained a daily settlement is the actual conversion into cash of daily gains or losses. This procedure is called **daily settlement** or **marking to market** and it is best illustrated via an actual example. - -Let's assume two parties enter a Future contract to buy some underlying with a settlement price of 100 USD in a month time (not to be confused with the daily settlement procedure). In order to enter this contract the clearinghouse will set an **initial margin requirement**both the future traders (in this case the party that is going to buy the underlying or the **holder of the long position** and the party that is selling the underlying or the **holder of the short position**) will have to deposit upfront (notice in the context of clearinghouse operations **margin** does not have the same meaning of leverage trading on borrowed money that is used elsewhere). Our initial margin requirement will be 5 USD per contract and will be deposited into a clearinghouse **margin account** associated with the specific contract. - -During the life of the contract as the margin account balances change, the parties involved in the contract must maintains their corresponding balances above a level called the **maintenance margin requirement** again decided by the clearinghouse and usually lower than the initial margin. - -At the end of each day, the clearinghouse will provide a **settlement price** (usually an average price of any trades that happened during the day) and execute the **mark-to-market** process (daily settlement). - -In our specific example, let's assume the maintenance margin has been set at 3 USD per contract and buying party is entering 10 contract (in other words he will have to deposit an initial margin of 50 USD. We shall also assume money cannot be withdrawn from the clearinghouse (i.e. excess funds). The initial price will be 100 USD (the price of the future contract). - -A complete example, is provided in the table below. Notice the two panels report the daily balances of the two parties (long and short). - - -#### Panel A. Holder of Long Position of 10 Contracts - -|Day (1)|Beginning Balance (2)|Funds Deposited (3)|Settlement Price (4)|Futures Price Change (5)|Gain/Loss (6)|Ending Balance (7)| -|:----------:|-------------:|------:|---:|---:|---:|---:| -|0|0|50|100.0| - | - |50| -|1|50|0|99.20| -0.80| -8|42| -|2|42|0|96.00| -3.20| -32|10| -|3|10|40|101.00|5.00|50|100| -|4|100|0|103.50|2.50|25|125| -|5|125|0|103.00| -0.50| -5|120| -|6|120|0|104.00|1.00|10|130| - - -#### Panel B. Holder of Short Position of 10 Contracts -|Day (1)|Beginning Balance (2)|Funds Deposited (3)|Settlement Price (4)|Futures Price Change (5)|Gain/Loss (6)|Ending Balance (7) -|:----------:|-------------:|------:|---:|---:|---:|---:| -|0|0|50|100.0| -| -|50 -|1|50|0|99.20| -0.80|8|58 -|2|58|0|96.00| -3.20|32|90 -|3|90|0|101.00|5.00| -50|40 -|4|40|0|103.50|2.50| -25| 15 -|5|15|35|103.00| -0.50| 5|55 -|6|55|0|104.00|1.00| -10|45|} - -The day the contract is entered will be referred as ''Day 0'', both parties will deposit an initial margin of 50 USD and we shall assume that on ''Day 1'' the future price moves down to 99.20 USD as indicated in Column 4 of Panel A. In Column 5 we can see the Future price change -0.80 (99.20 - 100) and this amount is multipled by the number of contract, 10, to obtain the number in Column 6: -0.80 x 10 = - 8 USD. The ending balance is shown in Column 7 and it is the beginning balance plus/minus any gain/loss. The ending balance on Day 1 for the Holder of the Long Position is 42 USD and it is above the maintenance margin of 30 USD so no extra deposit is required. - -### Ethereum clearinghouse implementation and logic - -* does it apply to all contracts? -* which flag should be set to enable clearinghouse? -* how are the money/ether debited/credited? Push or pull system? -* Normally clearinghouses use an average daily price (not close price). How to implement? THIS IS IMPORTANT TO AVOID PRICE MANIPULATION ethereum would be even more vulnerable than classic clearinghouse. -* what happens in case of default (failed margin call)? Reputation system? -* many contracts will require an external price feed (i.e. Gold price from CME or LIBOR interest rates). How do we feed them? -* can money being withdrawn from the clearinghouse (i.e. excess funds/gains)? Would be simpler if this was not the case. -* what if the parties really want to exchange the underlying? i.e. no cash/ether settlement? (NOT SPECIFIC TO CLEARINGHOUSE) -* losses/gains are magnified by the leverage inherently provided by the clearinghouse. ACCEPTABLE FOR ETHEREUM? NOTICE ALTHOUGH A FULL SUM DO NOT NEED TO BE DEPOSITED UPFRONT. - -### Code reference sample diff --git a/Contract-Metadata-Docs-(NatSpec,-ABI).md b/Contract-Metadata-Docs-(NatSpec,-ABI).md deleted file mode 100644 index 4c845dd8d..000000000 --- a/Contract-Metadata-Docs-(NatSpec,-ABI).md +++ /dev/null @@ -1,92 +0,0 @@ ---- -name: Contract Metadata Docs -category: ---- - -This is the main entry point for NatSpec and generally details a safe and efficient _standard_ for ethereum contract metadata distribution. - -By metadata we mean all information related to a contract that is thought to be relevant to and immutably linked to a specific version of a contract on the ethereum blockchain. -This includes: - -* Contract source code -* [ABI definition](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI) -* [NatSpec user doc](https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format#user-documentation) -* [NatSpec developer's doc](https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format#developer-documentation) - -These resources have their _standard specification_ in json format, ideally meant to be produced by IDE infrastructures or compilers directly. - -For instance, the [solidity](https://github.com/ethereum/wiki/wiki/Solidity-Tutorial) compiler offers a `doxygen` style way of specifying natspec with inline smart comments. Upon compilation it creates both NatSpec user doc as well ABI definition. But note that there is nothing inherently solidity specific about these data, and other contract languages are encouraged to implement their NatSpec/ABI support potentially with IDE-s extending it. - -Since DAPPs and IDEs will typically want to interact with these resources, standardising their deployment and distribution is important for a smooth ethereum experience. - -A specially important example of this is the **NatSpec transaction confirmation notice scheme**, which we will use to illustrate the point. However, the strategy described here trivially extends to arbitrary immutable metadata fixed to an ethereum contract. - -# Transaction Confirmation Notice - -The NatSpec user doc allows contract creators to attach custom confirmation notices to each method. -A powerful feature of NatSpec is to provide templating which allows parts of the user notice to be instantiated depending on the parameters of the actual transaction sent to the contract. - -Trusted ethereum client implementations are required to call back from their backend instantiating the natspec transaction notice from actual transaction data and present it to the user for confirmation. - -This serves as a first line of defense against illegitimate transactions sent by malicious DAPPs in the user's name. - -Surely, this is only feasible if -- the node can trust the authenticity of metadata sources. -- nodes have secure reliable access to the metadata resources - -Let's see how this is achieved. - -## Metadata Authentication - -**Proposal** -The metadocs are assumed to be in a single JSON structure called `cmd` file, that stands for _contract metadata doc_. - -The `cmd` file's content is hashed and content hash is registered on a name registry via a contract on the ethereum blockchain under the code hash, see https://github.com/ethereum/dapp-bin/blob/master/NatSpecReg/contract.sol _Registering_ in this context will simply mean a key value pair is recorded in an immutable contract storage as a result of a transaction sent to the registry contract. - -This provides a public immutable authentication for contract metadata, since: -- the authenticity of the link between the contract and metadata is secured by ethereum consensus -- the authenticity of actual metadata content is secured by content hashing -- the binding is tamper proof - - -DAPP IDE environments are supposed to support the functionality, that when you create a contract, all its standard metadata is -- bundled in a single `cmd` json file -- compiled source code is keccak hashed -> `Sha3()` -- `cmd` json is keccak hashed -> `Sha3()` -- the metadata is registered with the contract by sending a transaction to a trusted name registry. The transaction simply records `Sha3() -> Sha3()` as a key value pair in contract storage. - -In order to avoid malicious agents hijacking metadata by overwriting the namereg entry, we propose the following business process: - -- the link should be registered before a contract is deployed and is immutable from then on. -- before the corresponding contract is deployed, we check if the correct metadata bundle is found in the registry and confirmed to a satisfying level of certainty (X blocks). - -How it looks like in `Alethzero` is illustrated [here]|( -https://github.com/ethereum/wiki/wiki/NatSpec-Example) - -## Metadata Access - -In order to provide a robust (failure resistant, 100% uptime) service, decentralised file storage services can and will be used. In the case of content addressed systems like Swarm, accessing and fetching the resource you will only need the `cmd` content hash (using `BZZHASH(`). - -Until that point is reached, we will fall back to using HTTP distribution. To enable this we will include one or many URLHint contracts, which provide hints of URLs that allow downloading of particular content hashes. Find the contract in dapp-bin. - -The content downloaded should be treated in many ways (and hashed) to discover what the content is. Possible ways include base 64 encoding, hex encoding and raw, and any content-cropping needed (e.g. a HTML page should have everything up to body tags removed). - -It will be up to the dapp/content uploader to keep URLHint entries updated. - -The address of the URLHint contract will be specified on an ad-hoc basis and users will be able to enter additional ones into their browser. - -This functionality of uploading and registering location is supposed to be also supported by IDE and dev infrastructures. Developers (or IDE) are encouraged to register cmd location _before_ content hash registration (and therefore before actual contract creation) in order to avoid metadata hijacking. Note that if content hash registration is correct, hijacking the location cannot allow malicious content (since content hash authenticates the `cmd`), however it can still prevent your metadata from being accessible. Therefore -- the url-hint contract storage should be by definition immutable -- content-hash to url-hint should be registered before contract creation - -(surely with old web urls, we are always exposed to server failure/hacking, etc) - -Read more [here](https://github.com/ethereum/wiki/wiki/NatSpec-Determination) - -## Name registry contracts - -Interoperability requires that clients know where to look to resolve a contract's metadata, i.e., which name registry to use. Currently, we solve this by -- creating the two registry contracts after the genesis block -- and hardwiring their addresses in the client code (e.g., in the natspec transaction confirmation notice module on the client side and the deployment module on the dev/IDE side). - - diff --git a/Dagger-Hashimoto.md b/Dagger-Hashimoto.md deleted file mode 100644 index 680e23845..000000000 --- a/Dagger-Hashimoto.md +++ /dev/null @@ -1,338 +0,0 @@ ---- -name: Dagger Hashimoto -category: ---- - -## Introduction - -Dagger Hashimoto is a proposed spec for the mining algorithm for Ethereum 1.0. Dagger Hashimoto aims to simultaneously satisfy two goals: - -1. **ASIC-resistance**: the benefit from creating specialized hardware for the algorithm should be as small as possible, ideally to the point that even in an economy where ASICs have been developed the speedup is sufficiently small that it is still marginally profitable for users on ordinary computers to mine with spare CPU power. -2. **Light client verifiability**: a block should be relatively efficiently verifiable by a light client. - -With an additional modification, we also specify how to fulfill a third goal if desired, but at the cost of additional complexity: - -3. **Full chain storage**: mining should require storage of the complete blockchain state (due to the irregular structure of the Ethereum state trie, we anticipate that some pruning will be possible, particularly of some often-used contracts, but we want to minimize this). - -Dagger Hashimoto builds on two key pieces of previous work: - -* [Hashimoto](http://vaurum.com/hashimoto.pdf), an algorithm by Thaddeus Dryja which intends to achieve ASIC resistance by being IO-bound, ie. making memory reads the limiting factor in the mining process. The theory is that RAM is in principle inherently a much more generic ingredient than computation, and billions of dollars of research already go into optimizing it for different use cases which often involve near-random access patterns (hence "random access memory"); hence, existing RAM is likely to be moderately close to optimal for evaluating the algorithm. Hashimoto uses the blockchain as a source of data, simultaneously satisfying (1) and (3) above. -* [Dagger](http://vitalik.ca/ethereum/dagger.html), an algorithm by Vitalik Buterin which uses directed acyclic graphs to simultaneously achieve memory-hard computation but memory-easy validation. The core principle is that each individual nonce only requires a small portion of a large total data tree, and recomputing the subtree for each nonce is prohibitive for mining - hence the need to store the tree - but okay for a single nonce's worth of verification. Dagger was meant to be an alternative to existing memory-hard algorithms like [Scrypt](http://en.wikipedia.org/wiki/Scrypt), which are memory-hard but are also very hard to verify when their memory-hardness is increased to genuinely secure levels. However, Dagger was proven to be vulnerable to shared memory hardware acceleration [by Sergio Lerner](https://bitslog.wordpress.com/2014/01/17/ethereum-dagger-pow-is-flawed/) and was then dropped in favor of other avenues of research. - -Approaches that were tried between Dagger and Dagger Hashimoto but are currently not our primary focus include: - -* "Blockchain-based proof of work" - a proof of work function that involves running contracts taken from the blockchain. The approach was abandoned because it was long-range attack vulnerabilities, since attackers can create forks and populate them with contracts that they have a secret fast "trapdoor" execution mechanism for. -* "Random circuit" - a proof of work function developed largely by Vlad Zamfir that involves generating a new program every 1000 nonces - essentially, choosing a new hash function each time, faster than even FPGAs can reconfigure. The approach was temporarily put aside because it was difficult to see what mechanism one can use to generate random programs that would be general enough so that specialization gains would be low; however, we see no fundamental reasons why the concept cannot be made to work. - -The difference between Dagger Hashimoto and Hashimoto is that, instead of using the blockchain as a data source, Dagger Hashimoto uses a custom-generated 1 GB data set, which updates based on block data every N blocks. The data set is generated using the Dagger algorithm, allowing for the efficient calculation of a subset specific to every nonce for the light client verification algorithm. The difference between Dagger Hashimoto and Dagger is that, unlike in the original Dagger, the dataset used to query the block is semi-permanent, only being updated at occasional intervals (eg. once per week). This means that the portion of the effort that goes toward generating the dataset is close to zero, so Sergio Lerner's arguments regarding shared memory speedups become negligible. - -## DAG Generation - -The code for the algorithm will be defined in Python below. First, we give `encode_int` for marshaling unsigned ints of specified precision to strings. Its inverse is also given: - -```python -NUM_BITS = 512 - -def encode_int(x): - "Encode an integer x as a string of 64 characters using a big-endian scheme" - o = '' - for _ in range(NUM_BITS / 8): - o = chr(x % 256) + o - x //= 256 - return o - -def decode_int(s): - "Unencode an integer x from a string using a big-endian scheme" - x = 0 - for c in s: - x *= 256 - x += ord(c) - return x -``` - -We next assume that `sha3` is a function that takes an integer and outputs an integer, and `dbl_sha3` is a double-sha3 function; if converting this reference code into an implementation use: - -```python -from pyethereum import utils -def sha3(x): - if isinstance(x, (int, long)): - x = encode_int(x) - return decode_int(utils.sha3(x)) - -def dbl_sha3(x): - if isinstance(x, (int, long)): - x = encode_int(x) - return decode_int(utils.sha3(utils.sha3(x))) -``` - -### Parameters - -The parameters used for the algorithm are: - -```python -SAFE_PRIME_512 = 2**512 - 38117 # Largest Safe Prime less than 2**512 - -params = { - "n": 4000055296 * 8 // NUM_BITS, # Size of the dataset (4 Gigabytes); MUST BE MULTIPLE OF 65536 - "n_inc": 65536, # Increment in value of n per period; MUST BE MULTIPLE OF 65536 - # with epochtime=20000 gives 882 MB growth per year - "cache_size": 2500, # Size of the light client's cache (can be chosen by light - # client; not part of the algo spec) - "diff": 2**14, # Difficulty (adjusted during block evaluation) - "epochtime": 100000, # Length of an epoch in blocks (how often the dataset is updated) - "k": 1, # Number of parents of a node - "w": w, # Used for modular exponentiation hashing - "accesses": 200, # Number of dataset accesses during hashimoto - "P": SAFE_PRIME_512 # Safe Prime for hashing and random number generation -} -``` - -`P` in this case is a prime chosen such that `log₂(P)` is just slightly less than 512, which corresponds to the 512 bits we have been using to represent our numbers. Note that only the latter half of the DAG actually needs to be stored, so the de-facto RAM requirement starts off at 1 GB and grows by 441 MB per year. - -### Dagger graph building - -The dagger graph building primitive is defined as follows: - -```python -def produce_dag(params, seed, length): - P = params["P"] - picker = init = pow(sha3(seed), params["w"], P) - o = [init] - for i in range(1, length): - x = picker = (picker * init) % P - for _ in range(params["k"]): - x ^= o[x % i] - o.append(pow(x, params["w"], P)) - return o -``` - -Essentially, it starts off a graph as a single node, `sha3(seed)`, and from there starts sequentially adding on other nodes based on random previous nodes. When a new node is created, a modular power of the seed is computed to randomly select some indices less than `i` (using `x % i` above), and the values of the nodes at those indices are used in a calculation to generate a new a value for `x`, which is then fed into a small proof of work function (based on XOR) to ultimately generate the value of the graph at index `i`. The rationale behind this particular design is to force sequential access of the DAG; the next value of the DAG that will be accessed cannot be determined until the current value is known. Finally, modular exponentiation is used to further hash the result. - -This algorithm relies on several results from number theory. See the appendix below for a discussion. - -## Light Client Evaluation - -The intent of the above graph construction is to allow each individual node in the graph can be reconstructed by computing a subtree of only a small number of nodes, and requiring only a small amount of auxiliary memory. Note that with k=1, the subtree is only a chain of values going up to the first element in the DAG. - -The light client computing function for the DAG works as follows: - -```python -def quick_calc(params, seed, p): - w, P = params["w"], params["P"] - cache = {} - - def quick_calc_cached(p): - if p in cache: - pass - elif p == 0: - cache[p] = pow(sha3(seed), w, P) - else: - x = pow(sha3(seed), (p + 1) * w, P) - for _ in range(params["k"]): - x ^= quick_calc_cached(x % p) - cache[p] = pow(x, w, P) - return cache[p] - - return quick_calc_cached(p) -``` - -Essentially, it is simply a rewrite of the above algorithm that removes the loop of computing the values for the entire DAG and replaces the earlier node lookup with a recursive call or a cache lookup. Note that for `k=1` the cache is unnecessary, although a further optimization actually precomputes the first few thousand values of the DAG and keeps that as a static cache for computations; see the appendix for a code implementation of this. - -## Double Buffer of DAGs - -In a full client, a [*double buffer*](https://en.wikipedia.org/wiki/Multiple_buffering) of 2 DAGs produced by the above formula is used. The idea is that DAGs are produced every `epochtime` number of blocks according to the params above. The client does not use the latest DAG produced, but the previous one. The benefit of this is that it allows the DAGs to be replaced over time without needing to incorporate a step where miners must suddenly recompute all of the data. Otherwise, there is the potential for an abrupt temporary slowdown in chain processing at regular intervals and dramatically increasing centralization and thus 51% attack risks within those few minutes before all data is recomputed. - -The algorithm used to generate the actual set of DAGs used to compute the work for a block is as follows: - -```python -def get_prevhash(n): - from pyethereum.blocks import GENESIS_PREVHASH - from pyethreum import chain_manager - if n <= 0: - return hash_to_int(GENESIS_PREVHASH) - else: - prevhash = chain_manager.index.get_block_by_number(n - 1) - return decode_int(prevhash) - -def get_seedset(params, block): - seedset = {} - seedset["back_number"] = block.number - (block.number % params["epochtime"]) - seedset["back_hash"] = get_prevhash(seedset["back_number"]) - seedset["front_number"] = max(seedset["back_number"] - params["epochtime"], 0) - seedset["front_hash"] = get_prevhash(seedset["front_number"]) - return seedset - -def get_dagsize(params, block): - return params["n"] + (block.number // params["epochtime"]) * params["n_inc"] - -def get_daggerset(params, block): - dagsz = get_dagsize(params, block) - seedset = get_seedset(params, block) - if seedset["front_hash"] <= 0: - # No back buffer is possible, just make front buffer - return {"front": {"dag": produce_dag(params, seedset["front_hash"], dagsz), - "block_number": 0}} - else: - return {"front": {"dag": produce_dag(params, seedset["front_hash"], dagsz), - "block_number": seedset["front_number"]}, - "back": {"dag": produce_dag(params, seedset["back_hash"], dagsz), - "block_number": seedset["back_number"]}} -``` - -## Hashimoto - -The idea behind the original Hashimoto is to use the blockchain as a dataset, performing a computation which selects N indices from the blockchain, gathers the transactions at those indices, performs an XOR of this data, and returns the hash of the result. Thaddeus Dryja's original algorithm, translated to Python for consistency, is as follows: - -```python -def orig_hashimoto(prev_hash, merkle_root, list_of_transactions, nonce): - hash_output_A = sha256(prev_hash + merkle_root + nonce) - txid_mix = 0 - for i in range(64): - shifted_A = hash_output_A >> i - transaction = shifted_A % len(list_of_transactions) - txid_mix ^= list_of_transactions[transaction] << i - return txid_max ^ (nonce << 192) -``` - -Unfortunately, while Hashimoto is considered RAM hard, it relies on 256-bit arithmetic, which has considerable computational overhead. To address this issue, dagger hashimoto only uses the least significant 64 bits when indexing its dataset. - -```python -def hashimoto(dag, dagsize, params, header, nonce): - m = dagsize / 2 - mix = sha3(encode_int(nonce) + header) - for _ in range(params["accesses"]): - mix ^= dag[m + (mix % 2**64) % m] - return dbl_sha3(mix) -``` - -The use of double sha3 allows for a form of zero-data, near-instant pre-verification, verifying only that a correct intermediate value was provided. This outer layer of PoW is highly ASIC-friendly and fairly weak, but exists to make DDoS even more difficult since that small amount of work must be done in order to produce a block that will not be rejected immediately. Here is the light-client version: - -```python -def quick_hashimoto(seed, dagsize, params, header, nonce): - m = dagsize // 2 - mix = sha3(nonce + header) - for _ in range(params["accesses"]): - mix ^= quick_calc(params, seed, m + (mix % 2**64) % m) - return dbl_sha3(mix) -``` - -## Mining and Verifying - -Now, let us put it all together into the mining algo: - -```python -def mine(daggerset, params, block): - from random import randint - nonce = randint(0, 2**64) - while 1: - result = hashimoto(daggerset, get_dagsize(params, block), - params, decode_int(block.prevhash), nonce) - if result * params["diff"] < 2**256: - break - nonce += 1 - if nonce >= 2**64: - nonce = 0 - return nonce -``` - -Here is the verification algorithm: -```python -def verify(daggerset, params, block, nonce): - result = hashimoto(daggerset, get_dagsize(params, block), - params, decode_int(block.prevhash), nonce) - return result * params["diff"] < 2**256 -``` - -Light-client friendly verification: - -```python -def light_verify(params, header, nonce): - seedset = get_seedset(params, block) - result = quick_hashimoto(seedset["front_hash"], get_dagsize(params, block), - params, decode_int(block.prevhash), nonce) - return result * params["diff"] < 2**256 -``` - -Also, note that Dagger Hashimoto imposes additional requirements on the block header: - -* For two-layer verification to work, a block header must have both the nonce and the middle value pre-sha3 -* Somewhere, a block header must store the sha3 of the current seedset - -# Appendix - -As noted above, the RNG used for DAG generation relies on some results from number theory. First, we provide assurance that the Lehmer RNG that is the basis for the `picker` variable has a wide period. Second, we show that `pow(x,3,P)` will not map `x` to `1` or `P-1` provided `x ∈ [2,P-2]` to start. Finally, we show that `pow(x,3,P)` has a low collision rate when treated as a hashing function. - -## Lehmer Random Number Generator - -While the `produce_dag` function does not need to produce unbiased random numbers, a potential threat is that `seed**i % P` only takes on a handful of values. This could provide an advantage to miners recognizing the pattern over those that do not. - -To avoid this, a result from number theory is appealed to. A [*Safe Prime*](https://en.wikipedia.org/wiki/Safe_prime) is defined to be a prime `P` such that `(P-1)/2` is also prime. The *order* of a member `x` of the [multiplicative group](https://en.wikipedia.org/wiki/Multiplicative_group_of_integers_modulo_n) `ℤ/nℤ` is defined to be the minimal `m` such that
xᵐ mod P ≡ 1
-Given these definitions, we have: - -> Observation 1. Let `x` be a member of the multiplicative group `ℤ/Pℤ` for a safe prime `P`. If `x mod P ≠ 1 mod P` and `x mod P ≠ P-1 mod P`, then the order of `x` is either `P-1` or `(P-1)/2`. - -*Proof*. Since `P` is a safe prime, then by [Lagrange's Theorem][Lagrange] we have that the order of `x` is either `1`, `2`, `(P-1)/2`, or `P-1`. - -The order of `x` cannot be `1`, since by Fermat's Little Theorem we have: -
xP-1 mod P ≡ 1
-Hence `x` must be a multiplicative identity of `ℤ/nℤ`, which is unique. Since we assumed that `x ≠ 1` by assumption, this is not possible. - -The order of `x` cannot be `2` unless `x = P-1`, since this would violate that `P` is prime. -
- -From the above proposition, we can recognize that iterating `(picker * init) % P` will have a cycle length of at least `(P-1)/2`. This is because we selected `P` to be a safe prime approximately equal to be a higher power of two, and `init` is in the interval `[2,2**256+1]`. Given the magnitude fo `P`, we should never expect a cycle from modular exponentiation. - -When we are assigning the first cell in the DAG (the variable labeled `init`), we compute `pow(sha3(seed) + 2, 3, P)`. At first glance, this does not guarantee that the result is neither `1` nor `P-1`. However, since `P-1` is a safe prime, we have the following additional assuance, which is a corollary of Observation 1: - -> Observation 2. Let `x` be a member of the multiplicative group `ℤ/Pℤ` for a safe prime `P`, and let `w` be a natural number. If `x mod P ≠ 1 mod P` and `x mod P ≠ P-1 mod P`, as well as `w mod P ≠ P-1 mod P` and `w mod P ≠ 0 mod P`, then `xʷ mod P ≠ 1 mod P` and `xʷ mod P ≠ P-1 mod P` - -[Lagrange]: https://en.wikipedia.org/wiki/Lagrange%27s_theorem_(group_theory) - -## Modular Exponentiation as a Hash Function - -For certain values of `P` and `w`, the function `pow(x, w, P)` may have many collisions. For instance, `pow(x,9,19)` only takes on values `{1,18}`. - -Given that `P` is prime, then an appropriate `w` for a modular exponentation hashing function can be chosen using the following result: - -> Observation 3. Let `P` be a prime; `w` and `P-1` are relatively prime if and only if for all `a` and `b` in `ℤ/Pℤ`:
`aʷ mod P ≡ bʷ mod P` if and only if `a mod P ≡ b mod P`
- -Thus, given that `P` is prime and `w` is relatively prime to `P-1`, we have that `|{pow(x, w, P) : x ∈ ℤ}| = P`, implying that the hashing function has the minimal collision rate possible. - -In the special case that `P` is a safe prime as we have selected, then `P-1` only has factors 1, 2, `(P-1)/2` and `P-1`. Since `P` > 7, we know that 3 is relatively prime to `P-1`, hence `w=3` satisfies the above proposition. - -## More Efficient Cache-based Evaluation Algos - - def quick_calc(params, seed, p): - cache = produce_dag(params, seed, params["cache_size"]) - return quick_calc_cached(cache, params, p) - - def quick_calc_cached(cache, params, p): - P = params["P"] - if p < len(cache): - return cache[p] - else: - x = pow(cache[0], p + 1, P) - for _ in range(params["k"]): - x ^= quick_calc_cached(cache, params, x % p) - return pow(x, params["w"], P) - - def quick_hashimoto(seed, dagsize, params, header, nonce): - cache = produce_dag(params, seed, params["cache_size"]) - return quick_hashimoto_cached(cache, dagsize, params, header, nonce) - - def quick_hashimoto_cached(cache, dagsize, params, header, nonce): - m = dagsize // 2 - mask = 2**64 - 1 - mix = sha3(encode_int(nonce) + header) - for _ in range(params["accesses"]): - mix ^= quick_calc_cached(cache, params, m + (mix & mask) % m) - return dbl_sha3(mix) - - ------------------------------------ - -Special thanks to feedback from: - -* Tim Hughes -* Matthew Wampler-Doty -* Thaddeus Dryja diff --git a/Dagger.md b/Dagger.md deleted file mode 100644 index d0c2231d6..000000000 --- a/Dagger.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -name: Dagger -category: ---- - -**Note: we will not be using Dagger as our Proof of Work algorithm. This page is pending deletion** - -Over the past five years of experience with Bitcoin and alternative cryptocurrencies, one important property for proof of work functions that has been discovered is that of "memory-hardness" - computing a valid proof of work should require not only a large number of computations, but also a large amount of memory. Currently, there are three major categories of memory-hard functions used in mining: scrypt, Primecoin mining and the birthday problem. However, both are imperfect: neither require nearly as much memory as an ideal memory-hard function could require, and both suffer from time-memory tradeoff attacks, where the function can be computed with significantly less memory than intended at the cost of sacrificing some computational efficiency. - -Dagger is a proof of work algorithm intended to solve these problems, providing a memory-hard proof of work based on moderately connected directed acyclic graphs (DAGs, hence the name), which, while far from optimal, has much stronger memory-hardness properties than anything else in use today. - -## Why Be Memory-Hard? - -The main reason why memory hardness is important is to make the proof of work function resistant to specialized hardware. With Bitcoin, whose mining algorithm requires only a simple SHA256 computation, companies have already existed for over a year that create specialized "application-specific integrated circuits" (ASICs) designed and configured in silicon for the sole purpose of computing billions of SHA256 hashes in an attempt to "mine" a valid Bitcoin block. These chips have no legitimate applications outside of Bitcoin mining and password cracking, and the presence of these chips, which are thousands of times more efficient per dollar and kilowatt hour at computing hashes than generic CPUs, makes it impossible for ordinary users with generic CPU and GPU hardware to compete. - -This dominance of specialized hardware has several detrimental effects: - -1. **It negates the democratic distribution aspect of cryptocurrency mining**. In a generic hardware-dominated ecosystem, the fact that everyone has a computer guarantees that everyone will have an equal opportunity to earn at least some of the initial money supply. With specialized hardware, this factor does not exist; each economic actor's mining potential is linear (in fact, slightly superlinear) in their quantity of pre-existing capital, potentially exacerbating existing wealth inequalities. -2. **It increases resource waste**. In an efficient market, marginal revenue approaches marginal cost. Since mining revenue is a linear function of money spent on mining hardware and electricity, this also implies that total revenue approaches total cost. Hence, in a specialized hardware dominated ecosystem, the quantity of resources wasted is close to 100% of the security level of the network. In a CPU and GPU-dominated ecosystem, because everyone already has a computer, people do not need to buy specialized hardware for the first few hashes per second worth of mining power. Hence, revenue is sublinear in cost - everyone gets a bit of revenue "for free". This implies that the quantity of resources wasted by the network is potentially considerably lower than its security parameter. -3. **It centralizes mining in the hands of a few actors** (ie. ASIC manufacturers), making 51% attacks much more likely and potentially opening the network up to regulatory pressure. - -Specialized hardware is so powerful because it includes many thousands of circuits specifically designed for computing the proof of work function, allowing the hardware to compute the function thousands of times in parallel. Memory hardness alleviates this problem by making the main limiting factor not CPU power, but memory. One can also make a modest improvement by targeting CPU clock speed, but the extent to which such optimizations can be made is fundamentally limited to a very low value by technological considerations. Thus, improvement through parallelization hits a roadblock: running ten memory-hard computations in parallel requires ten times as much memory. Specialized hardware menufacturers can certainly pack terabytes of memory into their devices, but the effect of this is mitigated by two factors. First, hobbyists can achieve the same effect by simply buying many off-the-shelf memory cards. Second, memory is much more expensive to produce (if measured in laptop equivalents) than SHA256 hashing chips; the RAM used in ordinary computers is already essentially optimal. - -## Objections to Memory-Hardness - -1. **All algorithms will be vulnerable to ASICs eventually**. This point has become more popular especially after the recent announcement from a company producing ASICs for Scrypt, and essentially states that theoretically any algorithm can be better done by specialized hardware than general purpose hardware, and so there is no point in trying to make algorithms targeted to general purpose hardware. What the argument misses, however, is that the speedup from applying specialized hardware to the moderately memory-hard Scrypt has been demonstrated to be much lower than for Bitcoin. Furthermore, there are indeed reasons to suggest the trend will continue - as described above, the memory found in commodity hardware is much closer to optimal than the computing circuits. -2. **Botnets will take over the mining process**. This point can also be addressed in two ways: empirically and theoretically. Empirically, botnets so far have not been substantially involved in mounting 51% attacks in existing altcoins, generally, they are content simply to extract revenue as "legitimate" miners. Theoretically, the current public prominence of botnets as a threat is backed largely by their performance in network flooding / denial of service attacks - situations where each computer in a botnet is only used for the number of connections that it can make. In the context of mining, however, botnet-infected computers tend to be running older operating systems and have weaker specifications, meaning that they will have a much lower performance and impact on the network than their size might initially suggest. - -## Existing alternatives - -The existence of every new algorithm, protocol of cryptographic primitive as opposed to existing and more well-tested technologies must always be strongly justified; in as delicate an area as cryptocurrency, caution is very important both because the system will handle millions of dollars of capital and because if a mistake is made there is no way to simply upgrade to a new version with a bugfix. The purpose of this section will be to go through the three existing alternatives and show why they are inadequate. - -### Scrypt - -Scrypt is the algorithm used by Litecoin, Dogecoin and most other new cryptocurrencies coming out today. A very simplified description of Scrypt-like algorithms is as follows: - -1. Let `H[0] = D+N` where D is the underlying data and N is the nonce. -2. For `i` from `1` to `N` let `H[i] = f(H[0] ... H[i-1])` where f is some hash-like function that takes multiple inputs. -3. For `i` from `1` to `M` let `R[i] = random([1 ... M])` -4. `SCRYPT(D,N) = f(H[R[0]] ... H[R[M]]`. If `SCRYPT(D,N)` is low enough, then `N` is a valid nonce. - -The idea is that there is no way to practically compute `SCRYPT(D)` without building the entire `H` array and keeping it in memory for the last step. However, Scrypt-like algorithms have a property that inherently limits just how memory-hard they can be: verification requires computing one round of the entire function, so the function is as memory-hard to verify as it is memory-hard to compute. Thus, while scrypt may be viable for achieving memory hardness around a few megabytes per thread, it is a non-starter for memory hardness in the area of hundreds of megabytes per thread. In fact, hundreds of megabytes per thread is arguably necessary; there are already companies [http://www.cryptocoinsnews.com/2013/11/22/alpha-technologies-offer-scrypt-mining-asics/ working on ASICs for scrypt] today. - -### Primecoin - -Primecoin's algorithm is not designed to be memory-hard, but it does have that property to some extent. The algorithm requires miners to find so-called Cunningham chains of prime numbers - chains of the form `[ n+1, 2n+1, 4n+1 ... n*2^k+1 ]` for a sufficiently large `k`. As it turns out, it is very difficult to do this for any significant length without first filling in a data structure known as a sieve. The advantage of Primecoin is that verification is nearly instant and very memory-cheap; all that one needs to do is run the Fermat primality test to make sure that all of the values are prime. However, the Primecoin algorithm has two weaknesses in this regard: - -1. '''Time-memory tradeoff''' - an ASIC has the option of removing much of the memory required by sacrificing some computational efficiency; even with only 100 KB per thread a miner can be fairly efficient. -2. '''All clear effect''' - as it turns out, it is possible for GPUs and ASICs to have multiple threads share the same memory. Since Primecoin mining only requires the sieve to be filled once, an ASIC can calculate a sieve first and then run thousands of threads through it. - -### Birthday attack - -The birthday attack algorithm is ingenious, and works as follows: - -1. Let `H[i] = sha256(D + N + i)` for `i` from 0 to 232 - 1 given data `D` and nonce `N`. -2. If `abs(H[i] - H[j])` is sufficiently low, then `(N,i,j)` is a valid solution triple. - -The ingenuity of the protocol comes from the fact that while efficiently computing the birthday attack requires storing the hashes in a data structure so that every new hash can be checked against all previous ones, verifying the solution only requires checking two hashes. The algorithm is resistant against the all-clear effect because memory must be flushed every 232 rounds. However, there are several shortcuts and time-memory tradeoff attacks. First, one can optimize by storing only the first few bytes of each hash instead of the entire hash. Second, one can only store hashes with the first two bits being 00; this takes 75% of possible solutions out of consideration, reducing time efficiency by 4x, but it also increases space efficiency by 4x. Finally, there is potential for optimization by examining the various options between storing hashes in a large array, a binary or red-black tree, and other more complex structures; the optimal algorithm may be quite complicated. - -Dagger intends to solve all of these issues, having a currency that is memory-hard to computer but memory-easy to verify, has no all clear effect, no time-memory tradeoff even at a 1:1 ratio, and for which a close-to-optimal algorithm is the naive one. - -## Algorithm specification: - -Essentially, the Dagger algorithm works by creating a directed acyclic graph (the technical term for a tree where each node is allowed to have multiple parents) with a total of 223 - 1 nodes in sequence. Each node depends on 3-15 randomly selected nodes before it. If the miner finds a node between index 222 and 223 such that this resulting hash is below 2256 divided by the difficulty parameter, the result is a valid proof of work. - -Let `D` be the underlying data (eg. in Bitcoin's case the block header), `N` be the nonce and `||` be the string concatenation operator (ie. `'foo' || 'bar' == 'foobar'`) . The entire code for the algorithm is as follows: - - - - D(data,xn,0) = sha3(data) - D(data,xn,n) = - with v = sha3(data + xn + n) - L = 2 if n < 2^21 else 11 if n < 2^22 else 3 - a[k] = floor(v/n^k) mod n for 0 <= k < 2 - a[k] = floor(v/n^k) mod 2^22 for 2 <= k < L - sha3(v ++ D(data,xn,a[0]) ++ D(data,xn,a[1]) ++ ... ++ D(data,xn,a[L-1])) - - - -## Properties: -Objective: find `xn`, `n` such that `n > 2^22` and `D(data,xn,n) < 2^256 / diff` - -1. With 228 bytes (256 MB) of memory, the optimal algorithm is to run `D` all the way through from start to finish. -2. One potential problem is lazy evaluation; parts of the tree can be evaluated only as needed in order to reduce the number of hashes required. However, because a (pseudo-) random node out of 225 is taken 228 times, we can statistically estimate that each node has a 1 / e8 change of remaining unused - only about 0.03%. Hence, the benefit from lazy evaluation is insubstantial. -3. It is possible to run the algorithm with much less memory using lazy evaluation. However, empirical tests show that computing one nonce requires 3000 - 25000 hashes. -4. Verification also requires 3000 - 25000 hashes. -5. Because the 2^21 to 2^22 phase requires 11 parents, the time-memory tradeoff attack is severely weakened - attempting to store 2^21 nodes instead of 2^23 reduces memory usage by a factor of 4 but slows down computation by a factor about 20. Thus, no practical time-memory tradeoff attack exists; close to the full 256 MB is required for any reasonable level of efficiency. - -## Conclusion - -This algorithm provides a proof of work mining function with memory hardness properties that are not ideal, but that are nevertheless a massive improvement over anything available previously. It takes 512 MB to evaluate, 112 KB memory and 4078 hashes to verify, and even the tinest time-memory tradeoff is not worthwhile to implement because of the bottom-level branching adjustment. These parameters allow Dagger to be much more daring in its memory requirements than Primecoin or scrypt, asking for 512 MB of RAM for a single thread. Because the primary determinant of hardness is memory, and not computation, specialized hardware has only a tiny advantage; even an optimal Dagger mining ASIC would have little to offer over a hobbyist purchasing hundreds of gigabytes of memory cards off the shelf and plugging them into a medium-power GPU. And even in such an equilibrium, mining with ordinary CPUs will likely continue to be practical. - -## Acknowledgements - -* Thanks to Adam Back and Charles Hoskinson, for discussion and critique of earlier drafts of the protocol -* See also: [Fabien Coelho's paper](http://www.cri.ensmp.fr/classement/doc/A-370-v1.pdf), in which Fabien Coelho had independently discovered a similar algorithm in 2005. \ No newline at end of file diff --git a/Dapp-Developer-Resources.md b/Dapp-Developer-Resources.md deleted file mode 100644 index 531ce5405..000000000 --- a/Dapp-Developer-Resources.md +++ /dev/null @@ -1,17 +0,0 @@ -As a Ðapp developer you have three main resources which allow Ðapp development. - -### Main Resources - -- [Web3 JavaScript API](https://github.com/ethereum/wiki/wiki/JavaScript-API) - This is the main JavaScript SDK to use when you want to interact with a nodes API -- [JSON RPC API](https://github.com/ethereum/wiki/wiki/JSON-RPC) - This is the low level JSON RPC 2.0 interface to interface with a node. This API is used by the [Web3 JavaScript API](https://github.com/ethereum/wiki/wiki/JavaScript-API). -- [Solidity Documentation](https://solidity.readthedocs.io/en/latest/) - Solidity is the Ethereum developed Smart Contract language, which compiles to EVM (Ethereum Virtual Machine) opcodes. - -### Other Resources: - -- [Standardized Contract APIs](https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs) - Standard contract API, which should be used to make some contract types accessible by other Ðapps. (Not yet finalised) -- [Useful Ðapp Patterns](https://github.com/ethereum/wiki/wiki/Useful-Ðapp-Patterns) - Code snippets which are useful for Ðapp development. -- [Dapp using Meteor](https://github.com/ethereum/wiki/wiki/Dapp-using-Meteor) - This short tutorial gives an intro on how to start building a Ðapp using [Meteor](https://www.meteor.com), and also why Meteor is a good fit for Ðapps. - -### Useful read -- [FAQ](https://github.com/ethereum/wiki/wiki/FAQ) - Collection of links, useful for understanding the Ethereum eco system. -- [Glossary](https://github.com/ethereum/wiki/wiki/Glossary) - Great explanation of Blockchain related terms. diff --git a/Dapp-using-Meteor.md b/Dapp-using-Meteor.md deleted file mode 100644 index d198e48c0..000000000 --- a/Dapp-using-Meteor.md +++ /dev/null @@ -1,209 +0,0 @@ ---- -name: DAPP Using Meteor -category: ---- - -This tutorial will show you how to setup a Meteor app to be used as a Ðapp and probably answer a few questions on why Meteor should used. - -1. [Create your Ðapp](#create-your-%C3%90app) -2. [Start your Ðapp](#start-your-%C3%90app) -3. [Connect your Ðapp](#connect-your-%C3%90app) -4. [Run your Ðapp](#run-your-%C3%90app) -5. [Add Ðapp styles](#add-%C3%90app-styles) -6. [Using ethereum:elements](#using-ethereumelements) -7. [Ðapp code structure](#%C3%90app-code-structure) -8. [Bundle your Ðapp](#bundle-your-%C3%90app) - - -## FAQ - -### Isn't Meteor a full stack framework, how does that fit into Ðapp development - -True, Meteor is a full stack framework and its main improvement is realtime web applications, but Meteor is also the first framework (i know of), which fully embraced *s*ingle *p*age *a*pp (SPA) development and provided all necessary tools. - -5 reasons why Meteor is a perfect fit: - -1. Its purely written in JS and has all the tools a SPA needs (Templating engine, Model, on-the-fly compiling, bundling) -2. You get a development environment, which has live reload, CSS injection and support for many pre-compilers (LESS, Coffeescript, etc) out of the box -3. You can get all frontend code as single `index.html` with one `js` and `css` file plus your assets, using [meteor-build-client](https://github.com/frozeman/meteor-build-client). You can then host it everywhere or simple run the `index.html` itself or distribute it later on *swarm*. -4. It embraces full reactivity, which make building consistent interface much easier (similar to angualr.js `$scope` or binding) -5. It has a great model called Minimongo, which gives you a mongoDB like interface for a reactive in-memory database, which can also be [auto-persistet to localstorage](https://atmospherejs.com/frozeman/persistent-minimongo) or [indexedDB](https://atmospherejs.com/frozeman/persistent-minimongo2) - -### Do i need to host my Ðapp on a server? - -No, using [meteor-build-client](https://github.com/frozeman/meteor-build-client) you can get all the static assets of you Ðapp to run without any server, though if you use a router like [iron-](https://atmospherejs.com/iron/router) or [flow-router](https://atmospherejs.com/meteorhacks/flow-router), you need to use hash (`index.html#!/mypath`) routes instead of clean HTML5 pushstate routes. - -*** - -## Create your Ðapp - -Install Meteor if don't have already: - -```bash -$ curl https://install.meteor.com/ | sh -``` - -Then create an app: -```bash -$ meteor create myDapp -$ cd myDapp -``` - -Next add the web3 package: -```bash -$ meteor add ethereum:web3 -``` - -I recommend also to add the following packages: - -- [ethereum:dapp-styles](https://atmospherejs.com/ethereum/dapp-styles) - The LESS/CSS framework which gives your dapp a nice Mist-consistent look. -- [ethereum:tools](https://atmospherejs.com/ethereum/tools) - This package gives you the `EthTools` object with a set of formatting an conversion functions and template helpers for ether. -- [ethereum:elements](https://atmospherejs.com/ethereum/elements) - A set of interface elements specifically made for ethereum, see this [Demo](http://ethereum-elements.meteor.com) for more. -- [ethereum:accounts](https://atmospherejs.com/ethereum/accounts) - Gives you the reactive `EthAccounts` collection with all current available ethereum accounts, where balances will be automatically updated. -- [ethereum:blocks](https://atmospherejs.com/ethereum/blocks) - Gives you the reactive `EthBlocks` collection with the latest 50 blocks. To get the lastest block use `EthBlocks.latest` (It will also have the latest default gasPrice) -- [frozeman:template-var](https://atmospherejs.com/frozeman/template-var) - Gives you the `TemplateVar` object, that allows you to set reactive variables, which are template instance specific. See the [readme](https://atmospherejs.com/frozeman/template-var) for more. -- [frozeman:persistent-minimongo2](https://atmospherejs.com/frozeman/persistent-minimongo2) - Allows you to auto persist your minimongo collection in local storage - - -## Start your Ðapp - -### A short excursion into Meteors folder structure - -Meteor doesn't force you to have a specifc folder structure, though some folders have specifc meaning and will be treated differently when bundling/running your application. - -Folders with specific treatment -- `client` - files in a folder called `client` will only be loaded by the client part of your app and as we are building a Ðapp, thats where most of our files go. -- `lib` - files in folders called `lib` will load before other files in the same folder. This is an ideal place your init files, libraries, or ethereum specifc files. -- `public` - a folder called `public` contains assets meteor will make available on the root of your webserver (or later bundled Ðapp) -- There are a few more specifc folders like `server`, `tests`, `packages`, etc. If you want to get to know them take a look at the [Meteor docs](http://docs.meteor.com/#/full/structuringyourapp) - -So to build a Ðapp we ideally create the following folder structure in our `myDapp` folder: - -``` -- myDapp - - client - - lib - - myDapp.html - - myDapp.js - - myDapp.css - - public -``` - -**Note** The community provides also Meteor Ðapp Boilerplates like this on from Nick Dodson: https://github.com/SilentCicero/meteor-dapp-boilerplate - -### Connect your Ðapp -To connect our dapp we need to start `geth` with the right CORS headers in another terminal: - -```bash -$ geth --rpc --rpccorsdomain "http://localhost:3000" -``` - -We also need to set the provider. Ideally we create a file in our lib folder called `init.js` and add the following line: - -```js -// set providor -if(!web3.currentProvider) // make sure we don't overwrite a provider set by Mist later on - web3.setProvider(new web3.providers.HttpProvider("http://localhost:8545")); -``` - -### Run your Ðapp - -Now we can run our Ðapp by simply running: - -```bash -$ meteor -``` - -If we go to `http://localhost:3000`, we should see a website appear and if we open the browser console we can use the web3 object to query the geth node: - -```js -> web3.eth.accounts -['0xfff2b43a7433ddf50bb82227ed519cd6b142d382'] -``` - -## Add Ðapp styles - -If you want your Ðapp to nicely fit later into Mist and have follow the official look use the [dapp-styles css css/less framework](https://atmospherejs.com/ethereum/dapp-styles). - -*Note that they are under heavy development and the class names and elements may change.* - -To add it simple add the following packages to your Ðapp: - -```bash -$ meteor add less -$ meteor add ethereum:dapp-styles -``` - -Now rename you `myDapp.css` to `myDapp.less` and add the following line inside: - -```css -// libs -@import '{ethereum:dapp-styles}/dapp-styles.less'; -``` - -Now you can use all dapp-styles classes and also overwrite all variables of the framework. You can find them [in the repo](https://github.com/ethereum/dapp-styles/blob/master/constants.import.less). Overwrite them by copying them to your `myDapp.less` file and set different values. - -## Using ethereum packages - -To make your live as a Ðapp developer easier we provide some packages that help you build Ðapps faster. - -If you add the recommended packages above you should have the [ethereum:tools](https://atmospherejs.com/ethereum/tools), [accounts](https://atmospherejs.com/ethereum/accounts) and [ethereum:blocks](https://atmospherejs.com/ethereum/blocks) packages available. - -These 3 packages give you the `EthTools`, `EthAccounts` and `Ethblocks` objects, which give you formatter functions, a collection with the accounts from `web3.eth.accounts` (with auto updated balance) and a collection of the last 50 blocks. - -Most of these functions are reactive so they should make building interfaces a breeze. - -### Example usage - -If you look into you `myDapp.html` you will find the `hello` template. -Just add a helper called `{{currentBlock}}` some where between the `` tags. - -Now open the `myDapp.js` and add after the `counter: function..` the `currentBlock` helper: -```js -Template.elements.helpers({ - counter: function () { - ... - }, - currentBlock: function(){ - return EthBlocks.latest.number; - } - }); -``` - -Then initialize EthBlocks by adding `EthBlocks.init();` after `Session.setDefault('counter', 0);` - -If you now check your Ðapp in the browser you should see the latest block number, which will increase once you mine. - - -*For more examples please checkout the packages readmes and the [demo](http://ethereum-elements.meteor.com) ([source](https://github.com/frozeman/meteor-ethereum-elements-demo)) for more.* - -## Ðapp code structure - -*This tutorial won't go into building apps with Meteor. For this please refer to the [Meteor's tutorials](https://www.meteor.com/tutorials/blaze/creating-an-app), [A list of good resources](https://www.meteor.com/tools/resources), [EventMinded](https://www.eventedmind.com) (payed tutorials) or books like [Building Single-page Web Apps with Meteor](https://www.packtpub.com/web-development/building-single-page-web-apps-meteor) or [Discover Meteor](http://discovermeteor.com).* - - -TODO -Short: -- put ethereum related stuff into `client/lib/ethereum/somefile.js` -- use `myCollection.observe({added: func, changed: func, removed: func})` to communicate to ethereum, keep ethereum logic out of your app as much as possible. This way you just write and read from your reactive collections and the observe functions will handle the rest (e.g. sendTransactions) -- Filters etc will add logs etc to your collections. So you keep all the callback mess out of your app logic. - -For an example see the [Ethereum-Wallet](https://github.com/ethereum/meteor-dapp-wallet). - -## Bundle your Ðapp - -To bundle your Ðapp into a local standalone file use [meteor-build-client](https://github.com/frozeman/meteor-build-client): - -```bash -$ npm install -g meteor-build-client -$ cd myDapp -$ meteor-build-client ../build --path "" -``` - -This will put your Ðapps static files into the build folder, above your `myDapp` folder. - -The last option `--path` will make the linking of all files relative, allowing you to start the app by simply clicking the `build/index.html`. - -Be aware that when running your app on the `file://` protocol, you won't be able to use client side routing, due to web security. Later in mist you will be able to use client side routing, as dapps are severed over the `eth://` protocol. - -In the future you will be able to simply upload your Ðapp on swarm. \ No newline at end of file diff --git a/Decentralized-apps-(dapps).md b/Decentralized-apps-(dapps).md deleted file mode 100644 index 1dbed731b..000000000 --- a/Decentralized-apps-(dapps).md +++ /dev/null @@ -1,83 +0,0 @@ -Any good, service, governance or economic activity can be decentralized and tokenized with and transacted via Ethereum. The token represents the dapp (an abbreviation for decentralized app) while it uses the Ethereum blockchain, but the price of the token is different. Activity that has any economic or governance aspect, conceived or as of yet inconceived, can be done via Ethereum, provided that the right code is written and the necessary hardware is used (such as computers running an Ethereum node, and in some special cases, a measurement device to measure a resource flow for additional verification/auditable purposes, like a meter for electricity ⚡🔌, water 🚰 or gas 🔥; or a waste 🗑️ volume detector). Here's a challenge: keep an eye out for activity that has not been implemented on Ethereum (or could be implemented in a better way; check this article and research to check whether it's implementeId and if so, how well) and then: -
    -
  • develop a dapp for the idea yourself (after learning Solidity, if you don't already know it); or
  • -
  • sign an NDA with someone who is interested in developing dapps, share the idea, and form some agreement if they want to proceed with it (which could be proposed in the NDA itself), e.g. a founder's stake in an ICO, a salary, equity in the venture (although a community model more like Ethereum's non-profit foundation is better for a more equitable solution), royalties, a fee for every transaction, etc.
  • -
- -This platform aspect of Ethereum has been referred to as a 'fat protocol' here, as opposed to the 'thin protocols' of Web 1.0 and 2.0 with HTTP, SMTP, etc., with the take home point (in bold) being: -
the market cap of the protocol always grows faster than the combined value of the applications built on top, since the success of the application layer drives further speculation at the protocol layer.
-One kind of application that is particularly intriguing is decentralized autononous organisations (DAOs, this includes entities as large as, or even larger than nation-states 🇦🇺🇺🇸🇮🇳🇬🇧🇨🇳🇧🇷🇷🇺🇯🇵, social networks, multinational public companies, etc.). Note that having complete autonomy is probably not a good idea, since code may not be able to handle new issues that arise, so human intervention should probably always be an option, but preferably in the hands of a small, non-profit entity or some decentralized solution (perhaps similar to the Aragon Network). By analogy, you wouldn't want a nuclear power plant to be completely automated with no possible means of human intervention. As a precaution, you'd want several safeguards including, for example, an off button 😉. As explained in this Ethereum Wiki here, the first DAO, known as The DAO, resulted in many funds being stolen, and Ethereum hard forking into Ethereum and Ethereum Classic. - -The following list is sourced from [Coin Market Cap tokens (you can sort by market cap)](https://coinmarketcap.com/tokens/) and State of the Dapps, both of which lists many more, as well as elsewhere, e.g. Gitter research room chats. (There are 854 dapps on State of the Dapps as of Dec 1 2017; then [909 on Jan 1 2018] (https://web.archive.org/web/20180101114436/https://www.stateofthedapps.com/). 😯 You can search by tags.) Other examples are also presented e.g. on day 4 of [Devcon 3](http://www.ryanyosua.me/devcon-3-talks/), as well as outlined in the Ethereum whitepaper in the introduction and applications section. Note also that while most of the dapps in the following list run on the Ethereum platform, some examples do not, and where they don't run on Ethereum, it is generally noted as what they do run on. This is not a big deal, as any dapp could theoretically run on another blockchain, (or indirectly via inter-blockchains like Cosmos or Polkadot) provided that the host blockchain has the required features. Also note that the below list is not an endorsement, and is not exhaustive or necessarily well-maintained. At worst, it's included because it was briefly looked into and it seemed like a good idea, while more time may have been spent doing due diligence on some ideas and can therefore have a better idea of its usefulness. Dapps that have been implemented, or are under development, or have been publicly conceptualised, includes: -* a stable coin, e.g. [Dai](https://makerdao.com/whitepaper/DaiDec17WP.pdf) -* smart contracts for the legally enforceable and/or liquid transfer of assets, plus related services e.g. [Mattereum](https://mattereum.com/) and [Sweetbridge](https://sweetbridge.com), e.g. settlement, accounting, risk management, resource sharing, and Optimization & Liquid Talent. Also, asset-based lending: secure loans with holding of assets e.g cryptocurrenices (locking them up) in exchange for cash (fiat currencies), such as Sweetbridge and [SALT](https://coinmarketcap.com/currencies/salt/); -* [Veritaseum](http://veritas.veritaseum.com/), which "enables software-driven P2P capital markets without brokerages, banks and traditional exchanges". -* [invoice financing with Populous](https://populous.co/) -* decentralized exchanges to buy and sell cryptos and fiat, e.g. localethereum; for cryptos only there is DecentrexOmega One and NVO, where the latter two have not been launched as of November 30. -* non-decentralized exchanges such as [Coinbase](https://www.coinbase.com/) (US), [BTCmarkets](https://btcmarkets.net/) (Australia), while more are below, or ones that only exchange cryptocurrencies like Poloniex; -* other exchanges like [OmiseGo](https://omisego.network/). "OmiseGO is a public Ethereum-based financial technology for use in mainstream digital wallets, that enables real-time, peer-to-peer value exchange and payment services agnostically across jurisdictions and organizational silos, and across both fiat money and decentralized currencies. Designed to enable financial inclusion and disrupt existing institutions, access will be made available to everyone via the OmiseGO network and digital wallet framework."; -* exchange platforms like [Binance](https://www.binance.com/aboutUs.html); -* asset exchanges like [WAX](https://wax.io/). -* the Brave browser (which the author uses) which uses the Basic Attention Token, which provides a better solution for users, publishers and advertisers; -* [MaidSafe](https://maidsafe.net/), which has another browser that actually runs on the [Omni](http://www.omnilayer.org/) layer that runs on Bitcoin, not Ethereum. It is also claiming to be: "The World's First Autonomous Data Network". [Currently you have to receive an invite which requires roughly an hour of interaction on their Discourse forum/site.](https://web.archive.org/web/20171230003420/https://invite.maidsafe.net/) -* [ZeroNet](https://zeronet.io/), another decentralized internet network that runs on Bitcoin cryptography and the [BitTorrent network](http://www.bittorrent.com/). [It on Ubuntu 17.10](http://127.0.0.1:43110/Talk.ZeroNetwork.bit/?Topic:1514631579_13fVMZu2wTNAykEvkYHYfGmTBMSFxz9gFG/It+would+be+good+if+you+could+link+to+a+comment). You can make [your own site](http://127.0.0.1:43110/1zz1z8YPFQizJshGkgHq7GVtBSPCyQM5W/), although [you may have issues with following a tutorial](http://127.0.0.1:43110/Blog.ZeroNetwork.bit/?Post:99:ZeroChat+tutorial#comment_1_13fVMZu2wTNAykEvkYHYfGmTBMSFxz9gFG). Note that this link won't work unless you are running ZeroNet.sh) by clicking the download button on the homepage (then as detailed concisely below the button) extracting it and running (in bash) `./ZeroNet.sh` while `cd`ed to the extracted folder that ZeroNet.sh is located in. -* storage, e.g. Swarm and a distributed hypermedia protocol, IPFS [website](https://ipfs.io/), [doc](https://github.com/ipfs/ipfs); -* communication protocols, e.g. Whisper (also see here for code), which allows dapps (you don't need to capitalize this since it is an abbreviation of decentralized applications) to communicate with each other; -* multi-chain networks/tools like [Polkadot](https://polkadot.io/) and [BTCRelay](http://btcrelay.org/) -* Ethereum Name Service (names like jamesray.eth map to an address); -* mesh networking e.g. implemented here and as voted for here on Twitter (which also has other ideas posted in the comments); -* social networks e.g. Akasha (news here), -* Status: "A Mobile Ethereum OS: Browse, chat and make payments securely on the decentralized web."; -* decentralized search engines, e.g. Weipoint (a news post is here); -* reputation and ratings network e.g. as used by [Etheal](https://etheal.com/), which is described below (CTRL+F); -* identity (e.g. as provided by uPort, as well as [in-blockchain proposal](https://www.ethnews.com/erc725-a-self-sovereign-identity-standard-for-ethereum and [Shyft](https://www.shyft.network/)); -* decentralized electricity trading and other decentralized energy economic applications, which would allow renewable energy to be more economical and accelerate the transition to a clean, renewable energy and safe climate future. - -Sun on Twitter Twemoji 2.3Wind Face on Twitter Twemoji 2.3Deciduous Tree on Twitter Twemoji 2.3Water Wave on Twitter Twemoji 2.3 - -Examples of local electricity trading include: Grid+, LO3/Transactive Grid, Power Ledger, Nexergy, Local Volts and Divvi. Grid+ uses Ethereum and they have open source code. Power Ledger has closed source code and runs on the Ethereum Enterprise Alliance, rather than the public Ethereum blockchain. They had a token sale in early October. Both Power Ledger and Grid+ also detail more unique applications in their pipeline, such as renewable energy asset generation (Power Ledger) and Grid+'s in-home computer, an "intelligent agent" that pays for a customers electricity in real-time, using stable tokens, stores cryptocurrency like the hardware wallet functions of Ledger and Trezor; providing Casper proof-of-stake signing, and provide an Ethereum API for IoT ([pp. 26 and 34-36, white paper](https://drive.google.com/file/d/0Bz90riPGRHquNDVXVE81RmppaUk/view)). Transactive Grid uses Ethereum and it has been rolled out in Brooklyn with a microgrid, however LO3 hasn't released any code or details for its Transactive Grid application. The others are still all under development (as of August 2017), and they have been scant on the details of how they would implement their application, at the least not releasing their code. Divvi say on its website that they will use the blockchain. Local Volts and Nexergy do not. -* electricity tokenization: e.g. SolarCoin, EnergyCoin, although both are altcoins rather than Ethereum tokens; -* governance of any organisation, e.g. Democracy.Earth; and also governance of DAOs, e.g. Aragon; -* decentralized search engines like [BitClave](https://www.bitclave.com/en/), [Weipoint](https://www.weipoint.com/) and [Epocum](https://www.stateofthedapps.com/dapps/epocum); -* wallets like MyEtherWallet or hardware wallets Trezor or Ledger; -* blockchain explorers like [Etherscan](https://etherscan.io/); -* a gateway to decentralized services such as [Infura](https://infura.io/); -* visit dapps in your browser with [Metamask](https://metamask.io/); -* decentralized media; -* asset titles (such as land titles). Read more on that here: "Having so far built the software and tested it with a couple dozen land title registrations, Bitfury and the Georgian National Agency of Public Registry have now signed a new memorandum of understanding to expand the service to purchases and sales of land titles, registration of new land titles, demolition of property, mortgages and rentals, as well as notary services". Nottar.io also provides notary services. A similar, more specific application is for academic certificates with [Smart Diploma](https://www.stateofthedapps.com/dapps/smart-diploma); -* Debit card 💳 transactions 🤝 (done on several exchanges 💱, e.g. Coinjar Swipe (but it accepts BTC only), Coinbase, while others which I've mentioned elsewhere in this article have plans to do this e.g. [OmiseGO](https://www.omise.co/go); -* co-ownership of real assets e.g. the [Swarm Fund](https://www.swarm.fund/how-swarm-works/index.html) -* crowdsales, e.g. an Initial Coin Offering (ICO) as compared with an Intial Public Offering (IPO), or for tokens with Ethereum: an Initial Token Offering (ITO). Note that this is not so much a business model in itself, per se, rather it is more of a fundraising method (which has also led to scams, e.g. here); -* crowd development (but not as part of the blockchain, e.g. here), e.g. for infrastructure and other public assets; -* think of public companies being remodelled into communities with tokens instead of shares, governance using a platform like Democracy.Earth (which can be tailored to have voting anywhere between one vote one person like direct democracy, or conventionally more hierarchical like a board of directors and token-holders instead of or in addition to—and probably eventually superceding—shareholders); -* dividend payouts and secure email-based transactions with [Dividend](https://www.dividend.cloud/). For sending ETH via email there is also [You've Got ETH](https://www.stateofthedapps.com/dapps/you-ve-got-eth); -* prediction 🔮 🦉 markets like GNOSIS, Augur and [WINGS DAO](https://www.stateofthedapps.com/dapps/wings-dao); -* [Built-in price discovery and a liquidity mechanism for tokens with Bancor](https://www.bancor.network/); -* labour/recruitment/freelance markets like Chronobank and [Ethlance](https://ethlance.com/); -* permissioned distributed ledgers like [Hydrachain](http://www.brainbot.com/projects#hydrachain); -* trust-based models like the [Trustlines Network](http://trustlines.network/) -* Secure distributed computing, e.g. Golem. Ethereum needs to be faster e.g. with EWASM and parallelizability. -* accountability, e.g. for non-profits (e.g. "how do I know how badly you need a donation unless I can see your net liabilities, net assets, and balance sheet, and how you plan to use the funds?") and aid (also see here) -* Self Learning, Autonomous, Decentralized Artificial Intelligence (this could be used for many things such as self-driving cars, robots, or anything else that is owned by a contract; bots; and art); -* decentralised financial services like [WeTrust](https://www.wetrust.io); -* futures-like dapps such as [TimeBank](https://www.stateofthedapps.com/dapps/timebank) and [hodlethereum](https://hodlethereum.com/); -* sharing car refueling stations with [Share&Charge](https://www.stateofthedapps.com/dapps/share-charge); -* health, e.g. [Etheal](https://etheal.com/), a healthcare service comparison site with a content platform, trust and review / reputation system; an anonymous marketing platform for surveys, ads and communication research where users are paid by pharmaceutical companies; and a platform for building health apps; -* examples of contracts are [here](https://solidity.readthedocs.io/en/develop/solidity-by-example.html) and [here](https://viper.readthedocs.io/en/latest/viper-by-example.html), e.g. voting, auctions (open or blind), safe remote purchases, micropayment channels, crowdfunding and company stock. Many more can be found on Github, which may be referenced from the whitepaper and the website of a dapp. -* [insurance](https://www.stateofthedapps.com/tagged/insurance/); - - -Examples that have been conceptualized, but not implemented (at least as far as the creator of this wiki is aware of) include: -* reducing transaction costs for existing business models (here is a good read about that). However, to tokenize online centric business models, the network model should change from client-server to peer-to-peer, to avoid a conflict of interest. This is more difficult to achieve since a server is a piece of infrastructure, and transferring to a peer-to-peer model would cause it to be a sunk cost. Additionally, it may be difficult to build a replacement dapp for a successful website, because it is hard to get a network of engaged users to change to using something else (inertia). Centralized web apps (not just mobile apps but websites, and use the word to contrast with dapps) include: -* * Google (although note [Weipoint](https://www.weipoint.com/) as mentioned previously), -* * social networks like [Facebook](http://www.trustnodes.com/2018/01/04/zuckerberg-studying-cryptocurrency-implementation-facebook), Twitter, (although note [Akasha](https://akasha.world/) above); -* * online marketplaces e.g. Amazon, eBay and Alibaba (decentralized alternatives include [Soma for products or services](https://soma.co/), [Canya for services](https://canya.io/) also note this simple implementation and subreddit [here](https://www.reddit.com/r/ethmarket/), as well as more specific or niche marketplaces like [Cryptokitties](https://www.cryptokitties.co/), [Hamster](https://hmstr.io/)). For more info see [here](https://www.forbes.com/sites/rogeraitken/2017/10/24/whats-the-future-of-online-marketplaces-blockchains-technology-impact/#3f6bde2a63a0) -* making economically viable other business models that have seen low uptake or aren't economically viable without blockchain tech. So-called sharing economy business models (which are more aptly called tasker or rentier capitalism models) like Airbnb, Uber, AirTasker, Fiverr, Upwork, TaskRabbit, and Menulog are particularly ripe for transformation (the term transformation is preferrable to disruption, since it should be a net positive change, while negative effects are manageable or solvable), since no trusted third party for a transaction is needed, such as banks 🏦, credit card 💳 companies or PayPal, just a smart contract; and -* mortgage brokers; -* More examples are here—scroll to the examples—they have bold headings and are about two thirds of the way down, or search for "Dank meme trading". Note that the Basic Attention Token has already been mentioned, and the creator of this wiki is skeptical that AI will create truly beautiful art, since no AI can have any feeling. CryptoKitties is an example of meme trading and has taken up [a lot of the transactions on the Ethereum network](https://etherscan.io/address/0x06012c8cf97bead5deae237070f9587f8e7a266d). -* curation markets, which is part of what [Steemit](https://steemit.com/@jamesray/feed) does (which runs on the STEEM network), and which curators, social networks and wiki authors would all benefit from. More info is [here](https://medium.com/@simondlr/introducing-curation-markets-trade-popularity-of-memes-information-with-code-70bf6fed9881); -* [P2P Decentralised Autonomous Transportation Network](http://www.flyingcarpet.network/) -* [Waste collection management](https://twitter.com/JamesCRay01/status/936992945173020672). Other ideas include plus generally thinking of existing business models running on the blockchain, like real estate developers and investment trusts (with which blockchains could be used e.g. for crowdfunding). -* legally enforceable wills running on the blockchain, as well as being able to appoint an executor in a legally enforceable way on the blockchain. - -More examples are e.g. [here in a blog post](https://medium.com/@Ethereum_AI/ethereum-introduction-what-exactly-is-it-why-care-how-to-invest-9a627ab04408) and [here on Wikipedia](https://github.com/Ethereum-community/Ethereum-introduction/wiki/Decentralised-apps-(dapps)) diff --git a/Default-Extra-Data-Standard.md b/Default-Extra-Data-Standard.md deleted file mode 100644 index 145868ce0..000000000 --- a/Default-Extra-Data-Standard.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -name: Extra Data -category: ---- - -Implementations are encouraged to follow this protocol for populating the `extraData` field of mined blocks. - -`extraData` should be an RLP list whose first element is a version identifier encoded as a canonical RLP positive integer. All other items in the list are determined by the version ID. - -`[` version: `P`, ... `]` - -### Version 0 - -`[` version: `P`, clientIdentity: `B` `]` - -One further argument, a raw representation of a string to identify the client (this would usually be a shortened form of the client identifier as returned by the JSON RPC's `web3_clientVersion`). diff --git a/Deterministic_Wallet_Spec.md b/Deterministic_Wallet_Spec.md deleted file mode 100644 index b8da58be5..000000000 --- a/Deterministic_Wallet_Spec.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -name: Deterministic Wallet Spec -category: ---- - -Address/key generation - -The following is a proposed deterministic wallet specification. - -Let `S` be the secret. We define `key(i) = sha3(S + zpad(int_to_big_endian(i), 32))`, where `i` is an incrementing index starting at 0 - -Assuming `S = "123dog"`, we thus have: - - key(0) = sha3("123dog\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") - -Note that the big endian representation of 0 is the empty string. - - key(1) = sha3("123dog\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01") - key(2) = sha3("123dog\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02") - key(255) = sha3("123dog\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff") - key(256) = sha3("123dog\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00") - key(4294967297) = sha3("123dog\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01") \ No newline at end of file diff --git a/Distributed-Preimage-Archive.md b/Distributed-Preimage-Archive.md deleted file mode 100644 index a9bb673d2..000000000 --- a/Distributed-Preimage-Archive.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -name: Distributed Preimage Archive -category: ---- - -# Purpose - -DPA stores small pieces of information (preimage objects, arbitrary strings of bytes of limited length) retrievable by their (cryptographic) hash value. Thus, preimage objects stored in DPA have implicit integrity protection. The hash function used for key assignment is assumed to be collision-free, meaning that colliding keys for different preimage objects are assumed to be practically impossible. - -DPA serves as a fast, redundant store optimized for speedy retrieval and long-term reliability. Its most frequent use within Ethereum is to cache objects that can be retrieved and/or re-constructed by other means at significant cost. Since the key is derived from the preimage, there is no sense in which we can talk about multiple or alternative values for keys, the store is immutable. - -# High-level design - -DPA is organized as a DHT (Distributed Hash Table): each participating node has an address (resolved into a network address by the p2p layer) coming from the same value set as the range of the hash function. In particular it is the hash of the public key (NodeID field of the DEVP2P handshake). - -There is a distance measure defined over this value set that is a proper metric satisfying the triangle inequality. It is always possible to tell how far another node or another preimage object is from a given address or hash value. The distance from self is zero. - -Each node is interested in being able to find preimages to hash values as fast as possible and therefore stores as many preimages as it can itself. Whenever it must decide which preimage object to store and which to discard, preference is given to objects with an address that is closer. In practical terms, it is always the farthest preimage object that is discarded when a node runs short of storage capacity. Thus, each node ends up storing preimage objects within a given radius limited by available storage capacity. The cryptographic hash function takes care of randomization and fair load balancing. - -Nodes provide the following services through a public network API: - -1. Inserting new preimages into DPA -1. Retrieving preimages from their own storage, if they have it. -1. Sharing routing information to a given node address - -Locally, in addition to the above, nodes also provide the service of storing and retrieving large chunks of data. When storing, the data is disassembled into a tree of blocks according to a scheme resulting in the key corresponding to the root block. Given the key of the root block the data can then can be reassembled with the help of recursively retrieving the blocks in the tree. - -## Queries - -### Insert - -When receiving a preimage that is not already present in its local storage, the node stores it locally. If the storage allocated by the node for the archive is full, the object accessed the longest time ago is discarded. Note that this policy implicitly results in storing the objects closer to the node's address, as - all else being equal - those are the ones which are most likely to get queried from this particular node, due to the lookup strategy detailed below. - -After storing the preimage, the insert request is also forwarded to all the nodes in the corresponding row of the routing table. Note that the kademlia routing makes sure that the row in the close proximity of a node actually contains nodes further out than self thereby taking care of storage redundancy. -However, in order to mitigate against node drop out preimages, especially those with hashes in the node's proximity, need to be re-broadcast, albeit with a very low frequency. - -When a node received a store request, it remembers it for a while and does not forward the same request. This is needed to avoid redundant network traffic. - -### Retrieve - -Retrieval requests have the following parameters: - -1. The hash of the queried pre-image -1. Timeout value for routed retrieval, zero if routing is not required - -If the node has the pre-image, it is returned, called a delivery. Otherwise, the following happens: - -1. The entire row in the Kademlia table corresponding to the queried hash is returned. -1. If routing is deemed not worth the effort (timeout is too short), this fact is also communicated. -1. Otherwise, the same query is recursively done and if it succeeds within the specified timeout, the result is sent to the querying node. - -Successfully found pre-images are automatically re-inserted into DPA. - -A default time estimate for retrieval is calculated in proportion to the expected hop-distance from the node closest to the queried preimage. If this time is outside of the timeout parameter in the request, the request is not routed. - -Each node in the row corresponding to the queried preimage is sequentially queried in order of increasing distance from the target hash. The query is forwarded with a timeout value set to the maximum of the above estimate and the total timeout divided by the number of nodes in the row. If the preimage is found or the time elapsed is in excess of the received timeout value, processing of the query is aborted with timeout. - -From the set up of the first forward onwards, all retrieval requests of the same target are remembered in a request pool. If the data results in successful retrieval and the preimage is stored, the requests are answered by returning the preimage object to each requesting node whether forwarding or originator. The pool of requesting nodes then can be forgotten, since all further queries can be responded with the object delivery. - -## BZZ protocol spec - -**Handshake** - -`[0x01, protocolVersion: B_32, strategy: B_32, capacity: B_64, peers: B_8]` - -**Storing** - -`[+0x02, key: B_256, metadata: [], data: B_4k]`: the data chunk to be stored, preceded by its key. - -**Retrieving** - -`[0x03, key: B_256, timeout: B_64, metadata: []]`: key of the data chunk to be retrieved, timeout in milliseconds. Note that zero timeout retrievals serve also as messages to retrieve peers. - -**Peers** - -`[0x04, key: B_256, timeout: B_64, peers: [[peer], [peer], .... ]]` the encoding of a peer is identical to that in the devp2p base protocol peers messages: `[IP, Port, NodeID]` note that a node's DPA address is not the NodeID but the hash of the NodeID. Timeout serves to indicate whether the responder is forwarding the query within the timeout or not. - -**Delivery** - -`[0x05, key: B_256, metadata: [], data: B_4k]`: the delivery response to retrieval queries. - -## Routing - -It is based on Kademlia's routing. [details](https://github.com/ethereum/wiki/wiki/Cademlia-Peer-Selection) - -_to be continued..._ \ No newline at end of file diff --git a/EVM-JIT-Binary-Interface.md b/EVM-JIT-Binary-Interface.md deleted file mode 100644 index 3e2d2a85e..000000000 --- a/EVM-JIT-Binary-Interface.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -name: EVM JIT Binary Interface -category: ---- - -# JIT C Interface - -``` C -#include - -// JIT object opaque type -typedef struct evm_jit evm_jit; - -// Contract execution return code -typedef int evm_jit_return_code; - -// Host-endian 256-bit integer type -typedef struct i256 i256; - -// Big-endian right aligned 256-bit hash -typedef struct h256 h256; - -// Runtime data struct - must be provided by external language (Go, C++, Python) -typedef struct evm_jit_rt evm_jit_rt; - -// Runtime callback functions - implementations must be provided by external language (Go, C++, Python) -void evm_jit_rt_sload(evm_jit_rt* _rt, i256* _index, i256* _ret); -void evm_jit_rt_sstore(evm_jit_rt* _rt, i256* _index, i256* _value); -void evm_jit_rt_balance(evm_jit_rt* _rt, h256* _address, i256* _ret); -// And so on... - -evm_jit* evm_jit_create(evm_jit_rt* _runtime_data); - -evm_jit_return_code evm_jit_execute(evm_jit* _jit); - -void evm_jit_get_return_data(evm_jit* _jit, char* _return_data_offset, size_t* _return_data_size); - -void evm_jit_destroy(evm_jit* _jit); -``` - -# Return Code - -Informs user about contract exit status: - -Code| Exit Status -----|----- -0 | Stop -1 | Return -2 | Suicide -101 | Bad Jump Destination -102 | Out Of Gas -103 | Stack Underflow -104 | Bad Instruction - - - -# JIT Runtime Data - -A set of data possibly needed by running contract, sometimes by the compiler itself. -Can be called ExtVM data in C++, VMEnv data in Go. - -Name | Type | Access | Description ------ |------|--------|------------ -Gas | i256 | inout | Gas counter. -Address | h256 | in | Account address. -Caller | h256 | in | -Origin | h256 | in | -CallValue | i256 | in | -CallDataSize | i256 | in | -GasPrice | i256 | in | -PrevHash | i256 | in | -CoinBase | h256 | in | -TimeStamp | i256 | in | -Number | i256 | in | -Difficulty | i256 | in | -GasLimit | i256 | in | -CodeSize | i256 | const | -CallData | byte*| in | -Code | byte*| const | diff --git a/Ethash-C-API.md b/Ethash-C-API.md deleted file mode 100644 index cb6bb248a..000000000 --- a/Ethash-C-API.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -name: Ethash C API -category: ---- - -This is just a documentation of the request of the C API described in [this PR](https://github.com/ethereum/ethash/pull/11). - -```c -typedef int(*Callback)(unsigned); -typedef /*...*/ ethash_light_t; -typedef /*...*/ ethash_full_t; -typedef struct ethash_h256 { uint8_t b[32]; } ethash_h256_t; -typedef struct ethash_result { ethash_h256_t value; ethash_h256_t hixhash; } ethash_result_t; - -ethash_light_t ethash_light_new(unsigned number); -ethash_result_t ethash_light_compute(ethash_light_t light, ethash_h256_t header_hash, uint64_t nonce); -void ethash_light_delete(ethash_light_t light); - -ethash_full_t ethash_full_new(ethash_light_t light, CallBack c); -uint64_t ethash_full_dag_size(ethash_full_t full); -void const* ethash_full_dag(ethash_full_t full); -ethash_result_t ethash_full_compute(ethash_full_t full, ethash_h256_t header_hash, uint64_t nonce); -void ethash_full_delete(ethash_full_t full); -``` - -non-zero return from Callback means "cancel DAG creation" - this should cause an immediate return of `ethash_full_new` with 0. - -an object of type `ethash_full_t` may be tested for validity with != 0 - -### Example usage: -```c -int callback(unsigned _progress) -{ - printf("\rGenerating DAG. %d%% done...", _progress); - return 0; -} -void main() -{ - ethash_light_t light; - ethash_h256_t seed; - // TODO: populate p, seed, light - ethash_full_t dag = ethash_full_new(light, seed, &callback); - if (!dag) - { - printf("Failed generating DAG :-(\n"); - exit(-1); - } - printf("DAG Generated OK!\n"); - - ethash_h256_t headerHash; - // TODO: populate headerHash - uint64_t nonce = time(0); - ethash_result ret; - for (; !isWinner(ret); nonce++) - ret = ethash_full_compute(dag, headerHash, nonce); - printf("Got winner! nonce is %d\n", nonce); - ethash_full_delete(dag); -} -``` \ No newline at end of file diff --git a/Ethash-DAG-Disk-Storage-Format.md b/Ethash-DAG-Disk-Storage-Format.md deleted file mode 100644 index 15493aafc..000000000 --- a/Ethash-DAG-Disk-Storage-Format.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -name: Ethash DAG -category: ---- - -Ethash is the PoW system. It requires a great huge dataset known as the DAG (name refers to [Dagger Hashimoto](https://github.com/ethereum/wiki/wiki/Dagger-Hashimoto)). This takes a good long while to generate which is a pain. As such we tend to memoise it. Clients wishing to store the DAG in a cache should conform to this spec in order to share the cache with other clients: - -#### Location - -The DAG should be stored in a 1GB dump (for the initial epoch, anyway), in a file: - -- Mac/Linux: `$(HOME)/.ethash/full-R-` -- Windows: `$(HOME)/Appdata/Local/Ethash/full-R-` - -Where: - -- `` is a decimal integer, given as the C-constant `REVISION` in `libethash/ethash.h`; -- `` is 16 lowercase hex digits specifying the first 8 bytes of the epoch's seed hash. - -There may be many such DAGs stored in this directory; it is up to the client and/or user to remove out of date ones. - -#### Format - -Each file should begin with an 8-byte magic number, `0xfee1deadbaddcafe`, written in little-endian format (i.e., bytes `fe ca dd ba ad de e1 fe`). - -The Ethash algorithm expects the DAG as a two-dimensional array of uint32s (4-byte unsigned ints), with dimension (n × 16) where n is a large number. (n starts at 16777186 and grows from there.) Following the magic number, the rows of the DAG should be written sequentially into the file, with no delimiter between rows and each unint32 encoded in little-endian format. \ No newline at end of file diff --git a/Ethash-Design-Rationale.md b/Ethash-Design-Rationale.md deleted file mode 100644 index 191b1f1b7..000000000 --- a/Ethash-Design-Rationale.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -name: Ethash Design Rationale -category: ---- - -Ethash is intended to satisfy the following goals: - -1. **IO saturation**: The algorithm should consume nearly the entire available memory access bandwidth (this is a strategy toward achieving ASIC resistance, the argument being that commodity RAM, especially in GPUs, is much closer to the theoretical optimum than commodity computing capacity) -2. **GPU friendliness**: We try to make it as easy as possible to mine with GPUs. Targeting CPUs is almost certainly impossible, as potential specialization gains are too great, and there do exist criticisms of CPU-friendly algorithms that they are vulnerable to botnets, so we target GPUs as a compromise. -3. **Light client verifiability**: a light client should be able to verify a round of mining in under 0.01 seconds on a desktop in C, and under 0.1 seconds in Python or Javascript, with at most 1 MB of memory (but exponentially increasing) -4. **Light client slowdown**: the process of running the algorithm with a light client should be much slower than the process with a full client, to the point that the light client algorithm is not an economically viable route toward making a mining implementation, including via specialized hardware. -5. **Light client fast startup**: a light client should be able to become fully operational and able to verify blocks within 40 seconds in Javascript. - -### FNV - -FNV was used to provide a data aggregation function which is (i) non-associative, and (ii) easy to compute. A commutative and associative alternative to FNV would be XOR. - -### Parameters - -* A 16 MB cache was chosen because a smaller cache would allow for an ASIC to be produced far too easily using the light-evaluation method. The 16 MB cache still requires a very high bandwidth of cache reading, whereas a smaller cache could be much more easily optimized. A larger cache would lead to the algorithm being too hard to evaluate with a light client. -* 256 parents per DAG item was chosen in order to ensure that time-memory tradeoffs can only be made at a worse-than-1:1 ratio. -* The 1 GB DAG size was chosen in order to require a level of memory larger than the size at which most specialized memories and caches are built, but still small enough for ordinary computers to be able to mine with it. -* The ~0.73x per year growth level was chosen to roughly be balanced with Moore's law increases at least initially (exponential growth has a risk of overshooting Moore's law, leading to a situation where mining requires very large amounts of memory and ordinary GPUs are no longer usable for mining). -* 64 accesses was chosen because a larger number of accesses would lead to light verification taking too long, and a smaller number would mean that the bulk of the time consumption is the SHA3 at the end, not the memory reads, making the algorithm not so strongly IO-bound. -* The epoch length cannot be infinite (ie. constant dataset) because then the algorithm could be optimized via ROM, and very long epoch lengths make it easier to create memory which is designed to be updated very infrequently and only read often. Excessively short epochs would increase barriers to entry as weak machines would need to spend much of their time on a fixed cost of updating the dataset. The epoch length can probably be reduced or increased substantially if design considerations require it. -* The cache size and dataset size is prime in order to help mitigate the risk of cycles appearing in dataset item generation or mining. \ No newline at end of file diff --git a/Ethash.md b/Ethash.md deleted file mode 100644 index 49cec0a41..000000000 --- a/Ethash.md +++ /dev/null @@ -1,998 +0,0 @@ ---- -name: Ethash -category: ---- - -**This spec is REVISION 23. Whenever you substantively (ie. not clarifications) update the algorithm, please update the revision number in this sentence. Also, in all implementations please include a spec revision number** - -Ethash is the planned PoW algorithm for Ethereum 1.0. It is the latest version of Dagger-Hashimoto, although it can no longer appropriately be called that since many of the original features of both algorithms have been drastically changed in the last month of research and development. See [https://github.com/ethereum/wiki/wiki/Dagger-Hashimoto](https://github.com/ethereum/wiki/wiki/Dagger-Hashimoto) for the original version. - -The general route that the algorithm takes is as follows: - -1. There exists a **seed** which can be computed for each block by scanning through the block headers up until that point. -2. From the seed, one can compute a **16 MB pseudorandom cache**. Light clients store the cache. -3. From the cache, we can generate a **1 GB dataset**, with the property that each item in the dataset depends on only a small number of items from the cache. Full clients and miners store the dataset. The dataset grows linearly with time. -4. Mining involves grabbing random slices of the dataset and hashing them together. Verification can be done with low memory by using the cache to regenerate the specific pieces of the dataset that you need, so you only need to store the cache. - -The large dataset is updated once every 30000 blocks, so the vast majority of a miner's effort will be reading the dataset, not making changes to it. - -See [https://github.com/ethereum/wiki/wiki/Ethash-Design-Rationale](https://github.com/ethereum/wiki/wiki/Ethash-Design-Rationale) for design rationale considerations for this algorithm. - -### Definitions - -We employ the following definitions: - -``` -WORD_BYTES = 4 # bytes in word -DATASET_BYTES_INIT = 2**30 # bytes in dataset at genesis -DATASET_BYTES_GROWTH = 2**23 # dataset growth per epoch -CACHE_BYTES_INIT = 2**24 # bytes in dataset at genesis -CACHE_BYTES_GROWTH = 2**17 # cache growth per epoch -CACHE_MULTIPLIER=1024 # Size of the DAG relative to the cache -EPOCH_LENGTH = 30000 # blocks per epoch -MIX_BYTES = 128 # width of mix -HASH_BYTES = 64 # hash length in bytes -DATASET_PARENTS = 256 # number of parents of each dataset element -CACHE_ROUNDS = 3 # number of rounds in cache production -ACCESSES = 64 # number of accesses in hashimoto loop -``` - -### Parameters - -The parameters for Ethash's cache and dataset depend on the block number. The cache size and dataset size both grow linearly; however, we always take the highest prime below the linearly growing threshold in order to reduce the risk of accidental regularities leading to cyclic behavior. - -```python -def get_cache_size(block_number): - sz = CACHE_BYTES_INIT + CACHE_BYTES_GROWTH * (block_number // EPOCH_LENGTH) - sz -= HASH_BYTES - while not isprime(sz / HASH_BYTES): - sz -= 2 * HASH_BYTES - return sz - -def get_full_size(block_number): - sz = DATASET_BYTES_INIT + DATASET_BYTES_GROWTH * (block_number // EPOCH_LENGTH) - sz -= MIX_BYTES - while not isprime(sz / MIX_BYTES): - sz -= 2 * MIX_BYTES - return sz -``` - -Tables of dataset and cache size values are provided in the appendix. - -### Cache Generation - -Now, we specify the function for producing a cache: - -```python -def mkcache(cache_size, seed): - n = cache_size // HASH_BYTES - - # Sequentially produce the initial dataset - o = [sha3_512(seed)] - for i in range(1, n): - o.append(sha3_512(o[-1])) - - # Use a low-round version of randmemohash - for _ in range(CACHE_ROUNDS): - for i in range(n): - v = o[i][0] % n - o[i] = sha3_512(map(xor, o[(i-1+n) % n], o[v])) - - return o -``` - -[Sergio2014]: http://www.hashcash.org/papers/memohash.pdf - -The cache production process involves first sequentially filling up 32 MB of memory, then performing two passes of Sergio Demian Lerner's *RandMemoHash* algorithm from [*Strict Memory Hard Hashing Functions* (2014)](http://www.hashcash.org/papers/memohash.pdf). The output is a set of 524288 64-byte values. - -### Data aggregation function - -We use an algorithm inspired by the [FNV hash](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function) in some cases as a non-associative substitute for XOR. Note that we multiply the prime with the full 32-bit input, in contrast with the FNV-1 spec which multiplies the prime with one byte (octet) in turn. - -```python -FNV_PRIME = 0x01000193 - -def fnv(v1, v2): - return (v1 * FNV_PRIME ^ v2) % 2**32 -``` - -### Full dataset calculation - -Each 64-byte item in the full 1 GB dataset is computed as follows: - -```python -def calc_dataset_item(cache, i): - n = len(cache) - r = HASH_BYTES // WORD_BYTES - # initialize the mix - mix = copy.copy(cache[i % n]) - mix[0] ^= i - mix = sha3_512(mix) - # fnv it with a lot of random cache nodes based on i - for j in range(DATASET_PARENTS): - cache_index = fnv(i ^ j, mix[j % r]) - mix = map(fnv, mix, cache[cache_index % n]) - return sha3_512(mix) -``` - -Essentially, we combine data from 256 pseudorandomly selected cache nodes, and hash that to compute the dataset node. The entire dataset is then generated by: - -```python -def calc_dataset(full_size, cache): - return [calc_dataset_item(cache, i) for i in range(full_size // HASH_BYTES)] -``` - -### Main Loop - -Now, we specify the main "hashimoto"-like loop, where we aggregate data from the full dataset in order to produce our final value for a particular header and nonce. In the code below, `header` represents the SHA3-256 _hash_ of the RLP representation of a _truncated_ block header, that is, of a header excluding the fields **mixHash** and **nonce**. `nonce` is the eight bytes of a 64 bit unsigned integer in big-endian order. So `nonce[::-1]` is the eight-byte little-endian representation of that value: - -```python -def hashimoto(header, nonce, full_size, dataset_lookup): - n = full_size / HASH_BYTES - w = MIX_BYTES // WORD_BYTES - mixhashes = MIX_BYTES / HASH_BYTES - # combine header+nonce into a 64 byte seed - s = sha3_512(header + nonce[::-1]) - # start the mix with replicated s - mix = [] - for _ in range(MIX_BYTES / HASH_BYTES): - mix.extend(s) - # mix in random dataset nodes - for i in range(ACCESSES): - p = fnv(i ^ s[0], mix[i % w]) % (n // mixhashes) * mixhashes - newdata = [] - for j in range(MIX_BYTES / HASH_BYTES): - newdata.extend(dataset_lookup(p + j)) - mix = map(fnv, mix, newdata) - # compress mix - cmix = [] - for i in range(0, len(mix), 4): - cmix.append(fnv(fnv(fnv(mix[i], mix[i+1]), mix[i+2]), mix[i+3])) - return { - "mix digest": serialize_hash(cmix), - "result": serialize_hash(sha3_256(s+cmix)) - } - -def hashimoto_light(full_size, cache, header, nonce): - return hashimoto(header, nonce, full_size, lambda x: calc_dataset_item(cache, x)) - -def hashimoto_full(full_size, dataset, header, nonce): - return hashimoto(header, nonce, full_size, lambda x: dataset[x]) -``` - -Essentially, we maintain a "mix" 128 bytes wide, and repeatedly sequentially fetch 128 bytes from the full dataset and use the `fnv` function to combine it with the mix. 128 bytes of sequential access are used so that each round of the algorithm always fetches a full page from RAM, minimizing translation lookaside buffer misses which ASICs would theoretically be able to avoid. - -If the output of this algorithm is below the desired target, then the nonce is valid. Note that the extra application of `sha3_256` at the end ensures that there exists an intermediate nonce which can be provided to prove that at least a small amount of work was done; this quick outer PoW verification can be used for anti-DDoS purposes. It also serves to provide statistical assurance that the result is an unbiased, 256 bit number. - -### Mining - -The mining algorithm is defined as follows: - -```python -def mine(full_size, dataset, header, difficulty): - target = zpad(encode_int(2**256 // difficulty), 64)[::-1] - from random import randint - nonce = randint(0, 2**64) - while hashimoto_full(full_size, dataset, header, nonce) > target: - nonce = (nonce + 1) % 2**64 - return nonce -``` - -### Defining the Seed Hash - -In order to compute the seed hash that would be used to mine on top of a given block, we use the following algorithm: - -```python - def get_seedhash(block): - s = '\x00' * 32 - for i in range(block.number // EPOCH_LENGTH): - s = serialize_hash(sha3_256(s)) - return s -``` - -Note that for smooth mining and verifying, we recommend pre-computing future seedhashes and datasets in a separate thread. - -### Appendix - -The following code should be prepended if you are interested in running the above python spec as code. - -```python -import sha3, copy - -# Assumes little endian bit ordering (same as Intel architectures) -def decode_int(s): - return int(s[::-1].encode('hex'), 16) if s else 0 - -def encode_int(s): - a = "%x" % s - return '' if s == 0 else ('0' * (len(a) % 2) + a).decode('hex')[::-1] - -def zpad(s, length): - return s + '\x00' * max(0, length - len(s)) - -def serialize_hash(h): - return ''.join([zpad(encode_int(x), 4) for x in h]) - -def deserialize_hash(h): - return [decode_int(h[i:i+WORD_BYTES]) for i in range(0, len(h), WORD_BYTES)] - -def hash_words(h, sz, x): - if isinstance(x, list): - x = serialize_hash(x) - y = h(x) - return deserialize_hash(y) - -def serialize_cache(ds): - return ''.join([serialize_hash(h) for h in ds]) - -serialize_dataset = serialize_cache - -# sha3 hash function, outputs 64 bytes -def sha3_512(x): - return hash_words(lambda v: sha3.sha3_512(v).digest(), 64, x) - -def sha3_256(x): - return hash_words(lambda v: sha3.sha3_256(v).digest(), 32, x) - -def xor(a, b): - return a ^ b - -def isprime(x): - for i in range(2, int(x**0.5)): - if x % i == 0: - return False - return True -``` - -### Data Sizes - -The following lookup tables provide approximately 2048 tabulated epochs of data sizes and cache sizes. They were generated with the *Mathematica* function provided here: - -```python -def get_datasize(block_number): - return data_sizes[block_number // EPOCH_LENGTH] - -def get_cachesize(block_number): - return cache_sizes[block_number // EPOCH_LENGTH] - -data_sizes = [ -1073739904, 1082130304, 1090514816, 1098906752, 1107293056, -1115684224, 1124070016, 1132461952, 1140849536, 1149232768, -1157627776, 1166013824, 1174404736, 1182786944, 1191180416, -1199568512, 1207958912, 1216345216, 1224732032, 1233124736, -1241513344, 1249902464, 1258290304, 1266673792, 1275067264, -1283453312, 1291844992, 1300234112, 1308619904, 1317010048, -1325397376, 1333787776, 1342176128, 1350561664, 1358954368, -1367339392, 1375731584, 1384118144, 1392507008, 1400897408, -1409284736, 1417673344, 1426062464, 1434451072, 1442839168, -1451229056, 1459615616, 1468006016, 1476394112, 1484782976, -1493171584, 1501559168, 1509948032, 1518337664, 1526726528, -1535114624, 1543503488, 1551892096, 1560278656, 1568669056, -1577056384, 1585446272, 1593831296, 1602219392, 1610610304, -1619000192, 1627386752, 1635773824, 1644164224, 1652555648, -1660943488, 1669332608, 1677721216, 1686109312, 1694497664, -1702886272, 1711274624, 1719661184, 1728047744, 1736434816, -1744829056, 1753218944, 1761606272, 1769995904, 1778382464, -1786772864, 1795157888, 1803550592, 1811937664, 1820327552, -1828711552, 1837102976, 1845488768, 1853879936, 1862269312, -1870656896, 1879048064, 1887431552, 1895825024, 1904212096, -1912601216, 1920988544, 1929379456, 1937765504, 1946156672, -1954543232, 1962932096, 1971321728, 1979707264, 1988093056, -1996487552, 2004874624, 2013262208, 2021653888, 2030039936, -2038430848, 2046819968, 2055208576, 2063596672, 2071981952, -2080373632, 2088762752, 2097149056, 2105539712, 2113928576, -2122315136, 2130700672, 2139092608, 2147483264, 2155872128, -2164257664, 2172642176, 2181035392, 2189426048, 2197814912, -2206203008, 2214587264, 2222979712, 2231367808, 2239758208, -2248145024, 2256527744, 2264922752, 2273312128, 2281701248, -2290086272, 2298476672, 2306867072, 2315251072, 2323639168, -2332032128, 2340420224, 2348808064, 2357196416, 2365580416, -2373966976, 2382363008, 2390748544, 2399139968, 2407530368, -2415918976, 2424307328, 2432695424, 2441084288, 2449472384, -2457861248, 2466247808, 2474637184, 2483026816, 2491414144, -2499803776, 2508191872, 2516582272, 2524970368, 2533359232, -2541743488, 2550134144, 2558525056, 2566913408, 2575301504, -2583686528, 2592073856, 2600467328, 2608856192, 2617240448, -2625631616, 2634022016, 2642407552, 2650796416, 2659188352, -2667574912, 2675965312, 2684352896, 2692738688, 2701130624, -2709518464, 2717907328, 2726293376, 2734685056, 2743073152, -2751462016, 2759851648, 2768232832, 2776625536, 2785017728, -2793401984, 2801794432, 2810182016, 2818571648, 2826959488, -2835349376, 2843734144, 2852121472, 2860514432, 2868900992, -2877286784, 2885676928, 2894069632, 2902451584, 2910843008, -2919234688, 2927622784, 2936011648, 2944400768, 2952789376, -2961177728, 2969565568, 2977951616, 2986338944, 2994731392, -3003120256, 3011508352, 3019895936, 3028287104, 3036675968, -3045063808, 3053452928, 3061837696, 3070228352, 3078615424, -3087003776, 3095394944, 3103782272, 3112173184, 3120562048, -3128944768, 3137339264, 3145725056, 3154109312, 3162505088, -3170893184, 3179280256, 3187669376, 3196056704, 3204445568, -3212836736, 3221224064, 3229612928, 3238002304, 3246391168, -3254778496, 3263165824, 3271556224, 3279944576, 3288332416, -3296719232, 3305110912, 3313500032, 3321887104, 3330273152, -3338658944, 3347053184, 3355440512, 3363827072, 3372220288, -3380608384, 3388997504, 3397384576, 3405774208, 3414163072, -3422551936, 3430937984, 3439328384, 3447714176, 3456104576, -3464493952, 3472883584, 3481268864, 3489655168, 3498048896, -3506434432, 3514826368, 3523213952, 3531603584, 3539987072, -3548380288, 3556763264, 3565157248, 3573545344, 3581934464, -3590324096, 3598712704, 3607098752, 3615488384, 3623877248, -3632265856, 3640646528, 3649043584, 3657430144, 3665821568, -3674207872, 3682597504, 3690984832, 3699367808, 3707764352, -3716152448, 3724541056, 3732925568, 3741318016, 3749706368, -3758091136, 3766481536, 3774872704, 3783260032, 3791650432, -3800036224, 3808427648, 3816815488, 3825204608, 3833592704, -3841981568, 3850370432, 3858755968, 3867147904, 3875536256, -3883920512, 3892313728, 3900702592, 3909087872, 3917478784, -3925868416, 3934256512, 3942645376, 3951032192, 3959422336, -3967809152, 3976200064, 3984588416, 3992974976, 4001363584, -4009751168, 4018141312, 4026530432, 4034911616, 4043308928, -4051695488, 4060084352, 4068472448, 4076862848, 4085249408, -4093640576, 4102028416, 4110413696, 4118805632, 4127194496, -4135583104, 4143971968, 4152360832, 4160746112, 4169135744, -4177525888, 4185912704, 4194303616, 4202691968, 4211076736, -4219463552, 4227855488, 4236246656, 4244633728, 4253022848, -4261412224, 4269799808, 4278184832, 4286578048, 4294962304, -4303349632, 4311743104, 4320130432, 4328521088, 4336909184, -4345295488, 4353687424, 4362073472, 4370458496, 4378852736, -4387238528, 4395630208, 4404019072, 4412407424, 4420790656, -4429182848, 4437571456, 4445962112, 4454344064, 4462738048, -4471119232, 4479516544, 4487904128, 4496289664, 4504682368, -4513068416, 4521459584, 4529846144, 4538232704, 4546619776, -4555010176, 4563402112, 4571790208, 4580174464, 4588567936, -4596957056, 4605344896, 4613734016, 4622119808, 4630511488, -4638898816, 4647287936, 4655675264, 4664065664, 4672451968, -4680842624, 4689231488, 4697620352, 4706007424, 4714397056, -4722786176, 4731173248, 4739562368, 4747951744, 4756340608, -4764727936, 4773114496, 4781504384, 4789894784, 4798283648, -4806667648, 4815059584, 4823449472, 4831835776, 4840226176, -4848612224, 4857003392, 4865391488, 4873780096, 4882169728, -4890557312, 4898946944, 4907333248, 4915722368, 4924110976, -4932499328, 4940889728, 4949276032, 4957666432, 4966054784, -4974438016, 4982831488, 4991221376, 4999607168, 5007998848, -5016386432, 5024763776, 5033164672, 5041544576, 5049941888, -5058329728, 5066717056, 5075107456, 5083494272, 5091883904, -5100273536, 5108662144, 5117048192, 5125436032, 5133827456, -5142215296, 5150605184, 5158993024, 5167382144, 5175769472, -5184157568, 5192543872, 5200936064, 5209324928, 5217711232, -5226102656, 5234490496, 5242877312, 5251263872, 5259654016, -5268040832, 5276434304, 5284819328, 5293209728, 5301598592, -5309986688, 5318374784, 5326764416, 5335151488, 5343542144, -5351929472, 5360319872, 5368706944, 5377096576, 5385484928, -5393871232, 5402263424, 5410650496, 5419040384, 5427426944, -5435816576, 5444205952, 5452594816, 5460981376, 5469367936, -5477760896, 5486148736, 5494536832, 5502925952, 5511315328, -5519703424, 5528089984, 5536481152, 5544869504, 5553256064, -5561645696, 5570032768, 5578423936, 5586811264, 5595193216, -5603585408, 5611972736, 5620366208, 5628750464, 5637143936, -5645528192, 5653921408, 5662310272, 5670694784, 5679082624, -5687474048, 5695864448, 5704251008, 5712641408, 5721030272, -5729416832, 5737806208, 5746194304, 5754583936, 5762969984, -5771358592, 5779748224, 5788137856, 5796527488, 5804911232, -5813300608, 5821692544, 5830082176, 5838468992, 5846855552, -5855247488, 5863636096, 5872024448, 5880411008, 5888799872, -5897186432, 5905576832, 5913966976, 5922352768, 5930744704, -5939132288, 5947522432, 5955911296, 5964299392, 5972688256, -5981074304, 5989465472, 5997851008, 6006241408, 6014627968, -6023015552, 6031408256, 6039796096, 6048185216, 6056574848, -6064963456, 6073351808, 6081736064, 6090128768, 6098517632, -6106906496, 6115289216, 6123680896, 6132070016, 6140459648, -6148849024, 6157237376, 6165624704, 6174009728, 6182403712, -6190792064, 6199176064, 6207569792, 6215952256, 6224345216, -6232732544, 6241124224, 6249510272, 6257899136, 6266287744, -6274676864, 6283065728, 6291454336, 6299843456, 6308232064, -6316620928, 6325006208, 6333395584, 6341784704, 6350174848, -6358562176, 6366951296, 6375337856, 6383729536, 6392119168, -6400504192, 6408895616, 6417283456, 6425673344, 6434059136, -6442444672, 6450837376, 6459223424, 6467613056, 6476004224, -6484393088, 6492781952, 6501170048, 6509555072, 6517947008, -6526336384, 6534725504, 6543112832, 6551500672, 6559888768, -6568278656, 6576662912, 6585055616, 6593443456, 6601834112, -6610219648, 6618610304, 6626999168, 6635385472, 6643777408, -6652164224, 6660552832, 6668941952, 6677330048, 6685719424, -6694107776, 6702493568, 6710882176, 6719274112, 6727662976, -6736052096, 6744437632, 6752825984, 6761213824, 6769604224, -6777993856, 6786383488, 6794770816, 6803158144, 6811549312, -6819937664, 6828326528, 6836706176, 6845101696, 6853491328, -6861880448, 6870269312, 6878655104, 6887046272, 6895433344, -6903822208, 6912212864, 6920596864, 6928988288, 6937377152, -6945764992, 6954149248, 6962544256, 6970928768, 6979317376, -6987709312, 6996093824, 7004487296, 7012875392, 7021258624, -7029652352, 7038038912, 7046427776, 7054818944, 7063207808, -7071595136, 7079980928, 7088372608, 7096759424, 7105149824, -7113536896, 7121928064, 7130315392, 7138699648, 7147092352, -7155479168, 7163865728, 7172249984, 7180648064, 7189036672, -7197424768, 7205810816, 7214196608, 7222589824, 7230975104, -7239367552, 7247755904, 7256145536, 7264533376, 7272921472, -7281308032, 7289694848, 7298088832, 7306471808, 7314864512, -7323253888, 7331643008, 7340029568, 7348419712, 7356808832, -7365196672, 7373585792, 7381973888, 7390362752, 7398750592, -7407138944, 7415528576, 7423915648, 7432302208, 7440690304, -7449080192, 7457472128, 7465860992, 7474249088, 7482635648, -7491023744, 7499412608, 7507803008, 7516192384, 7524579968, -7532967296, 7541358464, 7549745792, 7558134656, 7566524032, -7574912896, 7583300992, 7591690112, 7600075136, 7608466816, -7616854912, 7625244544, 7633629824, 7642020992, 7650410368, -7658794112, 7667187328, 7675574912, 7683961984, 7692349568, -7700739712, 7709130368, 7717519232, 7725905536, 7734295424, -7742683264, 7751069056, 7759457408, 7767849088, 7776238208, -7784626816, 7793014912, 7801405312, 7809792128, 7818179968, -7826571136, 7834957184, 7843347328, 7851732352, 7860124544, -7868512384, 7876902016, 7885287808, 7893679744, 7902067072, -7910455936, 7918844288, 7927230848, 7935622784, 7944009344, -7952400256, 7960786048, 7969176704, 7977565312, 7985953408, -7994339968, 8002730368, 8011119488, 8019508096, 8027896192, -8036285056, 8044674688, 8053062272, 8061448832, 8069838464, -8078227328, 8086616704, 8095006592, 8103393664, 8111783552, -8120171392, 8128560256, 8136949376, 8145336704, 8153726848, -8162114944, 8170503296, 8178891904, 8187280768, 8195669632, -8204058496, 8212444544, 8220834176, 8229222272, 8237612672, -8246000768, 8254389376, 8262775168, 8271167104, 8279553664, -8287944064, 8296333184, 8304715136, 8313108352, 8321497984, -8329885568, 8338274432, 8346663296, 8355052928, 8363441536, -8371828352, 8380217984, 8388606592, 8396996224, 8405384576, -8413772672, 8422161536, 8430549376, 8438939008, 8447326592, -8455715456, 8464104832, 8472492928, 8480882048, 8489270656, -8497659776, 8506045312, 8514434944, 8522823808, 8531208832, -8539602304, 8547990656, 8556378752, 8564768384, 8573154176, -8581542784, 8589933952, 8598322816, 8606705024, 8615099264, -8623487872, 8631876992, 8640264064, 8648653952, 8657040256, -8665430656, 8673820544, 8682209152, 8690592128, 8698977152, -8707374464, 8715763328, 8724151424, 8732540032, 8740928384, -8749315712, 8757704576, 8766089344, 8774480768, 8782871936, -8791260032, 8799645824, 8808034432, 8816426368, 8824812928, -8833199488, 8841591424, 8849976448, 8858366336, 8866757248, -8875147136, 8883532928, 8891923328, 8900306816, 8908700288, -8917088384, 8925478784, 8933867392, 8942250368, 8950644608, -8959032704, 8967420544, 8975809664, 8984197504, 8992584064, -9000976256, 9009362048, 9017752448, 9026141312, 9034530688, -9042917504, 9051307904, 9059694208, 9068084864, 9076471424, -9084861824, 9093250688, 9101638528, 9110027648, 9118416512, -9126803584, 9135188096, 9143581312, 9151969664, 9160356224, -9168747136, 9177134464, 9185525632, 9193910144, 9202302848, -9210690688, 9219079552, 9227465344, 9235854464, 9244244864, -9252633472, 9261021824, 9269411456, 9277799296, 9286188928, -9294574208, 9302965888, 9311351936, 9319740032, 9328131968, -9336516736, 9344907392, 9353296768, 9361685888, 9370074752, -9378463616, 9386849408, 9395239808, 9403629184, 9412016512, -9420405376, 9428795008, 9437181568, 9445570688, 9453960832, -9462346624, 9470738048, 9479121536, 9487515008, 9495903616, -9504289664, 9512678528, 9521067904, 9529456256, 9537843584, -9546233728, 9554621312, 9563011456, 9571398784, 9579788672, -9588178304, 9596567168, 9604954496, 9613343104, 9621732992, -9630121856, 9638508416, 9646898816, 9655283584, 9663675776, -9672061312, 9680449664, 9688840064, 9697230464, 9705617536, -9714003584, 9722393984, 9730772608, 9739172224, 9747561088, -9755945344, 9764338816, 9772726144, 9781116544, 9789503872, -9797892992, 9806282624, 9814670464, 9823056512, 9831439232, -9839833984, 9848224384, 9856613504, 9865000576, 9873391232, -9881772416, 9890162816, 9898556288, 9906940544, 9915333248, -9923721088, 9932108672, 9940496512, 9948888448, 9957276544, -9965666176, 9974048384, 9982441088, 9990830464, 9999219584, -10007602816, 10015996544, 10024385152, 10032774016, 10041163648, -10049548928, 10057940096, 10066329472, 10074717824, 10083105152, -10091495296, 10099878784, 10108272256, 10116660608, 10125049216, -10133437312, 10141825664, 10150213504, 10158601088, 10166991232, -10175378816, 10183766144, 10192157312, 10200545408, 10208935552, -10217322112, 10225712768, 10234099328, 10242489472, 10250876032, -10259264896, 10267656064, 10276042624, 10284429184, 10292820352, -10301209472, 10309598848, 10317987712, 10326375296, 10334763392, -10343153536, 10351541632, 10359930752, 10368318592, 10376707456, -10385096576, 10393484672, 10401867136, 10410262144, 10418647424, -10427039104, 10435425664, 10443810176, 10452203648, 10460589952, -10468982144, 10477369472, 10485759104, 10494147712, 10502533504, -10510923392, 10519313536, 10527702656, 10536091264, 10544478592, -10552867712, 10561255808, 10569642368, 10578032768, 10586423168, -10594805632, 10603200128, 10611588992, 10619976064, 10628361344, -10636754048, 10645143424, 10653531776, 10661920384, 10670307968, -10678696832, 10687086464, 10695475072, 10703863168, 10712246144, -10720639616, 10729026688, 10737414784, 10745806208, 10754190976, -10762581376, 10770971264, 10779356288, 10787747456, 10796135552, -10804525184, 10812915584, 10821301888, 10829692288, 10838078336, -10846469248, 10854858368, 10863247232, 10871631488, 10880023424, -10888412032, 10896799616, 10905188992, 10913574016, 10921964672, -10930352768, 10938742912, 10947132544, 10955518592, 10963909504, -10972298368, 10980687488, 10989074816, 10997462912, 11005851776, -11014241152, 11022627712, 11031017344, 11039403904, 11047793024, -11056184704, 11064570752, 11072960896, 11081343872, 11089737856, -11098128256, 11106514816, 11114904448, 11123293568, 11131680128, -11140065152, 11148458368, 11156845696, 11165236864, 11173624192, -11182013824, 11190402688, 11198790784, 11207179136, 11215568768, -11223957376, 11232345728, 11240734592, 11249122688, 11257511296, -11265899648, 11274285952, 11282675584, 11291065472, 11299452544, -11307842432, 11316231296, 11324616832, 11333009024, 11341395584, -11349782656, 11358172288, 11366560384, 11374950016, 11383339648, -11391721856, 11400117376, 11408504192, 11416893568, 11425283456, -11433671552, 11442061184, 11450444672, 11458837888, 11467226752, -11475611776, 11484003968, 11492392064, 11500780672, 11509169024, -11517550976, 11525944448, 11534335616, 11542724224, 11551111808, -11559500672, 11567890304, 11576277376, 11584667008, 11593056128, -11601443456, 11609830016, 11618221952, 11626607488, 11634995072, -11643387776, 11651775104, 11660161664, 11668552576, 11676940928, -11685330304, 11693718656, 11702106496, 11710496128, 11718882688, -11727273088, 11735660416, 11744050048, 11752437376, 11760824704, -11769216128, 11777604736, 11785991296, 11794381952, 11802770048, -11811157888, 11819548544, 11827932544, 11836324736, 11844713344, -11853100928, 11861486464, 11869879936, 11878268032, 11886656896, -11895044992, 11903433088, 11911822976, 11920210816, 11928600448, -11936987264, 11945375872, 11953761152, 11962151296, 11970543488, -11978928512, 11987320448, 11995708288, 12004095104, 12012486272, -12020875136, 12029255552, 12037652096, 12046039168, 12054429568, -12062813824, 12071206528, 12079594624, 12087983744, 12096371072, -12104759936, 12113147264, 12121534592, 12129924992, 12138314624, -12146703232, 12155091584, 12163481216, 12171864704, 12180255872, -12188643968, 12197034112, 12205424512, 12213811328, 12222199424, -12230590336, 12238977664, 12247365248, 12255755392, 12264143488, -12272531584, 12280920448, 12289309568, 12297694592, 12306086528, -12314475392, 12322865024, 12331253632, 12339640448, 12348029312, -12356418944, 12364805248, 12373196672, 12381580928, 12389969024, -12398357632, 12406750592, 12415138432, 12423527552, 12431916416, -12440304512, 12448692352, 12457081216, 12465467776, 12473859968, -12482245504, 12490636672, 12499025536, 12507411584, 12515801728, -12524190592, 12532577152, 12540966272, 12549354368, 12557743232, -12566129536, 12574523264, 12582911872, 12591299456, 12599688064, -12608074624, 12616463488, 12624845696, 12633239936, 12641631616, -12650019968, 12658407296, 12666795136, 12675183232, 12683574656, -12691960192, 12700350592, 12708740224, 12717128576, 12725515904, -12733906816, 12742295168, 12750680192, 12759071872, 12767460736, -12775848832, 12784236928, 12792626816, 12801014656, 12809404288, -12817789312, 12826181504, 12834568832, 12842954624, 12851345792, -12859732352, 12868122496, 12876512128, 12884901248, 12893289088, -12901672832, 12910067584, 12918455168, 12926842496, 12935232896, -12943620736, 12952009856, 12960396928, 12968786816, 12977176192, -12985563776, 12993951104, 13002341504, 13010730368, 13019115392, -13027506304, 13035895168, 13044272512, 13052673152, 13061062528, -13069446272, 13077838976, 13086227072, 13094613632, 13103000192, -13111393664, 13119782528, 13128157568, 13136559232, 13144945024, -13153329536, 13161724288, 13170111872, 13178502784, 13186884736, -13195279744, 13203667072, 13212057472, 13220445824, 13228832128, -13237221248, 13245610624, 13254000512, 13262388352, 13270777472, -13279166336, 13287553408, 13295943296, 13304331904, 13312719488, -13321108096, 13329494656, 13337885824, 13346274944, 13354663808, -13363051136, 13371439232, 13379825024, 13388210816, 13396605056, -13404995456, 13413380224, 13421771392, 13430159744, 13438546048, -13446937216, 13455326848, 13463708288, 13472103808, 13480492672, -13488875648, 13497269888, 13505657728, 13514045312, 13522435712, -13530824576, 13539210112, 13547599232, 13555989376, 13564379008, -13572766336, 13581154432, 13589544832, 13597932928, 13606320512, -13614710656, 13623097472, 13631477632, 13639874944, 13648264064, -13656652928, 13665041792, 13673430656, 13681818496, 13690207616, -13698595712, 13706982272, 13715373184, 13723762048, 13732150144, -13740536704, 13748926592, 13757316224, 13765700992, 13774090112, -13782477952, 13790869376, 13799259008, 13807647872, 13816036736, -13824425344, 13832814208, 13841202304, 13849591424, 13857978752, -13866368896, 13874754688, 13883145344, 13891533184, 13899919232, -13908311168, 13916692096, 13925085056, 13933473152, 13941866368, -13950253696, 13958643584, 13967032192, 13975417216, 13983807616, -13992197504, 14000582272, 14008973696, 14017363072, 14025752192, -14034137984, 14042528384, 14050918016, 14059301504, 14067691648, -14076083584, 14084470144, 14092852352, 14101249664, 14109635968, -14118024832, 14126407552, 14134804352, 14143188608, 14151577984, -14159968384, 14168357248, 14176741504, 14185127296, 14193521024, -14201911424, 14210301824, 14218685056, 14227067264, 14235467392, -14243855488, 14252243072, 14260630144, 14269021568, 14277409408, -14285799296, 14294187904, 14302571392, 14310961792, 14319353728, -14327738752, 14336130944, 14344518784, 14352906368, 14361296512, -14369685376, 14378071424, 14386462592, 14394848128, 14403230848, -14411627392, 14420013952, 14428402304, 14436793472, 14445181568, -14453569664, 14461959808, 14470347904, 14478737024, 14487122816, -14495511424, 14503901824, 14512291712, 14520677504, 14529064832, -14537456768, 14545845632, 14554234496, 14562618496, 14571011456, -14579398784, 14587789184, 14596172672, 14604564608, 14612953984, -14621341312, 14629724288, 14638120832, 14646503296, 14654897536, -14663284864, 14671675264, 14680061056, 14688447616, 14696835968, -14705228416, 14713616768, 14722003328, 14730392192, 14738784128, -14747172736, 14755561088, 14763947648, 14772336512, 14780725376, -14789110144, 14797499776, 14805892736, 14814276992, 14822670208, -14831056256, 14839444352, 14847836032, 14856222848, 14864612992, -14872997504, 14881388672, 14889775744, 14898165376, 14906553472, -14914944896, 14923329664, 14931721856, 14940109696, 14948497024, -14956887424, 14965276544, 14973663616, 14982053248, 14990439808, -14998830976, 15007216768, 15015605888, 15023995264, 15032385152, -15040768384, 15049154944, 15057549184, 15065939072, 15074328448, -15082715008, 15091104128, 15099493504, 15107879296, 15116269184, -15124659584, 15133042304, 15141431936, 15149824384, 15158214272, -15166602368, 15174991232, 15183378304, 15191760512, 15200154496, -15208542592, 15216931712, 15225323392, 15233708416, 15242098048, -15250489216, 15258875264, 15267265408, 15275654528, 15284043136, -15292431488, 15300819584, 15309208192, 15317596544, 15325986176, -15334374784, 15342763648, 15351151744, 15359540608, 15367929728, -15376318336, 15384706432, 15393092992, 15401481856, 15409869952, -15418258816, 15426649984, 15435037568, 15443425664, 15451815296, -15460203392, 15468589184, 15476979328, 15485369216, 15493755776, -15502146944, 15510534272, 15518924416, 15527311232, 15535699072, -15544089472, 15552478336, 15560866688, 15569254528, 15577642624, -15586031488, 15594419072, 15602809472, 15611199104, 15619586432, -15627975296, 15636364928, 15644753792, 15653141888, 15661529216, -15669918848, 15678305152, 15686696576, 15695083136, 15703474048, -15711861632, 15720251264, 15728636288, 15737027456, 15745417088, -15753804928, 15762194048, 15770582656, 15778971008, 15787358336, -15795747712, 15804132224, 15812523392, 15820909696, 15829300096, -15837691264, 15846071936, 15854466944, 15862855808, 15871244672, -15879634816, 15888020608, 15896409728, 15904799104, 15913185152, -15921577088, 15929966464, 15938354816, 15946743424, 15955129472, -15963519872, 15971907968, 15980296064, 15988684928, 15997073024, -16005460864, 16013851264, 16022241152, 16030629248, 16039012736, -16047406976, 16055794816, 16064181376, 16072571264, 16080957824, -16089346688, 16097737856, 16106125184, 16114514816, 16122904192, -16131292544, 16139678848, 16148066944, 16156453504, 16164839552, -16173236096, 16181623424, 16190012032, 16198401152, 16206790528, -16215177344, 16223567744, 16231956352, 16240344704, 16248731008, -16257117824, 16265504384, 16273898624, 16282281856, 16290668672, -16299064192, 16307449216, 16315842176, 16324230016, 16332613504, -16341006464, 16349394304, 16357783168, 16366172288, 16374561664, -16382951296, 16391337856, 16399726208, 16408116352, 16416505472, -16424892032, 16433282176, 16441668224, 16450058624, 16458448768, -16466836864, 16475224448, 16483613056, 16492001408, 16500391808, -16508779648, 16517166976, 16525555328, 16533944192, 16542330752, -16550719616, 16559110528, 16567497088, 16575888512, 16584274816, -16592665472, 16601051008, 16609442944, 16617832064, 16626218624, -16634607488, 16642996096, 16651385728, 16659773824, 16668163712, -16676552576, 16684938112, 16693328768, 16701718144, 16710095488, -16718492288, 16726883968, 16735272832, 16743661184, 16752049792, -16760436608, 16768827008, 16777214336, 16785599104, 16793992832, -16802381696, 16810768768, 16819151744, 16827542656, 16835934848, -16844323712, 16852711552, 16861101952, 16869489536, 16877876864, -16886265728, 16894653056, 16903044736, 16911431296, 16919821696, -16928207488, 16936592768, 16944987776, 16953375616, 16961763968, -16970152832, 16978540928, 16986929536, 16995319168, 17003704448, -17012096896, 17020481152, 17028870784, 17037262208, 17045649536, -17054039936, 17062426496, 17070814336, 17079205504, 17087592064, -17095978112, 17104369024, 17112759424, 17121147776, 17129536384, -17137926016, 17146314368, 17154700928, 17163089792, 17171480192, -17179864192, 17188256896, 17196644992, 17205033856, 17213423488, -17221811072, 17230198912, 17238588032, 17246976896, 17255360384, -17263754624, 17272143232, 17280530048, 17288918912, 17297309312, -17305696384, 17314085504, 17322475136, 17330863744, 17339252096, -17347640192, 17356026496, 17364413824, 17372796544, 17381190016, -17389583488, 17397972608, 17406360704, 17414748544, 17423135872, -17431527296, 17439915904, 17448303232, 17456691584, 17465081728, -17473468288, 17481857408, 17490247552, 17498635904, 17507022464, -17515409024, 17523801728, 17532189824, 17540577664, 17548966016, -17557353344, 17565741184, 17574131584, 17582519168, 17590907008, -17599296128, 17607687808, 17616076672, 17624455808, 17632852352, -17641238656, 17649630848, 17658018944, 17666403968, 17674794112, -17683178368, 17691573376, 17699962496, 17708350592, 17716739968, -17725126528, 17733517184, 17741898112, 17750293888, 17758673024, -17767070336, 17775458432, 17783848832, 17792236928, 17800625536, -17809012352, 17817402752, 17825785984, 17834178944, 17842563968, -17850955648, 17859344512, 17867732864, 17876119424, 17884511872, -17892900224, 17901287296, 17909677696, 17918058112, 17926451072, -17934843776, 17943230848, 17951609216, 17960008576, 17968397696, -17976784256, 17985175424, 17993564032, 18001952128, 18010339712, -18018728576, 18027116672, 18035503232, 18043894144, 18052283264, -18060672128, 18069056384, 18077449856, 18085837184, 18094225792, -18102613376, 18111004544, 18119388544, 18127781248, 18136170368, -18144558976, 18152947328, 18161336192, 18169724288, 18178108544, -18186498944, 18194886784, 18203275648, 18211666048, 18220048768, -18228444544, 18236833408, 18245220736] - -cache_sizes = [ -16776896, 16907456, 17039296, 17170112, 17301056, 17432512, 17563072, -17693888, 17824192, 17955904, 18087488, 18218176, 18349504, 18481088, -18611392, 18742336, 18874304, 19004224, 19135936, 19267264, 19398208, -19529408, 19660096, 19791424, 19922752, 20053952, 20184896, 20315968, -20446912, 20576576, 20709184, 20840384, 20971072, 21102272, 21233216, -21364544, 21494848, 21626816, 21757376, 21887552, 22019392, 22151104, -22281536, 22412224, 22543936, 22675264, 22806464, 22935872, 23068096, -23198272, 23330752, 23459008, 23592512, 23723968, 23854912, 23986112, -24116672, 24247616, 24378688, 24509504, 24640832, 24772544, 24903488, -25034432, 25165376, 25296704, 25427392, 25558592, 25690048, 25820096, -25951936, 26081728, 26214208, 26345024, 26476096, 26606656, 26737472, -26869184, 26998208, 27131584, 27262528, 27393728, 27523904, 27655744, -27786688, 27917888, 28049344, 28179904, 28311488, 28441792, 28573504, -28700864, 28835648, 28966208, 29096768, 29228608, 29359808, 29490752, -29621824, 29752256, 29882816, 30014912, 30144448, 30273728, 30406976, -30538432, 30670784, 30799936, 30932672, 31063744, 31195072, 31325248, -31456192, 31588288, 31719232, 31850432, 31981504, 32110784, 32243392, -32372672, 32505664, 32636608, 32767808, 32897344, 33029824, 33160768, -33289664, 33423296, 33554368, 33683648, 33816512, 33947456, 34076992, -34208704, 34340032, 34471744, 34600256, 34734016, 34864576, 34993984, -35127104, 35258176, 35386688, 35518528, 35650624, 35782336, 35910976, -36044608, 36175808, 36305728, 36436672, 36568384, 36699968, 36830656, -36961984, 37093312, 37223488, 37355072, 37486528, 37617472, 37747904, -37879232, 38009792, 38141888, 38272448, 38403392, 38535104, 38660672, -38795584, 38925632, 39059264, 39190336, 39320768, 39452096, 39581632, -39713984, 39844928, 39974848, 40107968, 40238144, 40367168, 40500032, -40631744, 40762816, 40894144, 41023552, 41155904, 41286208, 41418304, -41547712, 41680448, 41811904, 41942848, 42073792, 42204992, 42334912, -42467008, 42597824, 42729152, 42860096, 42991552, 43122368, 43253696, -43382848, 43515712, 43646912, 43777088, 43907648, 44039104, 44170432, -44302144, 44433344, 44564288, 44694976, 44825152, 44956864, 45088448, -45219008, 45350464, 45481024, 45612608, 45744064, 45874496, 46006208, -46136768, 46267712, 46399424, 46529344, 46660672, 46791488, 46923328, -47053504, 47185856, 47316928, 47447872, 47579072, 47710144, 47839936, -47971648, 48103232, 48234176, 48365248, 48496192, 48627136, 48757312, -48889664, 49020736, 49149248, 49283008, 49413824, 49545152, 49675712, -49807168, 49938368, 50069056, 50200256, 50331584, 50462656, 50593472, -50724032, 50853952, 50986048, 51117632, 51248576, 51379904, 51510848, -51641792, 51773248, 51903296, 52035136, 52164032, 52297664, 52427968, -52557376, 52690112, 52821952, 52952896, 53081536, 53213504, 53344576, -53475776, 53608384, 53738816, 53870528, 54000832, 54131776, 54263744, -54394688, 54525248, 54655936, 54787904, 54918592, 55049152, 55181248, -55312064, 55442752, 55574336, 55705024, 55836224, 55967168, 56097856, -56228672, 56358592, 56490176, 56621888, 56753728, 56884928, 57015488, -57146816, 57278272, 57409216, 57540416, 57671104, 57802432, 57933632, -58064576, 58195264, 58326976, 58457408, 58588864, 58720192, 58849984, -58981696, 59113024, 59243456, 59375552, 59506624, 59637568, 59768512, -59897792, 60030016, 60161984, 60293056, 60423872, 60554432, 60683968, -60817216, 60948032, 61079488, 61209664, 61341376, 61471936, 61602752, -61733696, 61865792, 61996736, 62127808, 62259136, 62389568, 62520512, -62651584, 62781632, 62910784, 63045056, 63176128, 63307072, 63438656, -63569216, 63700928, 63831616, 63960896, 64093888, 64225088, 64355392, -64486976, 64617664, 64748608, 64879424, 65009216, 65142464, 65273792, -65402816, 65535424, 65666752, 65797696, 65927744, 66060224, 66191296, -66321344, 66453056, 66584384, 66715328, 66846656, 66977728, 67108672, -67239104, 67370432, 67501888, 67631296, 67763776, 67895104, 68026304, -68157248, 68287936, 68419264, 68548288, 68681408, 68811968, 68942912, -69074624, 69205568, 69337024, 69467584, 69599168, 69729472, 69861184, -69989824, 70122944, 70253888, 70385344, 70515904, 70647232, 70778816, -70907968, 71040832, 71171648, 71303104, 71432512, 71564992, 71695168, -71826368, 71958464, 72089536, 72219712, 72350144, 72482624, 72613568, -72744512, 72875584, 73006144, 73138112, 73268672, 73400128, 73530944, -73662272, 73793344, 73924544, 74055104, 74185792, 74316992, 74448832, -74579392, 74710976, 74841664, 74972864, 75102784, 75233344, 75364544, -75497024, 75627584, 75759296, 75890624, 76021696, 76152256, 76283072, -76414144, 76545856, 76676672, 76806976, 76937792, 77070016, 77200832, -77331392, 77462464, 77593664, 77725376, 77856448, 77987776, 78118336, -78249664, 78380992, 78511424, 78642496, 78773056, 78905152, 79033664, -79166656, 79297472, 79429568, 79560512, 79690816, 79822784, 79953472, -80084672, 80214208, 80346944, 80477632, 80608576, 80740288, 80870848, -81002048, 81133504, 81264448, 81395648, 81525952, 81657536, 81786304, -81919808, 82050112, 82181312, 82311616, 82443968, 82573376, 82705984, -82835776, 82967744, 83096768, 83230528, 83359552, 83491264, 83622464, -83753536, 83886016, 84015296, 84147776, 84277184, 84409792, 84540608, -84672064, 84803008, 84934336, 85065152, 85193792, 85326784, 85458496, -85589312, 85721024, 85851968, 85982656, 86112448, 86244416, 86370112, -86506688, 86637632, 86769344, 86900672, 87031744, 87162304, 87293632, -87424576, 87555392, 87687104, 87816896, 87947968, 88079168, 88211264, -88341824, 88473152, 88603712, 88735424, 88862912, 88996672, 89128384, -89259712, 89390272, 89521984, 89652544, 89783872, 89914816, 90045376, -90177088, 90307904, 90438848, 90569152, 90700096, 90832832, 90963776, -91093696, 91223744, 91356992, 91486784, 91618496, 91749824, 91880384, -92012224, 92143552, 92273344, 92405696, 92536768, 92666432, 92798912, -92926016, 93060544, 93192128, 93322816, 93453632, 93583936, 93715136, -93845056, 93977792, 94109504, 94240448, 94371776, 94501184, 94632896, -94764224, 94895552, 95023424, 95158208, 95287744, 95420224, 95550016, -95681216, 95811904, 95943872, 96075328, 96203584, 96337856, 96468544, -96599744, 96731072, 96860992, 96992576, 97124288, 97254848, 97385536, -97517248, 97647808, 97779392, 97910464, 98041408, 98172608, 98303168, -98434496, 98565568, 98696768, 98827328, 98958784, 99089728, 99220928, -99352384, 99482816, 99614272, 99745472, 99876416, 100007104, -100138048, 100267072, 100401088, 100529984, 100662592, 100791872, -100925248, 101056064, 101187392, 101317952, 101449408, 101580608, -101711296, 101841728, 101973824, 102104896, 102235712, 102366016, -102498112, 102628672, 102760384, 102890432, 103021888, 103153472, -103284032, 103415744, 103545152, 103677248, 103808576, 103939648, -104070976, 104201792, 104332736, 104462528, 104594752, 104725952, -104854592, 104988608, 105118912, 105247808, 105381184, 105511232, -105643072, 105774784, 105903296, 106037056, 106167872, 106298944, -106429504, 106561472, 106691392, 106822592, 106954304, 107085376, -107216576, 107346368, 107478464, 107609792, 107739712, 107872192, -108003136, 108131392, 108265408, 108396224, 108527168, 108657344, -108789568, 108920384, 109049792, 109182272, 109312576, 109444928, -109572928, 109706944, 109837888, 109969088, 110099648, 110230976, -110362432, 110492992, 110624704, 110755264, 110886208, 111017408, -111148864, 111279296, 111410752, 111541952, 111673024, 111803456, -111933632, 112066496, 112196416, 112328512, 112457792, 112590784, -112715968, 112852672, 112983616, 113114944, 113244224, 113376448, -113505472, 113639104, 113770304, 113901376, 114031552, 114163264, -114294592, 114425536, 114556864, 114687424, 114818624, 114948544, -115080512, 115212224, 115343296, 115473472, 115605184, 115736128, -115867072, 115997248, 116128576, 116260288, 116391488, 116522944, -116652992, 116784704, 116915648, 117046208, 117178304, 117308608, -117440192, 117569728, 117701824, 117833024, 117964096, 118094656, -118225984, 118357312, 118489024, 118617536, 118749632, 118882112, -119012416, 119144384, 119275328, 119406016, 119537344, 119668672, -119798464, 119928896, 120061376, 120192832, 120321728, 120454336, -120584512, 120716608, 120848192, 120979136, 121109056, 121241408, -121372352, 121502912, 121634752, 121764416, 121895744, 122027072, -122157632, 122289088, 122421184, 122550592, 122682944, 122813888, -122945344, 123075776, 123207488, 123338048, 123468736, 123600704, -123731264, 123861952, 123993664, 124124608, 124256192, 124386368, -124518208, 124649024, 124778048, 124911296, 125041088, 125173696, -125303744, 125432896, 125566912, 125696576, 125829056, 125958592, -126090304, 126221248, 126352832, 126483776, 126615232, 126746432, -126876608, 127008704, 127139392, 127270336, 127401152, 127532224, -127663552, 127794752, 127925696, 128055232, 128188096, 128319424, -128449856, 128581312, 128712256, 128843584, 128973632, 129103808, -129236288, 129365696, 129498944, 129629888, 129760832, 129892288, -130023104, 130154048, 130283968, 130416448, 130547008, 130678336, -130807616, 130939456, 131071552, 131202112, 131331776, 131464384, -131594048, 131727296, 131858368, 131987392, 132120256, 132250816, -132382528, 132513728, 132644672, 132774976, 132905792, 133038016, -133168832, 133299392, 133429312, 133562048, 133692992, 133823296, -133954624, 134086336, 134217152, 134348608, 134479808, 134607296, -134741056, 134872384, 135002944, 135134144, 135265472, 135396544, -135527872, 135659072, 135787712, 135921472, 136052416, 136182848, -136313792, 136444864, 136576448, 136707904, 136837952, 136970048, -137099584, 137232064, 137363392, 137494208, 137625536, 137755712, -137887424, 138018368, 138149824, 138280256, 138411584, 138539584, -138672832, 138804928, 138936128, 139066688, 139196864, 139328704, -139460032, 139590208, 139721024, 139852864, 139984576, 140115776, -140245696, 140376512, 140508352, 140640064, 140769856, 140902336, -141032768, 141162688, 141294016, 141426496, 141556544, 141687488, -141819584, 141949888, 142080448, 142212544, 142342336, 142474432, -142606144, 142736192, 142868288, 142997824, 143129408, 143258944, -143392448, 143523136, 143653696, 143785024, 143916992, 144045632, -144177856, 144309184, 144440768, 144570688, 144701888, 144832448, -144965056, 145096384, 145227584, 145358656, 145489856, 145620928, -145751488, 145883072, 146011456, 146144704, 146275264, 146407232, -146538176, 146668736, 146800448, 146931392, 147062336, 147193664, -147324224, 147455936, 147586624, 147717056, 147848768, 147979456, -148110784, 148242368, 148373312, 148503232, 148635584, 148766144, -148897088, 149028416, 149159488, 149290688, 149420224, 149551552, -149683136, 149814976, 149943616, 150076352, 150208064, 150338624, -150470464, 150600256, 150732224, 150862784, 150993088, 151125952, -151254976, 151388096, 151519168, 151649728, 151778752, 151911104, -152042944, 152174144, 152304704, 152435648, 152567488, 152698816, -152828992, 152960576, 153091648, 153222976, 153353792, 153484096, -153616192, 153747008, 153878336, 154008256, 154139968, 154270912, -154402624, 154533824, 154663616, 154795712, 154926272, 155057984, -155188928, 155319872, 155450816, 155580608, 155712064, 155843392, -155971136, 156106688, 156237376, 156367424, 156499264, 156630976, -156761536, 156892352, 157024064, 157155008, 157284416, 157415872, -157545536, 157677248, 157810496, 157938112, 158071744, 158203328, -158334656, 158464832, 158596288, 158727616, 158858048, 158988992, -159121216, 159252416, 159381568, 159513152, 159645632, 159776192, -159906496, 160038464, 160169536, 160300352, 160430656, 160563008, -160693952, 160822208, 160956352, 161086784, 161217344, 161349184, -161480512, 161611456, 161742272, 161873216, 162002752, 162135872, -162266432, 162397888, 162529216, 162660032, 162790976, 162922048, -163052096, 163184576, 163314752, 163446592, 163577408, 163707968, -163839296, 163969984, 164100928, 164233024, 164364224, 164494912, -164625856, 164756672, 164887616, 165019072, 165150016, 165280064, -165412672, 165543104, 165674944, 165805888, 165936832, 166067648, -166198336, 166330048, 166461248, 166591552, 166722496, 166854208, -166985408, 167116736, 167246656, 167378368, 167508416, 167641024, -167771584, 167903168, 168034112, 168164032, 168295744, 168427456, -168557632, 168688448, 168819136, 168951616, 169082176, 169213504, -169344832, 169475648, 169605952, 169738048, 169866304, 169999552, -170131264, 170262464, 170393536, 170524352, 170655424, 170782016, -170917696, 171048896, 171179072, 171310784, 171439936, 171573184, -171702976, 171835072, 171966272, 172097216, 172228288, 172359232, -172489664, 172621376, 172747712, 172883264, 173014208, 173144512, -173275072, 173407424, 173539136, 173669696, 173800768, 173931712, -174063424, 174193472, 174325696, 174455744, 174586816, 174718912, -174849728, 174977728, 175109696, 175242688, 175374272, 175504832, -175636288, 175765696, 175898432, 176028992, 176159936, 176291264, -176422592, 176552512, 176684864, 176815424, 176946496, 177076544, -177209152, 177340096, 177470528, 177600704, 177731648, 177864256, -177994816, 178126528, 178257472, 178387648, 178518464, 178650176, -178781888, 178912064, 179044288, 179174848, 179305024, 179436736, -179568448, 179698496, 179830208, 179960512, 180092608, 180223808, -180354752, 180485696, 180617152, 180748096, 180877504, 181009984, -181139264, 181272512, 181402688, 181532608, 181663168, 181795136, -181926592, 182057536, 182190016, 182320192, 182451904, 182582336, -182713792, 182843072, 182976064, 183107264, 183237056, 183368384, -183494848, 183631424, 183762752, 183893824, 184024768, 184154816, -184286656, 184417984, 184548928, 184680128, 184810816, 184941248, -185072704, 185203904, 185335616, 185465408, 185596352, 185727296, -185859904, 185989696, 186121664, 186252992, 186383552, 186514112, -186645952, 186777152, 186907328, 187037504, 187170112, 187301824, -187429184, 187562048, 187693504, 187825472, 187957184, 188087104, -188218304, 188349376, 188481344, 188609728, 188743616, 188874304, -189005248, 189136448, 189265088, 189396544, 189528128, 189660992, -189791936, 189923264, 190054208, 190182848, 190315072, 190447424, -190577984, 190709312, 190840768, 190971328, 191102656, 191233472, -191364032, 191495872, 191626816, 191758016, 191888192, 192020288, -192148928, 192282176, 192413504, 192542528, 192674752, 192805952, -192937792, 193068608, 193198912, 193330496, 193462208, 193592384, -193723456, 193854272, 193985984, 194116672, 194247232, 194379712, -194508352, 194641856, 194772544, 194900672, 195035072, 195166016, -195296704, 195428032, 195558592, 195690304, 195818176, 195952576, -196083392, 196214336, 196345792, 196476736, 196607552, 196739008, -196869952, 197000768, 197130688, 197262784, 197394368, 197523904, -197656384, 197787584, 197916608, 198049472, 198180544, 198310208, -198442432, 198573632, 198705088, 198834368, 198967232, 199097792, -199228352, 199360192, 199491392, 199621696, 199751744, 199883968, -200014016, 200146624, 200276672, 200408128, 200540096, 200671168, -200801984, 200933312, 201062464, 201194944, 201326144, 201457472, -201588544, 201719744, 201850816, 201981632, 202111552, 202244032, -202374464, 202505152, 202636352, 202767808, 202898368, 203030336, -203159872, 203292608, 203423296, 203553472, 203685824, 203816896, -203947712, 204078272, 204208192, 204341056, 204472256, 204603328, -204733888, 204864448, 204996544, 205125568, 205258304, 205388864, -205517632, 205650112, 205782208, 205913536, 206044736, 206176192, -206307008, 206434496, 206569024, 206700224, 206831168, 206961856, -207093056, 207223616, 207355328, 207486784, 207616832, 207749056, -207879104, 208010048, 208141888, 208273216, 208404032, 208534336, -208666048, 208796864, 208927424, 209059264, 209189824, 209321792, -209451584, 209582656, 209715136, 209845568, 209976896, 210106432, -210239296, 210370112, 210501568, 210630976, 210763712, 210894272, -211024832, 211156672, 211287616, 211418176, 211549376, 211679296, -211812032, 211942592, 212074432, 212204864, 212334016, 212467648, -212597824, 212727616, 212860352, 212991424, 213120832, 213253952, -213385024, 213515584, 213645632, 213777728, 213909184, 214040128, -214170688, 214302656, 214433728, 214564544, 214695232, 214826048, -214956992, 215089088, 215219776, 215350592, 215482304, 215613248, -215743552, 215874752, 216005312, 216137024, 216267328, 216399296, -216530752, 216661696, 216790592, 216923968, 217054528, 217183168, -217316672, 217448128, 217579072, 217709504, 217838912, 217972672, -218102848, 218233024, 218364736, 218496832, 218627776, 218759104, -218888896, 219021248, 219151936, 219281728, 219413056, 219545024, -219675968, 219807296, 219938624, 220069312, 220200128, 220331456, -220461632, 220592704, 220725184, 220855744, 220987072, 221117888, -221249216, 221378368, 221510336, 221642048, 221772736, 221904832, -222031808, 222166976, 222297536, 222428992, 222559936, 222690368, -222820672, 222953152, 223083968, 223213376, 223345984, 223476928, -223608512, 223738688, 223869376, 224001472, 224132672, 224262848, -224394944, 224524864, 224657344, 224788288, 224919488, 225050432, -225181504, 225312704, 225443776, 225574592, 225704768, 225834176, -225966784, 226097216, 226229824, 226360384, 226491712, 226623424, -226754368, 226885312, 227015104, 227147456, 227278528, 227409472, -227539904, 227669696, 227802944, 227932352, 228065216, 228196288, -228326464, 228457792, 228588736, 228720064, 228850112, 228981056, -229113152, 229243328, 229375936, 229505344, 229636928, 229769152, -229894976, 230030272, 230162368, 230292416, 230424512, 230553152, -230684864, 230816704, 230948416, 231079616, 231210944, 231342016, -231472448, 231603776, 231733952, 231866176, 231996736, 232127296, -232259392, 232388672, 232521664, 232652608, 232782272, 232914496, -233043904, 233175616, 233306816, 233438528, 233569984, 233699776, -233830592, 233962688, 234092224, 234221888, 234353984, 234485312, -234618304, 234749888, 234880832, 235011776, 235142464, 235274048, -235403456, 235535936, 235667392, 235797568, 235928768, 236057152, -236190272, 236322752, 236453312, 236583616, 236715712, 236846528, -236976448, 237108544, 237239104, 237371072, 237501632, 237630784, -237764416, 237895232, 238026688, 238157632, 238286912, 238419392, -238548032, 238681024, 238812608, 238941632, 239075008, 239206336, -239335232, 239466944, 239599168, 239730496, 239861312, 239992384, -240122816, 240254656, 240385856, 240516928, 240647872, 240779072, -240909632, 241040704, 241171904, 241302848, 241433408, 241565248, -241696192, 241825984, 241958848, 242088256, 242220224, 242352064, -242481856, 242611648, 242744896, 242876224, 243005632, 243138496, -243268672, 243400384, 243531712, 243662656, 243793856, 243924544, -244054592, 244187072, 244316608, 244448704, 244580032, 244710976, -244841536, 244972864, 245104448, 245233984, 245365312, 245497792, -245628736, 245759936, 245889856, 246021056, 246152512, 246284224, -246415168, 246545344, 246675904, 246808384, 246939584, 247070144, -247199552, 247331648, 247463872, 247593536, 247726016, 247857088, -247987648, 248116928, 248249536, 248380736, 248512064, 248643008, -248773312, 248901056, 249036608, 249167552, 249298624, 249429184, -249560512, 249692096, 249822784, 249954112, 250085312, 250215488, -250345792, 250478528, 250608704, 250739264, 250870976, 251002816, -251133632, 251263552, 251395136, 251523904, 251657792, 251789248, -251919424, 252051392, 252182464, 252313408, 252444224, 252575552, -252706624, 252836032, 252968512, 253099712, 253227584, 253361728, -253493056, 253623488, 253754432, 253885504, 254017216, 254148032, -254279488, 254410432, 254541376, 254672576, 254803264, 254933824, -255065792, 255196736, 255326528, 255458752, 255589952, 255721408, -255851072, 255983296, 256114624, 256244416, 256374208, 256507712, -256636096, 256768832, 256900544, 257031616, 257162176, 257294272, -257424448, 257555776, 257686976, 257818432, 257949632, 258079552, -258211136, 258342464, 258473408, 258603712, 258734656, 258867008, -258996544, 259127744, 259260224, 259391296, 259522112, 259651904, -259784384, 259915328, 260045888, 260175424, 260308544, 260438336, -260570944, 260700992, 260832448, 260963776, 261092672, 261226304, -261356864, 261487936, 261619648, 261750592, 261879872, 262011968, -262143424, 262274752, 262404416, 262537024, 262667968, 262799296, -262928704, 263061184, 263191744, 263322944, 263454656, 263585216, -263716672, 263847872, 263978944, 264108608, 264241088, 264371648, -264501184, 264632768, 264764096, 264895936, 265024576, 265158464, -265287488, 265418432, 265550528, 265681216, 265813312, 265943488, -266075968, 266206144, 266337728, 266468032, 266600384, 266731072, -266862272, 266993344, 267124288, 267255616, 267386432, 267516992, -267648704, 267777728, 267910592, 268040512, 268172096, 268302784, -268435264, 268566208, 268696256, 268828096, 268959296, 269090368, -269221312, 269352256, 269482688, 269614784, 269745856, 269876416, -270007616, 270139328, 270270272, 270401216, 270531904, 270663616, -270791744, 270924736, 271056832, 271186112, 271317184, 271449536, -271580992, 271711936, 271843136, 271973056, 272105408, 272236352, -272367296, 272498368, 272629568, 272759488, 272891456, 273022784, -273153856, 273284672, 273415616, 273547072, 273677632, 273808448, -273937088, 274071488, 274200896, 274332992, 274463296, 274595392, -274726208, 274857536, 274988992, 275118656, 275250496, 275382208, -275513024, 275643968, 275775296, 275906368, 276037184, 276167872, -276297664, 276429376, 276560576, 276692672, 276822976, 276955072, -277085632, 277216832, 277347008, 277478848, 277609664, 277740992, -277868608, 278002624, 278134336, 278265536, 278395328, 278526784, -278657728, 278789824, 278921152, 279052096, 279182912, 279313088, -279443776, 279576256, 279706048, 279838528, 279969728, 280099648, -280230976, 280361408, 280493632, 280622528, 280755392, 280887104, -281018176, 281147968, 281278912, 281411392, 281542592, 281673152, -281803712, 281935552, 282066496, 282197312, 282329024, 282458816, -282590272, 282720832, 282853184, 282983744, 283115072, 283246144, -283377344, 283508416, 283639744, 283770304, 283901504, 284032576, -284163136, 284294848, 284426176, 284556992, 284687296, 284819264, -284950208, 285081536] -``` \ No newline at end of file diff --git a/Ethash_revision_11.md b/Ethash_revision_11.md deleted file mode 100644 index aa82ee5bb..000000000 --- a/Ethash_revision_11.md +++ /dev/null @@ -1,249 +0,0 @@ ---- -name: Ethash Revision 11 -category: ---- - -**This spec is REVISION 11. Whenever you substantively (ie. not clarifications) update the algorithm, please update the revision number in this sentence. Also, in all implementations please include a spec revision number** - -Ethash is the planned PoW algorithm for Ethereum 1.0. It is the latest version of Dagger-Hashimoto, although it can no longer appropriately be called that since many of the original features of both algorithms have been drastically changed in the last month of research and development. See [https://github.com/ethereum/wiki/wiki/Dagger-Hashimoto](https://github.com/ethereum/wiki/wiki/Dagger-Hashimoto) for the original version. - -The specification for the algorithm is written in python to give a balance between clarity and exactness. If you are interested in actually running the spec as code, then you can; you simply need to install the `python_sha3` and `pyethereum` libraries, and add the following lines to your top of the file: - -```python -import sha3 - -# Assumes little endian bit ordering (same as Intel architectures) -def decode_int(s): - return int(s[::-1].encode('hex'), 16) if s else 0 - -def encode_int(s): - a = "%x" % s - return '' if s == 0 else ('0' * (len(a) % 2) + a).decode('hex')[::-1] - -def zpad(s, length): - return s + '\x00' * max(0, length - len(s)) - -# sha3 hash function, outputs 64 bytes -def sha3_512(x): - return sha3.sha3_512(x).digest() - -def sha3_256(x): - return sha3.sha3_256(x).digest() -``` - -### Goals - -Ethash is intended to satisfy the following goals: - -1. **IO saturation**: the algorithm should consume nearly the entire available memory access bandwidth (this is a strategy toward achieving ASIC resistance) -2. **Light client verifiability**: a light client should be able to verify a round of mining in under 0.01 seconds on a desktop in C, and under 1 second in Python or Javascript, with at most 32 MB of memory -3. **Light client slowdown**: the process of running the algorithm with a light client should be much slower than the process with a full client, to the point that the light client algorithm is not an economically viable route toward making an ASIC implementation. -4. **Light client fast startup**: a light client should be able to become fully operational and able to verify blocks within 40 seconds in Python or Javascript. - -The general route that the algorithm takes is as follows: - -1. There exists a `seed` which can be computed for each block by scanning through the block headers up until that point. -2. From the seed, one can compute a 32 MB pseudorandom `cache` -3. From the seed and cache, there exists a function `calc_dag_item(seed, cache, i)` which calculates the value of any element in a larger 1 GB dataset. The function for computing each element involves many elements in the cache. Miners are meant to store the 1 GB dataset in memory. -4. The actual algorithm is a loop that involves combining together many items from the DAG and taking a hash of the output. Each individual read from the DAG is 4KB wide in order to fetch a full page from memory. - -The large dataset is updated once every 1000 blocks, so the vast majority of a miner's effort will be reading the dataset, not making changes to it. The dataset also grows over time; it starts off at 1 GB and grows by about 345 MB per year. - -First, we define the parameters: - -```python -params = { - "cache_bytes": 33554432, # bytes in cache - "dag_bytes_init": 1073741824, # bytes in dag - "dag_bytes_growth": 131072, # growth per epoch (~345 MB per year) - "epoch_length": 1000, # blocks per epoch - "dag_parents": 64, # number of parents of each dag element - "cache_rounds": 2, # number of processing rounds in cache production - "mix_bytes": 4096, # width of mix - "accesses": 32, # number of accesses in hashimoto loop - "hash_bytes": 64 # hash length in bytes -} -``` - -### Cache Generation - -Now, we specify the function for producing a cache: - -```python -def mkcache(params, seed): - n = params["cache_bytes"] / params["hash_bytes"] - - # Sequentially produce the initial dataset - o = [sha3_512(seed)] - for i in range(1, n): - o.append(sha3_512(o[-1])) - - for _ in range(params["cache_rounds"]): - for i in range(n): - v = (decode_int(o[i]) % 2**64) % n - o[i] = sha3_512(o[(i-1+n)%n] + o[v]) - - return o -``` - -[Sergio2014]: http://www.hashcash.org/papers/memohash.pdf - -The cache production process involves first sequentially filling up 32 MB of memory, then performing two passes of Sergio Demian Lerner's *RandMemoHash* algorithm from [*Strict Memory Hard Hashing Functions* (2014)](http://www.hashcash.org/papers/memohash.pdf). The output is a set of 524288 64-byte values. - -### Pseudo Random Number Generation - -Now, we specify some auxiliary methods for running a variant of the [Blum Blum Shub](https://en.wikipedia.org/wiki/Blum_Blum_Shub) pseudorandom number generator on a 32-bit prime modulus; this is a very quick way of generating pseudorandom data. - -```python -# two safe primes approximately equal to 2**32 -P1 = 4294967087 -P2 = 4294963787 - -# Clamp a value to between the specified minimum and maximum -def clamp(minimum, x, maximum): - return max(minimum, min(maximum, x)) - -# Many steps of the BBS RNG in logtime -def quick_bbs(seed, i, P): - return pow(seed, pow(3, i, P-1), P) - -# One step of the BBS RNG -def step_bbs(n, P): - return (n * n * n) % P -``` - -When choosing a safe prime *p* for our random number generator, we wish to find ones where the [multiplicative order](http://en.wikipedia.org/wiki/Multiplicative_order) of 3 in ℤ/(*p* - 1) is *high*, since this determines the cycle length of the corresponding random number generator. The multiplicative order of 3 in ℤ/(4294967086) is 1073741771. Note that cryptographic security is NOT required of the RNG here; we only need it to provide values which are roughly even across the entire output space `[0 ... 2**32 - 1]` and can be relied on to pass the [Diehard Tests](http://en.wikipedia.org/wiki/Diehard_tests). - -This particular pseudo random number generator may exhibit bias when taking its output modulo a value which is not a prime, so we will choose our memory sizes in terms of primes in order to remove any bias. - -### Data aggregation function - -We use an algorithm inspired by the [FNV hash](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function) in order to combine large blocks of data together. This is essentially meant to be a non-associative substitute for XOR. - -```python -FNV_PRIME = 0x01000193 - -def fnv(a, b): - o = '' - for pos in range(0, len(a), 4): - v1 = decode_int(a[pos:pos+4]) - v2 = decode_int(b[pos:pos+4]) - o += zpad(encode_int((v1 * FNV_PRIME ^ v2) % 2**32), 4) - return o -``` - -### Full dataset calculation - -Each 64-byte item in the full 1 GB dataset is computed as follows: - -```python -def calc_dag_item(params, cache, i): - n = params["cache_bytes"] / params["hash_bytes"] - L = params["hash_bytes"] - rand_seed = clamp(2, decode_int(cache[0][:4]), P1 - 2) - rand = clamp(2, quick_bbs(rand_seed, i, P1), P2 - 2) - mix = cache[i % n] - for j in range(params["dag_parents"]): - mix_value = decode_int(mix[(j*4)%L: (j*4+3)%L]) - mix = fnv(mix, cache[(rand ^ mix_value) % n]) - rand = step_bbs(rand, P2) - return mix -``` - -Essentially, we use our RNG to generate a seed for the specific item, and use that as the seed for another RNG which picks 64 indices from the cache. We initialize a mix to equal the 512-bit big-endian representation of the index (the purpose of this is to make sure all of the entropy from the index, and not just the first 32 bytes as does the RNG, in computing the final DAG value), and then repeatedly run through random parts of the cache and use our aggregation function to combine the data together. - -### Main Loop - -Now, we specify the main "hashimoto"-like loop, where we aggregate data from the full dataset in order to produce our final value for a particular header and nonce: - -```python -def hashimoto(params, header, nonce, dagsize, dag_lookup): - L = params["mix_bytes"] - w = params["mix_bytes"] / params["hash_bytes"] - n = dagsize / params["hash_bytes"] - s = sha3_512(header + nonce) - mix = [s for _ in range(w)] - rand = clamp(2, decode_int(s[-4:]), P2 - 2) - for i in range(params["accesses"]): - mix_value = decode_int(mix[0][(i*4) % L: (i*4+3) % L]) - p = (rand ^ mix_value) % (n // w) * w - for j in range(w): - mix[j] = fnv(mix[j], dag_lookup(p + j)) - rand = step_bbs(rand, P2) - return sha3_256(s+sha3_256(s + ''.join(mix))) - -def hashimoto_light(params, cache, header, nonce, dagsize): - return hashimoto(params, header, nonce, dagsize, lambda x: calc_dag_item(params, cache, x)) - -def hashimoto_full(params, dag, header, nonce): - return hashimoto(params, cache, header, nonce, len(dag), lambda x: dag[x]) -``` - -Essentially, we maintain a "mix" 4096 bytes wide, and repeatedly sequentially fetch 4096 bytes from the full dataset and use the `fnv` function to combine it with the mix. 4096 bytes of sequential access are used so that each round of the algorithm always fetches a full page from RAM, minimizing translation lookaside buffer misses which ASICs would theoretically be able to avoid. - -If the output of this algorithm is below the desired target, then the nonce is valid. Note that the double application of `sha3_256` ensures that there exists an intermediate nonce which can be provided to prove that at least a small amount of work was done; this quick outer PoW verification can be used for anti-DDoS purposes. It also serves to provide statistical assurance that the result is an unbiased, 256 bit number. - -### Mining - -The mining algorithm is defined as follows: - -```python -def mine(params, dag, header, difficulty): - from random import randint - nonce = randint(0,2**64) - while decode_int(hashimoto_full(params, dag, header, nonce)) < difficulty: - nonce += 1 - nonce %= 2**64 - return nonce -``` - -### Defining the seed - -In order to compute the seed for a given block, we use the following algorithm: - -```python - def get_seedset(params, block): - if block.number == 0: - return ('\x42' * 32, '\x43' * 32) - elif (block.number % params["epoch_length"] == 0): - x, y = get_seedset(params, block.parent) - if (block.number // params["epoch_length"]) % 2: - y = sha3_256(y + block.prevhash) - else: - x = sha3_256(x + block.prevhash) - return (x, y) - else: - return get_seedset(params, block.parent) -``` - -Note the this function outputs two seeds. During even-numbered epochs, the PoW uses the first seed, and during odd-numbered epochs the PoW uses the second seed; this allows a miner to rebuild one DAG while simultaneously still using the other DAG, ensuring a smooth transition as the dataset gets updated. - -In order to compute the size of the dataset and the cache at a given block number, we use the following function: - -```python -def get_datasize(params, block): - datasize_in_bytes = params["dag_bytes_init"] + \ - params["dag_bytes_growth"] * (block.number // params["epoch_length"]) - while not isprime(datasize_in_bytes // params["mix_bytes"]): - datasize_in_bytes -= params["mix_bytes"] - return datasize_in_bytes - -def get_cachesize(params, block): - datasize_in_bytes = get_datasize(params, block) - cachesize_in_bytes = (datasize_in_bytes // 32) - while not isprime(cachesize_in_bytes // params["hash_bytes"]): - cachesize_in_bytes -= params["hash_bytes"] - return cachesize_in_bytes -``` - -Where `isprime` is of course: - -```python - def isprime(n): - for i in range(2, int(n ** 0.5 + 1)): - if n % i == 0: - return False - return True -``` - -For an optimization, one can add the line `if pow(2, n, n) != 2: return False` as an initial check, or use the Sieve of Erasthothenes to precompute the list of primes that the dataset will increase to all at once. Essentially, we are keeping the size of the dataset to always be equal to the highest prime below a linearly growing function, so on average in the long term the dataset will grow roughly linearly. \ No newline at end of file diff --git a/Ethereum-Contract-ABI.md b/Ethereum-Contract-ABI.md deleted file mode 100644 index 1bec785cd..000000000 --- a/Ethereum-Contract-ABI.md +++ /dev/null @@ -1,383 +0,0 @@ ---- -name: Ethereum Contract ABI -category: ---- - -# Functions - -## Basic design - -We assume the ABI is strongly typed, known at compilation time and static. No introspection mechanism will be provided. We assert that all contracts will have the interface definitions of any contracts they call available at compile-time. - -This specification does not address contracts whose interface is dynamic or otherwise known only at run-time. Should these cases become important they can be adequately handled as facilities built within the Ethereum ecosystem. - -## Function Selector - -The first four bytes of the call data for a function call specifies the function to be called. It is the -first (left, high-order in big-endian) four bytes of the Keccak (SHA-3) hash of the signature of the function. The signature is defined as the canonical expression of the basic prototype, i.e. -the function name with the parenthesised list of parameter types. Parameter types are split by a single comma - no spaces are used. - -## Argument Encoding - -Starting from the fifth byte, the encoded arguments follow. This encoding is also used in other places, e.g. the return values and also event arguments are encoded in the same way, without the four bytes specifying the function. - -### Types - -The following elementary types exist: -- `uint`: unsigned integer type of `N` bits, `0 < N <= 256`, `N % 8 == 0`. e.g. `uint32`, `uint8`, `uint256`. -- `int`: two's complement signed integer type of `N` bits, `0 < N <= 256`, `N % 8 == 0`. -- `address`: equivalent to `bytes20`, except for the assumed interpretation and language typing. -- `uint`, `int`: synonyms for `uint256`, `int256` respectively (not to be used for computing the function selector). -- `bool`: equivalent to `uint8` restricted to the values 0 and 1 -- `realx`: fixed-point signed number of `N+M` bits, `0 < N + M <= 256`, `N % 8 == M % 8 == 0`. Corresponds to the int256 equivalent binary value divided by `2^M`. -- `urealx`: unsigned variant of `realx`. -- `real`, `ureal`: synonyms for `real128x128`, `ureal128x128` respectively (not to be used for computing the function selector). -- `bytes`: binary type of `N` bytes, `N >= 0`. - -The following (fixed-size) array type exists: -- `[N]`: a fixed-length array of the given fixed-length type. - -The following non-fixed-size types exist: -- `bytes`: dynamic sized byte sequence. -- `string`: dynamic sized unicode string assumed to be UTF-8 encoded. -- `[]`: a variable-length array of the given fixed-length type. - -### Formal Specification of the Encoding - -We will now formally specify the encoding, such that it will have the following -properties, which are especially useful if some arguments are nested arrays: - -**Properties:** - -1. The number of reads necessary to access a value is at most the depth of the -value inside the argument array structure, i.e. four reads are needed to -retrieve `a_i[k][l][r]`. In a previous version of the ABI, the number of reads scaled -linearly with the total number of dynamic parameters in the worst case. - -2. The data of a variable or array element is not interleaved with other data -and it is relocatable, i.e. it only uses relative "addresses" - -We distinguish static and dynamic types. Static types are encoded in-place and dynamic types are encoded at a separately allocated location after the current block. - -**Definition:** The following types are called "dynamic": -* `bytes` -* `string` -* `T[]` for any `T` -* `T[k]` for any dynamic `T` and any `k > 0` - -All other types are called "static". - -**Definition:** `len(a)` is the number of bytes in a binary string `a`. -The type of `len(a)` is assumed to be `uint256`. - -We define `enc`, the actual encoding, as a mapping of values of the ABI types to binary strings such -that `len(enc(X))` depends on the value of `X` if and only if the type of `X` -is dynamic. - -**Definition:** For any ABI value `X`, we recursively define `enc(X)`, depending -on the type of `X` being - -- `T[k]` for any `T` and `k`: - - `enc(X) = head(X[0]) ... head(X[k-1]) tail(X[0]) ... tail(X[k-1])` - - where `head` and `tail` are defined for `X[i]` being of a static type as - `head(X[i]) = enc(X[i])` and `tail(X[i]) = ""` (the empty string) - and as - `head(X[i]) = enc(len(head(X[0]) ... head(X[k-1]) tail(X[0]) ... tail(X[i-1])))` - `tail(X[i]) = enc(X[i])` - otherwise. - - Note that in the dynamic case, `head(X[i])` is well-defined since the lengths of - the head parts only depend on the types and not the values. Its value is the offset - of the beginning of `tail(X[i])` relative to the start of `enc(X)`. - -- `T[]` where `X` has `k` elements (`k` is assumed to be of type `uint256`): - - `enc(X) = enc(k) enc([X[1], ..., X[k]])` - - i.e. it is encoded as if it were an array of static size `k`, prefixed with - the number of elements. - -- `bytes`, of length `k` (which is assumed to be of type `uint256`): - - `enc(X) = enc(k) pad_right(X)`, i.e. the number of bytes is encoded as a - `uint256` followed by the actual value of `X` as a byte sequence, followed by - the minimum number of zero-bytes such that `len(enc(X))` is a multiple of 32. - -- `string`: - - `enc(X) = enc(enc_utf8(X))`, i.e. `X` is utf-8 encoded and this value is interpreted as of `bytes` type and encoded further. Note that the length used in this subsequent encoding is the number of bytes of the utf-8 encoded string, not its number of characters. - -- `uint`: `enc(X)` is the big-endian encoding of `X`, padded on the higher-order (left) side with zero-bytes such that the length is a multiple of 32 bytes. -- `address`: as in the `uint160` case -- `int`: `enc(X)` is the big-endian two's complement encoding of `X`, padded on the higher-oder (left) side with `0xff` for negative `X` and with zero bytes for positive `X` such that the length is a multiple of 32 bytes. -- `bool`: as in the `uint8` case, where `1` is used for `true` and `0` for `false` -- `realx`: `enc(X)` is `enc(X * 2**M)` where `X * 2**M` is interpreted as a `int256`. -- `real`: as in the `real128x128` case -- `urealx`: `enc(X)` is `enc(X * 2**M)` where `X * 2**M` is interpreted as a `uint256`. -- `ureal`: as in the `ureal128x128` case -- `bytes`: `enc(X)` is the sequence of bytes in `X` padded with zero-bytes to a length of 32. - -Note that for any `X`, `len(enc(X))` is a multiple of 32. - -## Function Selector and Argument Encoding - -All in all, a call to the function `f` with parameters `a_1, ..., a_n` is encoded as - - `function_selector(f) enc([a_1, ..., a_n])` - -and the return values `v_1, ..., v_k` of `f` are encoded as - - `enc([v_1, ..., v_k])` - -where the types of `[a_1, ..., a_n]` and `[v_1, ..., v_k]` are assumed to be -fixed-size arrays of length `n` and `k`, respectively. Note that strictly, -`[a_1, ..., a_n]` can be an "array" with elements of different types, but the -encoding is still well-defined as the assumed common type `T` (above) is not -actually used. - -## Examples - -Given the contract: - -```js -contract Foo { - function bar(real[2] xy) {} - function baz(uint32 x, bool y) returns (bool r) { r = x > 32 || y; } - function sam(bytes name, bool z, uint[] data) {} -} -``` - -Thus for our `Foo` example if we wanted to call `baz` with the parameters `69` and `true`, we would pass 68 bytes total, which can be broken down into: - -- `0xcdcd77c0`: the Method ID. This is derived as the first 4 bytes of the Keccak hash of the ASCII form of the signature `baz(uint32,bool)`. -- `0x0000000000000000000000000000000000000000000000000000000000000045`: the first parameter, a uint32 value `69` padded to 32 bytes -- `0x0000000000000000000000000000000000000000000000000000000000000001`: the second parameter - boolean `true`, padded to 32 bytes - -In total: -``` -0xcdcd77c000000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000001 -``` -It returns a single `bool`. If, for example, it were to return `false`, its output would be the single byte array `0x0000000000000000000000000000000000000000000000000000000000000000`, a single bool. - -If we wanted to call `bar` with the argument `[2.125, 8.5]`, we would pass 68 bytes total, broken down into: -- `0x3e279860`: the Method ID. This is derived from the signature `bar(real128x128[2])`. Note that `real` is substituted for its canonical representation `real128x128`. -- `0x0000000000000000000000000000000240000000000000000000000000000000`: the first part of the first parameter, a real128x128 value `2.125`. -- `0x0000000000000000000000000000000880000000000000000000000000000000`: the first part of the first parameter, a real128x128 value `8.5`. - -In total: -``` -0x3e27986000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000880000000000000000000000000000000 -``` - -If we wanted to call `sam` with the arguments `"dave"`, `true` and `[1,2,3]`, we would pass 292 bytes total, broken down into: -- `0x8FF261B0`: the Method ID. This is derived from the signature `sam(bytes,bool,uint256[])`. Note that `uint` is substituted for its canonical representation `uint256`. -- `0x0000000000000000000000000000000000000000000000000000000000000060`: the location of the data part of the first parameter (dynamic type), measured in bytes from the start of the arguments block. In this case, `0x60`. -- `0x0000000000000000000000000000000000000000000000000000000000000001`: the second parameter: boolean true. -- `0x00000000000000000000000000000000000000000000000000000000000000c0`: the location of the data part of the third parameter (dynamic type), measured in bytes. In this case, `0xc0`. -- `0x0000000000000000000000000000000000000000000000000000000000000004`: the data part of the first argument, it starts with the length of the byte array in elements, in this case, 4. -- `0x6461766500000000000000000000000000000000000000000000000000000000`: the contents of the first argument: the UTF-8 (equal to ASCII in this case) encoding of `"dave"`, padded on the right to 32 bytes. -- `0x0000000000000000000000000000000000000000000000000000000000000003`: the data part of the third argument, it starts with the length of the array in elements, in this case, 3. -- `0x0000000000000000000000000000000000000000000000000000000000000001`: the first entry of the third parameter. -- `0x0000000000000000000000000000000000000000000000000000000000000002`: the second entry of the third parameter. -- `0x0000000000000000000000000000000000000000000000000000000000000003`: the third entry of the third parameter. - -In total: -``` -0x8FF261B00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003 -``` - - -### Use of Dynamic Types - -A call to a function with the signature `f(uint,uint32[],bytes10,bytes)` with values `(0x123, [0x456, 0x789], "1234567890", "Hello, world!")` is encoded in the following way: - -We take the first four bytes of `sha3("f(uint256,uint32[],bytes10,bytes)")`, i.e. `0x8be65246`. -Then we encode the head parts of all four arguments. For the static types `uint256` and `bytes10`, these are directly the values we want to pass, whereas for the dynamic types `uint32[]` and `bytes`, we use the offset in bytes to the start of their data area, measured from the start of the value encoding (i.e. not counting the first four bytes containing the hash of the function signature). These are: - - - `0x0000000000000000000000000000000000000000000000000000000000000123` (`0x123` padded to 32 bytes) - - `0x0000000000000000000000000000000000000000000000000000000000000080` (offset to start of data part of second parameter, 4*32 bytes, exactly the size of the head part) - - `0x3132333435363738393000000000000000000000000000000000000000000000` (`"1234567890"` padded to 32 bytes on the right) - - `0x00000000000000000000000000000000000000000000000000000000000000e0` (offset to start of data part of fourth parameter = offset to start of data part of first dynamic parameter + size of data part of first dynamic parameter = 4*32 + 3*32 (see below)) - -After this, the data part of the first dynamic argument, `[0x456, 0x789]` follows: - - - `0x0000000000000000000000000000000000000000000000000000000000000002` (number of elements of the array, 2) - - `0x0000000000000000000000000000000000000000000000000000000000000456` (first element) - - `0x0000000000000000000000000000000000000000000000000000000000000789` (second element) - -Finally, we encode the data part of the second dynamic argument, `"Hello, world!"`: - - - `0x000000000000000000000000000000000000000000000000000000000000000d` (number of elements (bytes in this case): 13) - - `0x48656c6c6f2c20776f726c642100000000000000000000000000000000000000` (`"Hello, world!"` padded to 32 bytes on the right) - -All together, the encoding is (spaces added for clarity): - -`0x8be65246 0000000000000000000000000000000000000000000000000000000000000123 0000000000000000000000000000000000000000000000000000000000000080 3132333435363738393000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000e0 0000000000000000000000000000000000000000000000000000000000000002 0000000000000000000000000000000000000000000000000000000000000456 0000000000000000000000000000000000000000000000000000000000000789 000000000000000000000000000000000000000000000000000000000000000d 48656c6c6f2c20776f726c642100000000000000000000000000000000000000` - - -# Events - -Events are an abstraction of the Ethereum logging/event-watching protocol. Log entries provide the contract's address, a series of up to four topics and some arbitrary length binary data. Events leverage the existing function ABI in order to interpret this (together with an interface spec) as a properly typed structure. - -Given an event name and series of event parameters, we split them into two sub-series: those which are indexed and those which are not. Those which are indexed, which may number up to 3, are used alongside the Keccak hash of the event signature to form the topics of the log entry. Those which as not indexed form the byte array of the event. - -In effect, a log entry using this ABI is described as: - -- `address`: the address of the contract (intrinsically provided by Ethereum); -- `topics[0]`: `keccak(EVENT_NAME+"("+EVENT_ARGS.map(canonical_type_of).join(",")+")")` (`canonical_type_of` is a function that simply returns the canonical type of a given argument, e.g. for `uint indexed foo`, it would return `uint256`). If the event is declared as `anonymous` the `topics[0]` is not generated; -- `topics[n]`: `EVENT_INDEXED_ARGS[n - 1]` (`EVENT_INDEXED_ARGS` is the series of `EVENT_ARGS` that are indexed); -- `data`: `abi_serialise(EVENT_NON_INDEXED_ARGS)` (`EVENT_NON_INDEXED_ARGS` is the series of `EVENT_ARGS` that are not indexed, `abi_serialise` is the ABI serialisation function used for returning a series of typed values from a function, as described above). - -# JSON - -The JSON format for a contract's interface is given by an array of function and/or event descriptions. A function description is a JSON object with the fields: - -- `type`: `"function"` or `"constructor"` (can be omitted, defaulting to function); -- `name`: the name of the function (only present for function types); -- `inputs`: an array of objects, each of which contains: -* `name`: the name of the parameter; -* `type`: the canonical type of the parameter. -- `outputs`: an array of objects similar to `inputs`, can be omitted. - -An event description is a JSON object with fairly similar fields: - -- `type`: always `"event"` -- `name`: the name of the event; -- `inputs`: an array of objects, each of which contains: -* `name`: the name of the parameter; -* `type`: the canonical type of the parameter. -* `indexed`: `true` if the field is part of the log's topics, `false` if it one of the log's data segment. -* `anonymous`: `true` if the event was declared as `anonymous`. - -For example, - -```js -contract Test { -function Test(){ b = 0x12345678901234567890123456789012; } -event Event(uint indexed a, bytes32 b) -event Event2(uint indexed a, bytes32 b) -function foo(uint a) { Event(a, b); } -bytes32 b; -} -``` - -would result in the JSON: - -```js -[{ -"type":"event", -"inputs": [{"name":"a","type":"uint256","indexed":true},{"name":"b","type":"bytes32","indexed":false}], -"name":"Event" -}, { -"type":"event", -"inputs": [{"name":"a","type":"uint256","indexed":true},{"name":"b","type":"bytes32","indexed":false}], -"name":"Event2" -}, { -"type":"event", -"inputs": [{"name":"a","type":"uint256","indexed":true},{"name":"b","type":"bytes32","indexed":false}], -"name":"Event2" -}, { -"type":"function", -"inputs": [{"name":"a","type":"uint256"}], -"name":"foo", -"outputs": [] -}] -``` - -# Example Javascript Usage - -```js -var Test = eth.contract( -[{ -"type":"event", -"inputs": [{"name":"a","type":"uint256","indexed":true},{"name":"b","type":"bytes32","indexed":false}], -"name":"Event" -}, { -"type":"event", -"inputs": [{"name":"a","type":"uint256","indexed":true},{"name":"b","type":"bytes32","indexed":false}], -"name":"Event2" -}, { -"type":"function", -"inputs": [{"name":"a","type":"uint256"}], -"name":"foo", -"outputs": [] -}]); -var theTest = new Test(addrTest); - -// examples of usage: -// every log entry ("event") coming from theTest (i.e. Event & Event2): -var f0 = eth.filter(theTest); -// just log entries ("events") of type "Event" coming from theTest: -var f1 = eth.filter(theTest.Event); -// also written as -var f1 = theTest.Event(); -// just log entries ("events") of type "Event" and "Event2" coming from theTest: -var f2 = eth.filter([theTest.Event, theTest.Event2]); -// just log entries ("events") of type "Event" coming from theTest with indexed parameter 'a' equal to 69: -var f3 = eth.filter(theTest.Event, {'a': 69}); -// also written as -var f3 = theTest.Event({'a': 69}); -// just log entries ("events") of type "Event" coming from theTest with indexed parameter 'a' equal to 69 or 42: -var f4 = eth.filter(theTest.Event, {'a': [69, 42]}); -// also written as -var f4 = theTest.Event({'a': [69, 42]}); - -// options may also be supplied as a second parameter with `earliest`, `latest`, `offset` and `max`, as defined for `eth.filter`. -var options = { 'max': 100 }; -var f4 = theTest.Event({'a': [69, 42]}, options); - -var trigger; -f4.watch(trigger); - -// call foo to make an Event: -theTest.foo(69); - -// would call trigger like: -//trigger(theTest.Event, {'a': 69, 'b': '0x12345678901234567890123456789012'}, n); -// where n is the block number that the event triggered in. -``` - -Implementation: - -```js -// e.g. f4 would be similar to: -web3.eth.filter({'max': 100, 'address': theTest.address, 'topics': [ [69, 42] ]}); -// except that the resultant data would need to be converted from the basic log entry format like: -{ - 'address': theTest.address, - 'topics': [web3.sha3("Event(uint256,bytes32)"), 0x00...0045 /* 69 in hex format */], - 'data': '0x12345678901234567890123456789012', - 'number': n -} -// into data good for the trigger, specifically the three fields: - Test.Event // derivable from the first topic - {'a': 69, 'b': '0x12345678901234567890123456789012'} // derivable from the 'indexed' bool in the interface, the later 'topics' and the 'data' - n // from the 'number' -``` - -Event result: -```js -[ { - 'event': Test.Event, - 'args': {'a': 69, 'b': '0x12345678901234567890123456789012'}, - 'number': n - }, - { ... - } ... -] -``` - -### JUST DONE! [develop branch] -**NOTE: THIS IS OLD - IGNORE IT unless reading for historical purposes** - -- Internal LogFilter, log-entry matching mechanism and eth_installFilter needs to support matching multiple values (OR semantics) *per* topic index (at present it will only match topics with AND semantics and set-inclusion, not per-index). - -i.e. at present you can only ask for each of a number of given topic values to be matched throughout each topic: - -- `topics: [69, 42, "Gav"]` would match against logs with 3 topics `[42, 69, "Gav"]`, `["Gav", 69, 42]` but **not** against logs with topics `[42, 70, "Gav"]`. - -we need to be able to provide one of a number of topic values, and, each of these options for each topic index: - -- `topics: [[69, 42], [] /* anything */, "Gav"]` should match against logs with 3 topics `[42, 69, "Gav"]`, `[42, 70, "Gav"]` but **not** against `["Gav", 69, 42]`. \ No newline at end of file diff --git a/Ethereum-Development-Tutorial.md b/Ethereum-Development-Tutorial.md deleted file mode 100644 index 8706a29fe..000000000 --- a/Ethereum-Development-Tutorial.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -name: Ethereum Development Tutorial -category: ---- - -The purpose of this page is to serve as an introduction to the basics of Ethereum that you will need to understand from a development standpoint, in order to produce contracts and decentralized applications. For a general introduction to Ethereum, see [the white paper](https://github.com/ethereum/wiki/wiki/White-Paper), and for a full technical spec see the [yellow](http://gavwood.com/Paper.pdf) papers, although those are not prerequisites for this page; that is to say, this page is meant as an alternative introduction to Ethereum specifically targeted toward application developers. - -### Introduction - -Ethereum is a platform that is intended to allow people to easily write decentralized applications (Đapps) using blockchain technology. A decentralized application is an application which serves some specific purpose to its users, but which has the important property that the application itself does not depend on any specific party existing. Rather than serving as a front-end for selling or providing a specific party's services, a Đapp is a tool for people and organizations on different sides of an interaction use to come together without any centralized intermediary. - -Even necessary "intermediary" functions that are typically the domain of centralized providers, such as filtering, identity management, escrow and dispute resolution, are either handled directly by the network or left open for anyone to participate, using tools like internal token systems and reputation systems to ensure that users get access to high-quality services. Early examples of Đapps include BitTorrent for file sharing and Bitcoin for currency. Ethereum takes the primary developments used by BitTorrent and Bitcoin, the peer to peer network and the blockchain, and generalizes them in order to allow developers to use these technologies for any purpose. - -The Ethereum blockchain can be alternately described as a blockchain with a built-in programming language, or as a consensus-based globally executed virtual machine. The part of the protocol that actually handles internal state and computation is referred to as the Ethereum Virtual Machine (EVM). From a practical standpoint, the EVM can be thought of as a large decentralized computer containing millions of objects, called "accounts", which have the ability to maintain an internal database, execute code and talk to each other. - -There are two types of accounts: - -1. **Externally owned account (EOAs)**: an account controlled by a private key, and if you own the private key associated with the EOA you have the ability to send ether and messages from it. -2. **Contract**: an account that has its own code, and is controlled by code. - -By default, the Ethereum execution environment is lifeless; nothing happens and the state of every account remains the same. However, any user can trigger an action by sending a transaction from an externally owned account, setting Ethereum's wheels in motion. If the destination of the transaction is another EOA, then the transaction may transfer some ether but otherwise does nothing. However, if the destination is a contract, then the contract in turn activates, and automatically runs its code. - -The code has the ability to read/write to its own internal storage (a database mapping 32-byte keys to 32-byte values), read the storage of the received message, and send messages to other contracts, triggering their execution in turn. Once execution stops, and all sub-executions triggered by a message sent by a contract stop (this all happens in a deterministic and synchronous order, ie. a sub-call completes fully before the parent call goes any further), the execution environment halts once again, until woken by the next transaction. - -Contracts generally serve four purposes: - -1. Maintain a data store representing something which is useful to either other contracts or to the outside world; one example of this is a contract that simulates a currency, and another is a contract that records membership in a particular organization. - -2. Serve as a sort of externally owned account with a more complicated access policy; this is called a "forwarding contract" and typically involves simply resending incoming messages to some desired destination only if certain conditions are met; for example, one can have a forwarding contract that waits until two out of a given three private keys have confirmed a particular message before resending it (ie. multisig). More complex forwarding contracts have different conditions based on the nature of the message sent; the simplest use case for this functionality is a withdrawal limit that is overrideable via some more complicated access procedure. - -3. Manage an ongoing contract or relationship between multiple users. Examples of this include a financial contract, an escrow with some particular set of mediators, or some kind of insurance. One can also have an open contract that one party leaves open for any other party to engage with at any time; one example of this is a contract that automatically pays a bounty to whoever submits a valid solution to some mathematical problem, or proves that it is providing some computational resource. - -4. Provide functions to other contracts; essentially serving as a software library. - -Contracts interact with each other through an activity that is alternately called either "calling" or "sending messages". A "message" is an object containing some quantity of ether (a special internal currency used in Ethereum with the primary purpose of paying transaction fees), a byte-array of data of any size, the addresses of a sender and a recipient. When a contract receives a message it has the option of returning some data, which the original sender of the message can then immediately use. In this way, sending a message is exactly like calling a function. - -Because contracts can play such different roles, we expect that contracts will be interacting with each other. As an example, consider a situation where Alice and Bob are betting 100 GavCoin that the temperature in San Francisco will not exceed 35ºC at any point in the next year. However, Alice is very security-conscious, and as her primary account uses a forwarding contract which only sends messages with the approval of two out of three private keys. Bob is paranoid about quantum cryptography, so he uses a forwarding contract which passes along only messages that have been signed with [Lamport signatures](https://en.wikipedia.org/wiki/Lamport_signature) alongside traditional ECDSA (but because he's old fashioned, he prefers to use a version of Lamport sigs based on SHA256, which is not supported in Ethereum directly). - -The betting contract itself needs to fetch data about the San Francisco weather from some contract, and it also needs to talk to the GavCoin contract when it wants to actually send the GavCoin to either Alice or Bob (or, more precisely, Alice or Bob's forwarding contract). We can show the relationships between the accounts thus: - -![img](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/contract_relationship.png) - -When Bob wants to finalize the bet, the following steps happen: - -1. A transaction is sent, triggering a message from Bob's EOA to Bob's forwarding contract. -2. Bob's forwarding contract sends the hash of the message and the Lamport signature to a contract which functions as a Lamport signature verification library. -3. The Lamport signature verification library sees that Bob wants a SHA256-based Lamport sig, so it calls the SHA256 library many times as needed to verify the signature. -4. Once the Lamport signature verification library returns 1, signifying that the signature has been verified, it sends a message to the contract representing the bet. -5. The bet contract checks the contract providing the San Francisco temperature to see what the temperature is. -6. The bet contract sees that the response to the messages shows that the temperature is above 35ºC, so it sends a message to the GavCoin contract to move the GavCoin from its account to Bob's forwarding contract. - -Note that the GavCoin is all "stored" as entries in the GavCoin contract's database; the word "account" in the context of step 6 simply means that there is a data entry in the GavCoin contract storage with a key for the bet contract's address and a value for its balance. After receiving this message, the GavCoin contract decreases this value by some amount and increases the value in the entry corresponding to Bob's forwarding contract's address. We can see these steps in the following diagram: - -![img](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/contract_relationship2.png?1) - -### State Machine - -Computation in the EVM is done using a stack-based bytecode language that is like a cross between Bitcoin Script, traditional assembly and Lisp (the Lisp part being due to the recursive message-sending functionality). A program in EVM is a sequence of opcodes, like this: - - PUSH1 0 CALLDATALOAD SLOAD NOT PUSH1 9 JUMPI STOP JUMPDEST PUSH1 32 CALLDATALOAD PUSH1 0 CALLDATALOAD SSTORE - -The purpose of this particular contract is to serve as a name registry; anyone can send a message containing 64 bytes of data, 32 for the key and 32 for the value. The contract checks if the key has already been registered in storage, and if it has not been then the contract registers the value at that key. - -During execution, an infinitely expandable byte-array called "memory", the "program counter" pointing to the current instruction, and a stack of 32-byte values is maintained. At the start of execution, memory and stack are empty and the PC is zero. Now, let us suppose the contract with this code is being accessed for the first time, and a message is sent in with 123 wei (1018 wei = 1 ether) and 64 bytes of data where the first 32 bytes encode the number 54 and the second 32 bytes encode the number 2020202020. - -Thus, the state at the start is: - - PC: 0 STACK: [] MEM: [], STORAGE: {} - -The instruction at position 0 is PUSH1, which pushes a one-byte value onto the stack and jumps two steps in the code. Thus, we have: - - PC: 2 STACK: [0] MEM: [], STORAGE: {} - -The instruction at position 2 is CALLDATALOAD, which pops one value from the stack, loads the 32 bytes of message data starting from that index, and pushes that on to the stack. Recall that the first 32 bytes here encode 54. - - PC: 3 STACK: [54] MEM: [], STORAGE: {} - -SLOAD pops one from the stack, and pushes the value in contract storage at that index. Since the contract is used for the first time, it has nothing there, so zero. - - PC: 4 STACK: [0] MEM: [], STORAGE: {} - -NOT pops one value and pushes 1 if the value is zero, else 0 - - PC: 5 STACK: [1] MEM: [], STORAGE: {} - -Next, we PUSH1 9. - - PC: 7 STACK: [1, 9] MEM: [], STORAGE: {} - -The JUMPI instruction pops 2 values and jumps to the instruction designated by the first only if the second is nonzero. Here, the second is nonzero, so we jump. If the value in storage index 54 had not been zero, then the second value from top on the stack would have been 0 (due to NOT), so we would not have jumped, and we would have advanced to the STOP instruction which would have led to us stopping execution. - - PC: 9 STACK: [] MEM: [], STORAGE: {} - -Here, we PUSH1 32. - - PC: 11 STACK: [32] MEM: [], STORAGE: {} - -Now, we CALLDATALOAD again, popping 32 and pushing the bytes in message data starting from byte 32 until byte 63. - - PC: 13 STACK: [2020202020] MEM: [], STORAGE: {} - -Next, we PUSH1 0. - - PC: 14 STACK: [2020202020, 0] MEM: [], STORAGE: {} - -Now, we load message data bytes 0-31 again (loading message data is just as cheap as loading memory, so we don't bother to save it in memory) - - PC: 16 STACK: [2020202020, 54] MEM: [], STORAGE: {} - -Finally, we SSTORE to save the value 2020202020 in storage at index 54. - - PC: 17 STACK: [] MEM: [], STORAGE: {54: 2020202020} - -At index 17, there is no instruction, so we stop. If there was anything left in the stack or memory, it would be deleted, but the storage will stay and be available next time someone sends a message. Thus, if the sender of this message sends the same message again (or perhaps someone else tries to reregister 54 to 3030303030), the next time the `JUMPI` at position 7 would not process, and execution would STOP early at position 8. - -Fortunately, you do not have to program in low-level assembly; a high-level language exists, especially designed for writing contracts, known as [Solidity](https://github.com/ethereum/wiki/wiki/Solidity) exists to make it much easier for you to write contracts (there are several others, too, including [LLL](https://github.com/ethereum/cpp-ethereum/wiki/LLL-PoC-5), [Serpent](https://github.com/ethereum/wiki/wiki/Serpent) and [Mutan](https://github.com/ethereum/go-ethereum/wiki/Mutan-0.2), which you may find easier to learn or use depending on your experience). Any code you write in these languages gets compiled into EVM, and to create the contracts you send the transaction containing the EVM bytecode. - -There are two types of transactions: a sending transaction and a contract creating transaction. A sending transaction is a standard transaction, containing a receiving address, an ether amount, a data bytearray and some other parameters, and a signature from the private key associated with the sender account. A contract creating transaction looks like a standard transaction, except the receiving address is blank. When a contract creating transaction makes its way into the blockchain, the data bytearray in the transaction is interpreted as EVM code, and the value returned by that EVM execution is taken to be the code of the new contract; hence, you can have a transaction do certain things during initialization. The address of the new contract is deterministically calculated based on the sending address and the number of times that the sending account has made a transaction before (this value, called the account nonce, is also kept for unrelated security reasons). Thus, the full code that you need to put onto the blockchain to produce the above name registry is as follows: - - PUSH1 16 DUP PUSH1 12 PUSH1 0 CODECOPY PUSH1 0 RETURN STOP PUSH1 0 CALLDATALOAD SLOAD NOT PUSH1 9 JUMPI STOP PUSH1 32 CALLDATALOAD PUSH1 0 CALLDATALOAD SSTORE - -The key opcodes are CODECOPY, copying the 16 bytes of code starting from byte 12 into memory starting at index 0, and RETURN, returning memory bytes 0-16, ie. code byes 12-28 (feel free to "run" the execution manually on paper to verify that those parts of the code and memory actually get copied and returned). Code bytes 12-28 are, of course, the actual code as we saw above. - -### Gas - -One important aspect of the way the EVM works is that every single operation that is executed inside the EVM is actually simultaneously executed by every full node. This is a necessary component of the Ethereum 1.0 consensus model, and has the benefit that any contract on the EVM can call any other contract at almost zero cost, but also has the drawback that computational steps on the EVM are very expensive. Roughly, a good heuristic to use is that you will not be able to do anything on the EVM that you cannot do on a smartphone from 1999. Acceptable uses of the EVM include running business logic ("if this then that") and verifying signatures and other cryptographic objects; at the upper limit of this are applications that verify parts of other blockchains (eg. a decentralized ether-to-bitcoin exchange); unacceptable uses include using the EVM as a file storage, email or text messaging system, anything to do with graphical interfaces, and applications best suited for cloud computing like genetic algorithms, graph analysis or machine learning. - -In order to prevent deliberate attacks and abuse, the Ethereum protocol charges a fee per computational step. The fee is market-based, though mandatory in practice; a floating limit on the number of operations that can be contained in a block forces even miners who can afford to include transactions at close to no cost to charge a fee commensurate with the cost of the transaction to the entire network; see [the whitepaper section on fees](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-White-Paper#fees) for more details on the economic underpinnings of our fee and block operation limit system. - -The way the fee works is as follows. Every transaction must contain, alongside its other data, a `GASPRICE` and `STARTGAS` value. `STARTGAS` is the amount of "gas" that the transaction assigns itself, and `GASPRICE` is the fee that the transaction pays per unit of gas; thus, when a transaction is sent, the first thing that is done during evaluation is subtracting `STARTGAS * GASPRICE` wei plus the transaction's value from the sending account balance. `GASPRICE` is set by the transaction sender, but miners will likely refuse to process transactions whose `GASPRICE` is too low. - -Gas can be roughly thought of as a counter of computational steps, and is something that exists during transaction execution but not outside of it. When transaction execution starts, the gas remaining is set to `STARTGAS - 21000 - 68 * TXDATALEN` where `TXDATALEN` is the number of bytes in transaction data (note: zero bytes are charged only 4 gas due to the greater compressibility of long strings of zero bytes). Every computational step, a certain amount (usually 1, sometimes more depending on the operation) of gas is subtracted from the total. If gas goes down to zero, then all execution reverts, but the transaction is still valid and the sender still has to pay for gas. If transaction execution finishes with `N >= 0` gas remaining, then the sending account is refunded with `N * GASPRICE` wei. - -During contract execution, when a contract sends a message, that message call itself comes with a gas limit, and the sub-execution works the same way (namely, it can either run out of gas and revert or execute successfully and return a value). If sub-execution runs out of gas, the parent execution continues; thus, it is perfectly "safe" for a contract to call another contract if you set a gas limit on the sub-execution. If sub-execution has some gas remaining, then that gas is returned to the parent execution to continue using. - -### Virtual machine opcodes - -A complete listing of the opcodes in the EVM can be found in the [yellow paper](http://gavwood.com/Paper.pdf). Note that high-level languages will often have their own wrappers for these opcodes, sometimes with very different interfaces. - -### Basics of the Ethereum Blockchain - -The Ethereum blockchain (or "ledger") is the decentralized, massively replicated database in which the current state of all accounts is stored. The blockchain uses a database called a [Patricia tree](https://github.com/ethereum/wiki/wiki/Patricia-Tree) (or "trie") to store all accounts; this is essentially a specialized kind of Merkle tree that acts as a generic key/value store. Like a standard Merkle tree, a Patricia tree has a "root hash" that can be used to refer to the entire tree, and the contents of the tree cannot be modified without changing the root hash. For each account, the tree stores a 4-tuple containing `[account_nonce, ether_balance, code_hash, storage_root]`, where `account_nonce` is the number of transactions sent from the account (kept to prevent replay attacks), `ether_balance` is the balance of the account, `code_hash` the hash of the code if the account is a contract and "" otherwise, and `storage_root` is the root of yet another Patricia tree which stores the storage data. - -![we](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/chaindiag.png) - -Every minute, a miner produces a new block (the concept of mining in Ethereum is exactly the same as in Bitcoin; see any Bitcoin tutorial for more info on this), and that block contains a list of transactions that happened since the last block and the root hash of the Patricia tree representing the new state ("state tree") after applying those transactions and giving the miner an ether reward for creating the block. - -Because of the way the Patricia tree works, if few changes are made then most parts of the tree will be exactly the same as in the last block; hence, there is no need to store data twice as nodes in the new tree will simply be able to point back to the same memory address that stores the nodes of the old tree in places where the new tree and the old tree are exactly the same. If a thousand pieces of data are changed between block `N` and block `N + 1`, even if the total size of the tree is many gigabytes, the amount of new data that needs to be stored for block `N + 1` is at most a few hundred kilobytes and often substantially less (especially if multiple changes happen inside the same contract). Every block contains the hash of the previous block (this is what makes the block set a "chain") as well as ancillary data like the block number, timestamp, address of the miner and gas limit. - -### Graphical Interfaces - -A contract by itself is a powerful thing, but it is not a complete Đapp. A Đapp, rather, is defined as a combination of a contract and a graphical interface for using that contract (note: this is only true for now; future versions of Ethereum will include whisper, a protocol for allowing nodes in a Đapp to send direct peer-to-peer messages to each other without the blockchain). Right now, the interface is implemented as an HTML/CSS/JS webpage, with a special Javascript API in the form of the `eth` object for working with the Ethereum blockchain. The key parts of the Javascript API are as follows: - -* `eth.transact(from, ethervalue, to, data, gaslimit, gasprice)` - sends a transaction to the desired address from the desired address (note: `from` must be a private key and `to` must be an address in hex form) with the desired parameters -* `(string).pad(n)` - converts a number, encoded as a string, to binary form `n` bytes long -* `eth.gasPrice` - returns the current gas price -* `eth.secretToAddress(key)` - converts a private key into an address -* `eth.storageAt(acct, index)` - returns the desired account's storage entry at the desired index -* `eth.key` - the user's private key -* `eth.watch(acct, index, f)` - calls `f` when the given storage entry of the given account changes - -You do not need any special source file or library to use the `eth` object; however, your Đapp will only work when opened in an Ethereum client, not a regular web browser. For an example of the Javascript API being used in practice, see [the source code of this webpage](http://gavwood.com/gavcoin.html). - -### Fine Points To Keep Track Of - -See [https://github.com/ethereum/wiki/wiki/Subtleties](https://github.com/ethereum/wiki/wiki/Subtleties) \ No newline at end of file diff --git a/Ethereum-Natural-Specification-Format.md b/Ethereum-Natural-Specification-Format.md deleted file mode 100644 index 6409728eb..000000000 --- a/Ethereum-Natural-Specification-Format.md +++ /dev/null @@ -1,138 +0,0 @@ ---- -name: Ethereum Natural Specification Format -category: ---- - -Solidity contracts can have a special form of comments that form the basis of the Ethereum Natural Specification Format. For a usage example please check [here](https://github.com/ethereum/wiki/wiki/Natspec-Example/). - -# Documentation Example - -Documentation is inserted above the function following the doxygen notation of either one or multiple lines starting with `///` or a multiline comment starting with `/**` and ending with `*/`. - -As an example consider the documentation of the following function: - -``` - /// @notice Send `(valueInmGAV / 1000).fixed(0,3)` GAV from the account of - /// `message.caller.address()`, to an account accessible only by `to.address() - /// @dev This should be the documentation of the function for the developer docs - /// @param to The address of the recipient of the GavCoin - /// @param valueInmGav The GavCoin value to send - function send(address to, uint256 valueInmGAV) { - if (balances[message.caller] >= valueInmGAV) { - balances[to] += valueInmGAV; - balances[message.caller] -= valueInmGAV; - } -``` - -There are a few things to note about the above example. -- Natspec format uses doxygen tags with some special meaning. These are: - + @title: This is a title that should describe the contract and go above the contract definition - + @author: The name of the author of the contract. Should also go above the contract definition. - + @notice: Represents user documentation. This is the text that will appear to the user to notify him - of what the function he is about to execute is doing - + @dev: Represents developer documentation. This is documentation that would only be visible to the - developer. - + @param: Documents a parameter just like in doxygen. Has to be followed by the parameter name. - + @return: Documents the return type of a contract's function. - -- If any of the above are missing they are simply considered as blank, and it's not illegal to omit any of them. - -- `(valueInmGAV / 1000).fixed(0,3)` A dynamic expression. This should be a valid Javascript/Paperscript expression, which when evaluated in an EVM Javascript environment initialised with various system values (such as parameters). - - -# Documentation Output - -When parsed, documentation such as the one from the above example will produce 2 different json files. One is meant to be consumed by the user as a notice when a function is executed and the other to be used by the developer. - -Let us see a more full contract example. - -``` -/// @title This is the contract title. -/// @author Homer Simpson -contract GavCoin -{ - /// @notice Send `(valueInmGAV / 1000).fixed(0,3)` GAV from the account of - /// `message.caller.address()`, to an account accessible only by `to.address() - /// @dev This should be the documentation of the function for the developer docs - /// @param to The address of the recipient of the GavCoin - /// @param valueInmGav The GavCoin value to send - function send(address to, uint256 valueInmGAV) { - if (balances[message.caller] >= valueInmGAV) { - balances[to] += valueInmGAV; - balances[message.caller] -= valueInmGAV; - } - } - - /// @notice `(balanceInmGAV / 1000).fixed(0,3)` GAV is the total funds available to `who.address()`. - /// @param who The address of the person whose balance we check - /// @return The balance of the user provided as argument - function balance(address who) constant returns (uint256 balanceInmGAV) { - balanceInmGAV = balances[who]; - } - -invariants: - /// @notice The sum total amount of GAV in the system is 1 million. - /// @dev This is the invariant development documentation - reduce(0, add, map(valueOf, balances)) == 100000000000; - -construction: - /// @notice Endows `message.caller.address()` with 1m GAV. - balances[message.caller] = 100000000000; - -state: - mapping balances(address) returns uint256 with function(address a) returns uint256 { return a; }; -}; -``` - -## User Documentation - -The above documentation will produce the following user documentation json file as output: - -``` -{ - "source": "...", - "language": "Solidity", - "languageVersion": 1, - "methods": { - "send(address,uint256)": { "notice": "Send `(valueInmGAV / 1000).fixed(0,3)` GAV from the account of `message.caller.address()`, to an account accessible only by `to.address()`." }, - "balance(address)": { "notice": "`(balanceInmGAV / 1000).fixed(0,3)` GAV is the total funds available to `who.address()`." } - }, - "invariants": [ - { "notice": "The sum total amount of GAV in the system is 1 million." } - ], - "construction": [ - { "notice": "Endows `message.caller.address()` with 1m GAV." } - ] -} -``` - -Note that the key by which to find the methods is the function's canonical signature as defined in the [Contract ABI](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI#signature) and not simply the function's name. - -## Developer Documentation - -Apart from the user documentation file, a developer documentation json file should also be produced and should look like this: - -``` -{ - "author": "Homer Simpson", - "title": "This is the contract title.", - "methods": { - "send(uint256)": { - "details": "This should be the documentation of the function for the developer docs" - }, - "balance": { - "details": "" - } - }, - "invariants": [ - { "details": "This is the invariant development documentation"} - ], - "construction": { - "details": "" - } -} -``` - -## Example usage - -There is a detailed example of using the Natspec feature with the cpp client [here](https://github.com/ethereum/wiki/wiki/Natspec-Example/). \ No newline at end of file diff --git a/Ethereum-Wire-Protocol.md b/Ethereum-Wire-Protocol.md deleted file mode 100644 index 51f8df916..000000000 --- a/Ethereum-Wire-Protocol.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -name: Ethereum Wire Protocol -category: ---- - -Peer-to-peer communications between nodes running Ethereum clients run using the underlying [ÐΞVp2p Wire Protocol](https://github.com/ethereum/wiki/wiki/%C3%90%CE%9EVp2p-Wire-Protocol). - -### Basic Chain Syncing -- Two peers connect & say Hello and send their Status message. Status includes the Total Difficulty(TD) & hash of their best block. -- The client with the worst TD asks peer for full chain of just block hashes. -- Chain of hashes is stored in space shared by all peer connections, and used as a "work pool". -- While there are hashes in the chain of hashes that we don't have in our chain: - - Ask for N blocks from our peer using the hashes. Mark them as on their way so we don't get them from another peer. - -### Ethereum Sub-protocol - -**Status** -[`+0x00`: `P`, `protocolVersion`: `P`, `networkId`: `P`, `td`: `P`, `bestHash`: `B_32`, `genesisHash`: `B_32`] Inform a peer of its current **ethereum** state. This message should be sent _after_ the initial handshake and _prior_ to any **ethereum** related messages. -* `protocolVersion` is one of: - * `0x00` for PoC-1; - * `0x01` for PoC-2; - * `0x07` for PoC-3; - * `0x09` for PoC-4. - * `0x17` for PoC-5. - * `0x1c` for PoC-6. -* `networkId` should be 0 for testnet, 1 for mainnet. -* `td`: Total Difficulty of the best chain. Integer, as found in block header. -* `bestHash`: The hash of the best (i.e. highest TD) known block. -* `genesisHash`: The hash of the Genesis block. - -**NewBlockHashes** -[`+0x01`: `P`, `hash1`: `B_32`, `hash2`: `B_32`, `...`] Specify one or more new blocks which have appeared on the network. The list may contain 256 hashes at most. To be maximally helpful, nodes should inform peers of all blocks that they may not be aware of. Including hashes that the sending peer could reasonably be considered to know (due to the fact they were previously informed of because that node has itself advertised knowledge of the hashes through `NewBlockHashes`) is considered Bad Form, and may reduce the reputation of the sending node. Including hashes that the sending node later refuses to honour with a proceeding `GetBlocks` message is considered Bad Form, and may reduce the reputation of the sending node. - -**Transactions** -[`+0x02`: `P`, [`nonce`: `P`, `receivingAddress`: `B_20`, `value`: `P`, `...`], `...`] Specify (a) transaction(s) that the peer should make sure is included on its transaction queue. The items in the list (following the first item `0x12`) are transactions in the format described in the main Ethereum specification. Nodes must not resend the same transaction to a peer in the same session. This packet must contain at least one (new) transaction. - -**GetBlockHashes** -[`+0x03`: `P`, `hash` : `B_32`, `maxBlocks`: `P`] Requests a `BlockHashes` message of at most `maxBlocks` entries, of block hashes from the blockchain, starting at the parent of block `hash`. Does not _require_ the peer to give `maxBlocks` hashes - they could give somewhat fewer. - -**BlockHashes** -[`+0x04`: `P`, `hash_0`: `B_32`, `hash_1`: `B_32`, `...`] Gives a series of hashes of blocks (each the child of the next). This implies that the blocks are ordered from youngest to oldest. - -**GetBlocks** -[`+0x05`: `P`, `hash_0`: `B_32`, `hash_1`: `B_32`, `...`] Requests a `Blocks` message detailing a number of blocks to be sent, each referred to by a hash. Note: Don't expect that the peer necessarily give you all these blocks in a single message - you might have to re-request them. - -**Blocks** -[`+0x06`, [`blockHeader`, `transactionList`, `uncleList`], `...`] Specify (a) block(s) as an answer to `GetBlocks`. The items in the list (following the message ID) are blocks in the format described in the main Ethereum specification. This may validly contain no blocks if no blocks were able to be returned for the `GetBlocks` query. - -**NewBlock** -[`+0x07`, [`blockHeader`, `transactionList`, `uncleList`], `totalDifficulty`] Specify a single block that the peer should know about. The composite item in the list (following the message ID) is a block in the format described in the main Ethereum specification. -- `totalDifficulty` is the total difficulty of the block (aka score). - -### PV61 specific - -**BlockHashesFromNumber** -[`+0x08`: `P`, `number`: `P`, `maxBlocks`: `P`] -Requires peer to reply with a `BlockHashes` message. Message should contain block with that of number `number` on the canonical chain. Should also be followed by subsequent blocks, on the same chain, detailing a number of the first block hash and a total of hashes to be sent. Returned hash list must be ordered by block number in ascending order. - -### Proposed messages for New Model syncing (PV62) - -**NewBlockHashes** -[`+0x01`: `P`, [`hash_0`: `B_32`, `number_0`: `P`], [`hash_1`: `B_32`, `number_1`: `P`], ...] Specify one or more new blocks which have appeared on the network. To be maximally helpful, nodes should inform peers of all blocks that they may not be aware of. Including hashes that the sending peer could reasonably be considered to know (due to the fact they were previously informed of because that node has itself advertised knowledge of the hashes through `NewBlockHashes`) is considered Bad Form, and may reduce the reputation of the sending node. Including hashes that the sending node later refuses to honour with a proceeding `GetBlockHeaders` message is considered Bad Form, and may reduce the reputation of the sending node. - -**GetBlockHeaders** -[`+0x03`: `P`, `block`: { `P` , `B_32` }, `maxHeaders`: `P`, `skip`: `P`, `reverse`: `P` in { `0` , `1` } ] Require peer to return a `BlockHeaders` message. Reply must contain a number of block headers, of rising number when `reverse` is `0`, falling when `1`, `skip` blocks apart, beginning at block `block` (denoted by either number or hash) in the canonical chain, and with at most `maxHeaders` items. - -**BlockHeaders** -[`+0x04`, `blockHeader_0`, `blockHeader_1`, `...`] Reply to `GetBlockHeaders`. The items in the list (following the message ID) are block headers in the format described in the main Ethereum specification, previously asked for in a `GetBlockHeaders` message. This may validly contain no block headers if no block headers were able to be returned for the `GetBlockHeaders` query. - -**GetBlockBodies** -[`+0x05`, `hash_0`: `B_32`, `hash_1`: `B_32`, `...`] Require peer to return a `BlockBodies` message. Specify the set of blocks that we're interested in with the hashes. - -**BlockBodies** -[`+0x06`, [`transactions_0`, `uncles_0`] , `...`] Reply to `GetBlockBodies`. The items in the list (following the message ID) are some of the blocks, minus the header, in the format described in the main Ethereum specification, previously asked for in a `GetBlockBodies` message. This may validly contain no items if no blocks were able to be returned for the `GetBlockBodies` query. - -ELIMINATED: `GetBlockHashes`, `BlockHashes`, `GetBlocks`, `Blocks`, `BlockHashesFromNumber` - -### Proposed messages for fast synchronization (PV63) - -**GetNodeData** -[`+0x0d`, `hash_0`: `B_32`, `hash_1`: `B_32`, `...`] Require peer to return a `NodeData` message. Hint that useful values in it are those which correspond to given hashes. - -**NodeData** -[`+0x0e`, `value_0`: `B`, `value_1`: `B`, `...`] Provide a set of values which correspond to previously asked node data hashes from `GetNodeData`. Does not need to contain all; best effort is fine. If it contains none, then has no information for previous `GetNodeData` hashes. - -**GetReceipts** -[`+0x0f`, `hash_0`: `B_32`, `hash_1`: `B_32`, `...`] Require peer to return a `Receipts` message. Hint that useful values in it are those which correspond to blocks of the given hashes. - -**Receipts** -[`+0x10`, [`receipt_0`, `receipt_1`], `...`] Provide a set of receipts which correspond to previously asked in `GetReceipts`. - -### Proposal for light clients (PV64) - deprecated in favor of LES (the Light Ethereum sub-protocol) - -**GetAcctProof** -[`+0x11`, [`blknum`, `address`]] Require peer to return a `Proof` message, containing a Merkle-tree proof of the account data (nonce, balance, code hash, storage root) at `address` from the state root of block `blknum` - -**GetStorageDataProof** -[`+0x12`, [`blknum`, `address`, `key`]] Require peer to return a `Proof` message, containing a Merkle-tree proof of the storage value of index `key` in `address` from the state root of block `blknum` - -**Proof** -[`+0x13`, [`node_1`, `node_2`...]] Return a Merkle-tree proof consisting of a set of nodes that must be processed in order to access the piece of account data or storage value requested in `GetAcctProof` or `GetStorageDataProof` - -### Session Management - -For the Ethereum sub-protocol, upon an active session, a `Status` message must be sent. Following the reception of the peer's `Status` message, the Ethereum session is active and any other messages may be sent. All transactions should initially be sent with one or more Transactions messages. - -Transactions messages should also be sent periodically as the node has new transactions to disseminate. A node should never send a transaction back to the peer that it can determine already knows of it (either because it was previously sent or because it was informed from this peer originally). - -### Upcoming changes -- [Light Client Protocol](https://github.com/ethereum/wiki/wiki/Light-client-protocol) - -### Changes (PoC-7) -- [NewBlock Message](https://github.com/ethereum/wiki/wiki/NewBlock-Message) - -### Changed (PoC-6) -- [Parallel Block Downloads](https://github.com/ethereum/wiki/wiki/Parallel-Block-Downloads) \ No newline at end of file diff --git a/Ethereum-introduction.md b/Ethereum-introduction.md deleted file mode 100644 index 8d6a862fb..000000000 --- a/Ethereum-introduction.md +++ /dev/null @@ -1,277 +0,0 @@ -![Ethereum Homestead gold ingots](https://sustergy.files.wordpress.com/2017/05/ethereum-homestead-background-17.jpg?w=1000) - -Note that due to the lightning-fast pace of development in the Ethereum space with core development and dapps continually being launched, certain parts of this article may be outdated. You can help by keeping it up to date! - - - -Table of Contents -================= - - * [Table of Contents](#table-of-contents) - * [About Ethereum](#about-ethereum) - * [Uses](#uses) - * [List of dapps](#list-of-dapps) - * [Market analysis](#market-analysis) - * [Issues](#issues) - * [Scalability](#scalability) - * [Proof of work / proof of stake / other proving methods](#proof-of-work--proof-of-stake--other-proving-methods) - * [Public permissionless blockchains vs. private permissioned blockchains](#public-permissionless-blockchains-vs-private-permissioned-blockchains) - * [No technological artefacts can be a panacea](#no-technological-artefacts-can-be-a-panacea) - * [How do you buy and sell Ether, the currency of Ethereum?](#how-do-you-buy-and-sell-ether-the-currency-of-ethereum) - * [Table of exchanges](#table-of-exchanges) - * [More details about what I've tried (not very necessary to know)](#more-details-about-what-ive-tried-not-very-necessary-to-know) - * [Development](#development) - * [Concluding remarks](#concluding-remarks) - * [Further reading](#further-reading) - -# About Ethereum -Ethereum is a [decentralized](https://medium.com/@VitalikButerin/the-meaning-of-decentralization-a0c92b76a274) blockchain platform for "building unstoppable applications", while Ether is the cryptocurrency used on this platform. Ethereum has been described in several ways, such as (the first and third resources are more general introductions, while the second is a technical introduction, although all are outdated. -Another introduction is available [here](https://bitsonblocks.net/2016/10/02/a-gentle-introduction-to-ethereum/), but again, it is outdated. Despite being outdated, Ethereum has maintained backwards compatibility thus far up till January 1 2018, so the info is still relevant.): - -Let's briefly breakdown what those terms mean. - -**Decentralized** technology uses [peer-to-peer computer networks](https://en.wikipedia.org/wiki/Peer-to-peer) (there's a picture below), and are not subject to the whims of a central authority such as a government or server administrator (like Google or Facebook) which can help to achieve better decision making for public good. **Blockchain** means that the currency is built and secured by adding and verifying blocks of transactions to blocks made previously, thus forming a "chain". Blocks added to the chain become harder and harder to crack over time, as they are verified by more nodes in the blockchain peer-to-peer network. Blockchain technology has been referred to as the **Web 3.0**. The world wide web (retroactively the Web 1.0) consisted of websites publishing content and users passively reading/viewing it. The Web 2.0 used user interaction, such as forums (with upvoting and commenting), reaction buttons (e.g. the Facebook reactions: likes 👍, love ❤️ , laughter 😆, wow 😲, sad 😢, angry 😠), sharing (republishing), however these interactions have no direct economic effect on the host website; users do not share in the value generated from the website. The Web 3.0 is starting to be defined as the movement away from centralisation of computation power in servers which provide services to clients (known as the client-server network model) to peer-to-peer networks and blockchains, and from centralisation of authority and sovereignty from nation-states and corporations to the networked individual. - -![server-based-network](https://sustergy.files.wordpress.com/2017/05/200px-server-based-network-svg.png) -![p2p-network](https://sustergy.files.wordpress.com/2017/05/200px-p2p-network-svg.png) - -**Cryptocurrency** refers to a a digital currency that secures transactions with cryptographic code, which is solved through hardware computational power (known as mining or proof of work) or other less energy-intensive ways such as proof-of-stake. (There are more details on that below.) - -Zero knowledge proofs like ZK SNARKs can also be used to make cryptocurrency transactions more private 🕵️ or secret 🤐 (which is different to being secure 🔒), thus negating the need to run applications on a permissioned private network like the [Ethereum Enterprise Alliance](https://entethalliance.org/). Ethereum uses [precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128](https://github.com/ethereum/EIPs/pull/213), for [pairing checks](https://github.com/ethereum/EIPs/pull/212), which permit [zk-SNARKs](https://blog.ethereum.org/2017/10/12/byzantium-hf-announcement/), also see [here](https://medium.com/@VitalikButerin/zk-snarks-under-the-hood-b33151a013f6), [as implemented](https://github.com/ethereum/EIPs#finalized-eips-standards-that-have-been-adopted) in the [Byzantium hard fork](https://blog.ethereum.org/2017/10/12/byzantium-hf-announcement/). There is also the Zerocoin protocol which is demonstrated by Zcoin (which plans to integrate Ethereum). - -# Uses -The platform part of Ethereum makes it much more useful than just a cryptocurrency. With it, you can create any decentralized application (known as a dapp, which works over a peer-to- peer network rather than a centralized client-server network 💻🕸️), so the functionality is only limited by what programs could potentially do and not do, and by consequence, what programmers develop, 👨‍💻 but it can theoretically be used for any economic or governance activity. - -## List of dapps - -For a list of dapps, visit [here](https://github.com/Ethereum-community/Ethereum-introduction/wiki/Decentralised-apps-(dapps)). - - -*** - - -However, there are several issues that will need to be resolved to help Ethereum be used to its full potential, which are described below. - -## Market analysis -As of the 1st of December 2017, [the market capitalisation of Ethereum is $32.6 billion USD](https://cryptolization.com/ethereum) (refer to the link for the latest figure), and [it has been in circulation possibly since 30 July 2015](https://github.com/jamesray1/homestead-guide/blob/32d2fa4ccfa3d45f8493a673a08247450d55fea0/source/introduction/the-homestead-release.rst#milestones-of-the-ethereum-development-roadmap), with the [first transaction using Ethereum on 8 August 2015](https://www.etherchain.org/account/0x5abfec25f74cd88437631a7731906932776356f9). Compare this with the next largest and the current largest cryptocurrency, [Bitcoin, with a market cap of $41.0 b. US](https://cryptolization.com/ethereum), where [it has been in circulation since January 2009](http://www.newyorker.com/reporting/2011/10/10/111010fa_fact_davis). Technically, Ethereum has had a much faster growth rate, while more importantly for long term investment (I do not encourage speculation as that only causes volatility as has been seen) the fundamentals are much better than Bitcoin. While it is true that Bitcoin has more of a market and currency, e.g. in terms of more entities that will accept it as a form of payment, the creator of this wiki expects that time will change that (indeed the market cap of Ethereum recently surpassed half that of Bitcoin, around May 2017). Also, [the number of transactions of Ethereum surpassed that of several cryptocurrencies combined on 22 Nov 2017](https://www.reddit.com/r/ethereum/comments/7est9k/ethereum_is_now_processing_more_transactions_a/). However, note [this retort](https://www.reddit.com/r/ethereum/comments/7est9k/ethereum_is_now_processing_more_transactions_a/dq7a31u/). - -# Issues -There also several issues with Ethereum, such as not being scalable enough, not being full decentralized, energy consumption with mining, if quantum computing advances it would be insecure (but this is being fixed). With its [large storage database](https://www.reddit.com/r/ethtrader/comments/7axn5g/ethereum_blockchain_sizewe_have_a_problem/) (I have to provide a [Reddit link](https://www.reddit.com/r/ethtrader/comments/7axn5g/ethereum_blockchain_sizewe_have_a_problem/) as a source as the [original link](https://etherscan.io/chart/chaindatasizefull) doesn't have the graph any more, while [Wayback doesn't render it either](https://web.archive.org/web/20171211015955/https://etherscan.io/chart/chaindatasizefull).), mining and architecture requiring to run a full node to mine or validate transactions, it is not decentralized enough. More (outdated but still applicable) info on that is e.g. [here](https://ethereum.stackexchange.com/questions/143/what-are-the-ethereum-disk-space-needs#826), as well as [here](https://github.com/ethereum/go-ethereum#full-node-on-the-main-ethereum-network). - -## Scalability - -Ethereum will need to scale to process far more transactions per second (to become a "world computer") than Visa, Mastercard and American Express combined (which process on the order of [tens of thousands of transactions per second](https://usa.visa.com/run-your-business/small-business-tools/retail.html) [in the link, CTRL+F 24,000]), while Ethereum 1.0, the current version as of December 30 2017, processed [a record of 1103523 transactions on Friday, December 22, 2017, or 12.77 transactions per second](https://web.archive.org/web/20171230005127/https://etherscan.io/chart/tx). - -Note that [Ripple claims that it's Consensus Ledger can process a thousand transactions per second](https://ripple.com/dev-blog/ripple-consensus-ledger-can-sustain-1000-transactions-per-second/), while it could process more with payment channels. "Although payment channels achieve practically infinite scalability by decoupling payment from settlement, they do so without incurring the risk typically associated with delayed settlement." Further note that Ripple achieves this by trading off on decentralization, through a [distributed network of validators or distributed servers](https://ripple.com/build/xrp-ledger-consensus-process/), while it has been described as a [federation protocol](https://wiki.ripple.com/Federation_protocol). - -There are even more scalable blockchains that use a delegated proof of stake (DPOS) consensus protocol, such as Bitshares and Steem. [Bitshares can apparently process 100,000 TPS](https://bitshares.org/technology/industrial-performance-and-scalability/). - -More generally, in order to have faster payments or higher transaction throughput, you need to reduce the number of validators (miners are a kind of validator that perform energy intensive computational work, finding a random nonce or sequence number in a large set of numbers) in the consensus protocol, or reduce the other (i.e. for faster payments you can reduce transaction throughput or reduce validators, while for higher transaction throughput you can reduce validators or have payments take longer to finalize). This is [a trade-off triangle](https://twitter.com/VladZamfir/status/932319930363494400). You could potentially have one blockchain with [heterogeneous sharding](https://twitter.com/VladZamfir/status/932320997021171712), with different shards with a different degree of balance between these properties. Ethereum is working on [sharding](https://github.com/ethereum/sharding/blob/develop/docs/doc.md), which includes using [stateless clients](https://github.com/ethereum/sharding/blob/develop/docs/doc.md#stateless-clients) (while more on that is [here](https://ethresear.ch/t/the-stateless-client-concept/172/14)). - -If you increase scalability in an instant via some blockchain or shard, while keeping latency constant (or reducing it) you need to reduce decentralization, which reduces the number of points of attack needed to compromise the whole network, i.e. reducing decentralization reduces security. - -## Proof of work / proof of stake / other proving methods -The mining process to crack cryptographic code (specifically to discover the nonce, a very large number, for each block by trial and error) requires a lot of computation power. Nevertheless, I'm guessing that the computation power should be less when you consider the energy consumption of incumbent financial systems. (Think of extracting and processing resources to make coins and notes, minting and printing, energy consumption of banks and tiers of related energy consumption in the life cycle of fiat money.) Still, developers of some cryptocurrencies such as Ethereum are transitioning to (as is the case for Ethereum), or already using, a different way of maintaining and creating blocks, known as proof of stake. For more information, you can see this Proof of Stake Wikipedia article here (although note the header warning about the article potentially not being verifiable or neutral due to relying heavily on sources too closely associated to the subject). The tricky part is in getting proof methods to work better than proof of work, as outlined here in the criticism section of the PoS Wiki. - -## No technological artefacts can be a panacea -For the continual improvement of humanity, there needs to be balance in life between things that benefit us materially and things that benefit us on higher levels, particularly spiritually. There is a risk that technology can make some people better off, and others worse off. So there needs to be consideration for how technology can be implemented to maximise [utility](https://en.wikipedia.org/wiki/Utilitarianism). One consideration of that is [here](https://medium.com/@RhysLindmark/co-evolving-the-phase-shift-to-cryptocapitalism-by-founding-the-ethereum-commons-co-op-f4771e5f0c83). - -## There's a risk of attacks from quantum computing, if it becomes performant enough - - - -# How do you buy and sell Ether, the currency of Ethereum? - -Summary: compare deals with buying and sell through different exchanges such as P2P ones with an arbitrator like [**LocalEthereum**](https://localethereum.com), or with centralized exchanges (which vary with your local jurisdiction, e.g. in Australia there is [BTCmarkets](https://btcmarkets.net/fees) and in the US plus worldwide there is [Coinbase](https://www.coinbase.com), which also allows you to spend cryptocurrencies e.g. with a debit card. For more see the table below, [here](https://github.com/jamesray1/Ethereum-introduction/wiki/Ethereum-introduction#table-of-exchanges)). - -The simplest way may be to use [**LocalEthereum**](https://localethereum.com), where you don't need to go through KYC processes. The creator of this wiki has found that "I can **sell Ether for a better deal** than I can find with an exchange, without any trading or withdrawal fees, apart from those associated with different payment methods". I like that it has lower fees compared to exchanges. I also read about how the localethereum platform works, and it seems pretty secure. The maker fee (which is what the party of the trade that puts up the offer) is 0.25% while the taker fee is 0.75%. [BTCmarkets](https://btcmarkets.net/fees) has higher fees compared to the maker fee, and higher than the taker fee if the amount is below $3000. Additionally, there have been hacks with exchanges like Mt. Gox and Bithumb. That's harder to achieve with localethereum since they can't get access to your funds, they can only settle disputes (if they arise) by sending the funds in the escrow to the buyer or the seller. However, I have been able to find a **better deal**, at least at certain times, with buying Ether if I buy through [**BTCmarkets**](https://btcmarkets.net/fees), although that would be slower via BPAY with bank transfer than paying via cash deposit via an ATM or bank." - -More information about Ether is [here](http://ethdocs.org/en/latest/ether.html). - -Disclaimer from the creator of this wiki: I have put most of my funds in Ether, the currency of Ethereum. Does that shock you? 😲 Yep, it's risky, but I've done due diligence 🔍 with fundamental analysis, and a little bit of sentiment and technical analysis, and I think that the market cap of Ether will continue to grow 🌱🌳 and increase, albeit with some volatility 📈. I consider it a digital currency that is in a pioneering, rapid growth stage of development (fuelled by a lot of genuine uptake of the currency as well as speculation about its future value, if not its current value), not just an asset. I hope my post will outline why investing in Ether is a good idea (and not just investing a small percentage of your cash, unless you are tied up with a mortgage 🏠 or have other monetary or non-monetary ties or circumstances that limit your investable capital). However, if you don't want to risk the downside volatility, e.g. if you don't have any risk capital, then you may want to consider buying a stable coin like [Dai Coin](https://makerdao.com/) instead. - -Based on my research below, if you're in Australia 🇦🇺 (otherwise skip to the next paragraph), I recommend creating an account with BTCmarkets.net, verifying your ID, and using BPAY or PoliPayments to deposit AUD. Note that the rest of the following info in this paragraph is outdated since MEBank used to not support BPAY publicly, but now they do. If your bank doesn't support PoliPayments and you want to use that instead of BPAY, although I can't think of any good reason why you'd want to use PoliPayments over BPAY, then you can set up a bank account with BOQ (or any other bank that supports POLi Payments, doesn't invest in fossil fuels and has no fees for transaction and savings accounts [note that Bendigo doesn't have an Ultimate Everyday account any more]. You can probably ignore the interest rate since it is so marginal compared to other bank's rates and the gains that you are likely to make by holding funds with Ether instead. However, when I did research for interest rates I found that ME Bank savings rates were second only to UBank, which invests in fossil fuels indirectly as it is owned by NAB. - -## Table of exchanges - -You can use [localethereum](https://localethereum.com) anywhere, but in my experience you may not get as good a deal as buying it on a local exchange. - -If you're not in Australia 🇦🇺, then here's a comparison of exchange rates 💱 for fiat to crypto- and crypto- to crypto- currencies (note that there is still a focus on Australia, but you can click on the links to get more information of the fees): - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Exchange link (may go to a fees page)Fiat to crypto exchange fee buy/sell spread
BTCmarketsAUD is the only fiat currency. 0.85% trading fee. Funds available to deposit, withdraw, buy and sell are: AUD, ETH, ETC, BTC and LTC. To deposit AUD, you need to verify your account and then use POLi Payments (available banks are here. My bank is ME Bank, which doesn't support POLi Payments. I applied with BOQ because they do support POLi Payments, they don't invest in fossil fuels [like ME Bank] and they have transaction and savings accounts with no fees [like ME Bank].)
GDAX0.25/.3% maker fee low volume, 0% taker fee BTC for USD/EUR/GBP, ETH/LTC for USD/BTC/EUR
Coinjar, has a debit card with accounts for Ether, BTC, XRP and LTC.1.00% AUD/BTC (and only AUD/BTC)
CoinbaseIn Aus: 3.99% credit/debit card only (no other transaction method accepted). Other fiat and crypto currencies are available.
CEX7% BTC/ETH for USD/EUR/GBP/RUB
ice3x1% ZAR/BTC
LunoZAR/BTC fee not easy to find
okcoinCNY/USD for BTC/LTC, fee not easy to find
MaicoinTN/BTC Fee not shown, claimed none
- - - - - - - - - - - - - - - - - - - - - - - -
Crypto to crypto exchange fee / buy/sell spread
Poloniex0.15/.25% BTC/ETH “maker-taker” (presumably the same as buy-sell)
gdax.com/fees/0.25/.3% maker fee low volume, 0% taker fee ETH/LTC for BTC
Exodus~0.4720–.528% BTC/ETH variable. Desktop app. Sometimes currencies are not available for exchange!
NVODecentralised. ICO 05/27/17 02:00 UTC to 06/27/17 02:00 UTC
- -Exchanges are listed in [this article](https://medium.com/@Ethereum_AI/ethereum-introduction-what-exactly-is-it-why-care-how-to-invest-9a627ab04408), which I've copied and pasted (repetition is OK): - -**America, US dollars** - -https://www.coinbase.com - -https://gemini.com/ - -**Australian Dollar** - -https://btcmarkets.net/ - -**Canadian Dollar** - -https://www.quadrigacx.com - -**Chinese Yuan** - -https://www.huobi.com - -https://www.okcoin.com - -https://yunbi.com - -**European Euros** - -https://www.kraken.com - -**India** - -https://duckduckgo.com/?q=Ethereum+exchange+india&t=brave&ia=web - -**Mexican Peso** - -https://bitso.com - -**South Korean Won** - -https://coinone.co.kr/ - -https://www.bithumb.com/ - -## More details about what I've tried (not very necessary to know) - -I bought BTC in a different way. Step 2 worked for me. I will try step 1 next time I buy more BTC. - -I created an account on btcmarkets.net, verified my email address, tried to login, but couldn't. I tried to disable two factor authentication, but it asked for my mobile number, which I didn't enter when I created my account. I tried to reset my password and log in again, but that didn't work. I entered my email address correctly. I sent a message to support to ask for help. I figured out that my password was too long, and have notified btcmarkets.net. After creating a password of 23 characters, I was able to log in. I created another password of 56 characters using Chinese characters, emojis and ASCII characters, and was able to log in. (Incidentally, it is a hassle to do this, so a decentralised, private password generator would be wonderful.) - -The following steps are what I have tried so far, in detail. -
    -
  1. Convert AUD to Bitcoin (BTC) via an exchange like Coinjar. I left a review of Coinjar here. Fee: 1%. While this step is tailored for Australia, it can be adapted to any country that has a bitcoin exchange.
  2. -
  3. I created a Poloniex account, sent funds from got the Bitcoin deposit address, then sent my BitGo funds to that address. Once the transaction completed, I then used Poloniex Exchange to convert to Eth, with a maker-taker fee of: 0.15/0.25%.
  4. -
-Before step 2 above, I tried the following: -
    -
  1. Create an Ethereum Wallet 👛 like MyEtherWallet. Unfortunately Mist, a program being developed by Ethereum that has a browser and a wallet is still a pre-release, so it may not be very suitable for end users just yet.
  2. -
  3. Convert BTC to Ether (ETH) via a cryptocurrency exchange like Shapeshift. Use a precise transaction, make sure the amount is within the min. and max. deposit. Copy and paste the bitcoin address in Coinjar by signing in (if you aren't already) and going to Accounts > Everyday Bitcoin > View address. Put this address as the refundable address. Copy and paste the address from MyEtherWallet. Put this as the destination address. Tick the box to save the destination address for future payments. However, this didn't work.
  4. -
-I also sent an email to Coinjar to suggest that they develop functionality for purchasing Ether directly using AUD. You can do the same with the exchange of your choice. - -I have been able to deposit funds into Coinjar (needing to be less than the transaction limits) but have not been able to get Eth funds as of yet. I have also tried to create an account on BitGo, send coins from Coinjar to BitGo, and use Shapeshift with that account and still with MyEtherWallet, however that didn't work. - -I will not discuss trading (which I mean buying with the intention to sell most or all of the purchase at any future time particularly in the short term in order to realize a profit) as I am not very interested in trying to guess the short-term direction of markets (although I admit that trading helps to provide liquidity). - -# Development -Are you interested in learning to develop smart contracts with Ethereum, and maybe develop a really useful dapp and become a millionaire? - -Check out the [Ethereum website](https://www.ethereum.org/)! Then, you can [read the Solidity docs](https://solidity.readthedocs.io/en/develop/). - -If you want to help contribute to core development, there is also: -* the [Yellow Paper](https://github.com/ethereum/yellowpaper/pull/376) (make sure that you read the [EIPs](https://github.com/ethereum/EIPs) too since as of Dec 8 it is not up-to-date with the last commit on August 8, while the Constantinople EIPs were implemented in October). Instead I recommend ; -* Learn Python first, e.g. with [Learn Python the Hard Way](https://www.learnpythonthehardway.org/) (I learnt using this, it's pretty good), [Codecademy](https://www.codecademy.com/learn/learn-python), [Pydocs](https://docs.python.org/3/), [Coursera](https://www.coursera.org/courses?languages=en&query=learn+python), etc. Knowing Python is useful for [pyethereum](https://github.com/ethereum/pyethereum), which is being used as an Ethereum client, to implement Serenity and sharding, as well as [vyper](https://github.com/ethereum/Vyper), an experimental, secure smart contract programming language; -* [LLL](https://media.consensys.net/an-introduction-to-lll-for-ethereum-smart-contract-development-e26e38ea6c23) (also see [here](https://github.com/ethereum/solidity/tree/develop/liblll) and [here](https://github.com/ethereum/solidity/tree/develop/lllc)); -* [JULIA](https://solidity.readthedocs.io/en/develop/julia.html), an intermediate language for different Ethereum virtual machines; -* clients such as [Geth](https://github.com/ethereum/go-ethereum), [Parity](https://github.com/paritytech/parity) which is under [Parity Tech](https://github.com/paritytech) a separate organization to the Ethereum Foundation, [C++ Ethereum](https://github.com/ethereum/cpp-ethereum), [Pyethereum](https://github.com/ethereum/pyethereum); -* [Serenity](https://github.com/ethereum/pyethereum/tree/serenity); -* [sharding](https://github.com/ethereum/sharding/blob/develop/docs/doc.md); -* [research](https://github.com/ethereum/research) such as stateless clients, sharding, scalability improvements, Casper and more; -* [EWasM](https://github.com/ewasm); -* if you're interested in testing, see the documentation [here](https://ethereum-tests.readthedocs.io/en/latest/), as well as [the Github tests repo](https://github.com/ethereum/tests), [a Gist here (it is outdated)](https://gist.github.com/Souptacular/fd197b1fac7c6d2660b0bef27a33ed40#lll-and-evm-stack-resources), and [Gitter here](https://gitter.im/ethereum/tests) ; and -* [many other repositories](https://github.com/ethereum). - -# Concluding remarks - -Ether certainly seems like a good investment, and a good alternative to using fiat currencies, as well as an enabler for otherwise uneconomical business, due to lower transaction costs. It's more decentralized nature than central banks has advantages for trade from a local to global scale. With governance applications and systems on top Ethereum, it is even possible to do away with the hindering borders surmounted by nation-states. By doing away with these borders, society can be more open, inclusive and equitable. - -However, all technology can only help mankind and the world to a certain extent. What is more important is for each and every person to become increasingly blissful. Each person must go within and enter a stillness of body and mind, which is when that bliss starts to manifest, and practice balanced living. Practicing certain techniques such as those given by Self-Realization Fellowship, such as daily Kriya yoga meditation, developing unconditional love that starts in the heart, keeping the mind at the point between the eyebrows, and moral living, helps each person manifest that bliss within, and from there, express that bliss outwardly at all times. - -# Further reading - -* [Another introduction](https://github.com/jamesray1/Ethereum-introduction/wiki/Ethereum-introduction) -* [MyEtherWallet knowledge base (good for issues with wallets)](https://myetherwallet.github.io/knowledge-base/) -* [An introduction (Frontier first release, outdated)](https://ethereum.gitbooks.io/frontier-guide/content/ethereum.html) -* [Here's another introduction, made in November 2017](https://medium.com/@Ethereum_AI/ethereum-introduction-what-exactly-is-it-why-care-how-to-invest-9a627ab04408) -* [Ethereum community on Gitter](https://gitter.im/ethereum) -* [Ethereum research forum](https://ethresear.ch/) -* [Correct by construction Casper prototype](https://ethresear.ch/t/the-correct-by-construction-casper-paper-prototype-published-at-devcon-tear-it-apart/196) -* [Casper the Friendly Finality Gadget](https://ethresear.ch/t/latest-casper-basics-tear-it-apart/151/57) -* [The stateless client concept](https://ethresear.ch/t/the-stateless-client-concept/172) -* [Ethereum 2 and alternative PoS implementations](https://ethresear.ch/t/ethereum-2-and-alternative-pos-implementations/190/7) -* [Ethereum wiki](https://en.wikipedia.org/wiki/Ethereum) -* [Ethereum and the hodlers that love them](https://www.reddit.com/r/ethtrader/comments/6jyn9y/ethereum_the_hodlors_that_love_them/) - - -This article was originally created here in May 2017, and has been regularly updated since then: https://sustergy.wordpress.com/2017/05/18/why-buy-ether-and-how/. Feel free to send a donation to the initial author at jamesray.eth, or make edits to it yourself, or fork it! diff --git a/Exchange-Integration.md b/Exchange-Integration.md deleted file mode 100644 index 9fa065749..000000000 --- a/Exchange-Integration.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: Exchange Integration -category: ---- - -## Overview - -TODO - -## Reference implementation - -TODO: Design/documentation for implementation - -https://github.com/debris/eth-exchange diff --git a/FAQ.md b/FAQ.md deleted file mode 100644 index cc812a4a4..000000000 --- a/FAQ.md +++ /dev/null @@ -1,263 +0,0 @@ ---- -name: FAQ -category: ---- - -Answers to questions about Ethereum - - - - -* [Ethereum](#ethereum) - * [What is Ethereum?](#what-is-ethereum) - * [Where can I learn more about Ethereum?](#where-can-i-learn-more-about-ethereum) - * [Where can I find the main project repositories?](#where-can-i-find-the-main-project-repositories) - * [Where can I learn about the Ether sale and mining?](#where-can-i-learn-about-the-ether-sale-and-mining) -* [Clients](#clients) - * [Where can I find official releases?](#where-can-i-find-official-releases) - * [How to install development builds?](#how-to-install-development-builds) - * [How to install the clients from source?](#how-to-install-the-clients-from-source) -* [Mining](#mining) - * [How can I mine Ether?](#how-can-i-mine-ether) - * [How to get free testnet Ether?](#how-to-get-free-testnet-ether) -* [Contracts](#contracts) - * [Where can I learn about contract development?](#where-can-i-learn-about-contract-development) - * [Where can I learn Solidity?](#where-can-i-learn-solidity) - * [Where can I learn Serpent?](#where-can-i-learn-serpent) - * [Where can I learn LLL?](#where-can-i-learn-lll) - * [Where can I learn Solidity?](#where-can-i-learn-solidity) - * [How to test contracts?](#how-to-test-contracts) - * [How to deploy contracts automatically?](#how-to-deploy-contracts-automatically) - * [Where to find example contracts?](#where-to-find-example-contracts) -* [ÐApps](#Ðapps) - * [Where can I learn about the Ethereum APIs?](#where-can-i-learn-about-the-ethereum-apis) - * [Where can I learn about ÐApp development?](#where-can-i-learn-about-Ðapp-development) - * [Where can I find ÐApp development tools?](#where-can-i-find-Ðapp-development-tools) - * [Where can I find example ÐApps?](#where-can-i-find-example-Ðapps) -* [IRC](#irc) - * [How can I join the Ethereum IRC channels?](#how-can-i-join-the-ethereum-irc-channels) - * [Where can I find the Ethereum IRC logs?](#where-can-i-find-the-ethereum-irc-logs) - * [Where can I learn about the ZeroGox bot?](#where-can-i-learn-about-the-zerogox-bot) -* [More Questions and Answers](#more-questions-and-answers) - - - -## Ethereum - -### What is Ethereum? - -There are several ways to answer this question, which are introduced on the dedicated [What is Ethereum](http://github.com/ethereum/wiki/wiki/What-is-Ethereum) wiki page. - -If you prefer to learn by watching videos, see: - + [Vitalik Buterin explains Ethereum](https://www.youtube.com/watch?v=TDGq4aeevgY) (Video, 3min) - + [Vitalik Buterin reveals Ethereum at Bitcoin Miami 2014](http://youtu.be/l9dpjN3Mwps) (Video, 28min) - + [Singularity 1 on 1: Ethereum is a Decentralized Consensus Platform](http://youtu.be/fbEtivJIfIU) (Video, 69min) - + [Our second Reddit "Ask Me Anything" for community selected questions](http://www.reddit.com/r/IAmA/comments/2bjmgb/hi_we_are_the_ethereum_project_team_ask_us/) (not actually a video) - -### Where can I learn more about Ethereum? - -- Main site: https://www.ethereum.org -- Forums: https://forum.ethereum.org -- Github: https://github.com/ethereum -- Blog: https://blog.ethereum.org -- Wiki: http://wiki.ethereum.org -- Meetups: http://ethereum.meetup.com -- Whitepaper: http://ethereum.org/ethereum.html -- Yellow Paper: http://gavwood.com/paper.pdf -- Facebook: https://www.facebook.com/ethereumproject -- Youtube: http://www.youtube.com/ethereumproject -- Google+: http://google.com/+EthereumOrgOfficial -- IRC Freenode: #ethereum (http://bitly.com/IRC_ethereum for weblink) - -### Where can I find the main project repositories? - -+ [cpp-ethereum](https://github.com/ethereum/cpp-ethereum/) ([@gavofyork](https://github.com/gavofyork), [@programmerTim](https://github.com/programmerTim), [@caktux](https://github.com/caktux)) -+ [go-ethereum](https://github.com/ethereum/go-ethereum) ([@obscuren](https://github.com/obscuren), [@maran](https://github.com/maran)) -+ [pyethereum](https://github.com/ethereum/pyethereum) ([@vbuterin](https://github.com/vbuterin), [@heikoheiko](https://github.com/heikoheiko), [@chenhouwu](https://github.com/chenhouwu)) -+ [ethereumj](https://github.com/ethereum/ethereumj) ([@romanman](https://github.com/romanman), [@nicksavers](https://github.com/nicksavers)) -+ [ethereumjs-lib](https://github.com/ethereum/ethereumjs-lib) ([@ethers](https://github.com/ethers), [@wanderer](https://github.com/wanderer)) - -### Where can I learn about the Ether sale and mining? - -+ [The Ether Sale FAQ](https://forum.ethereum.org/discussion/196/the-ether-sale-faq/p1) -+ [The Mining FAQ](https://forum.ethereum.org/discussion/197/mining-faq-live-updates/p1) - -## Clients - -### Where can I find official releases? - -+ [Releases for AlethZero](https://github.com/ethereum/cpp-ethereum/releases) -+ [Releases for Mist](https://github.com/ethereum/go-ethereum/releases) -+ [Releases for Pyethereum](https://github.com/ethereum/pyethereum/releases) - -### How to install development builds? - -+ Homebrew - + [Homebrew Ethereum](https://github.com/caktux/homebrew-ethereum) ([@caktux](https://github.com/caktux)) -+ Guides - + [AlethZero super easy install guide for OSX](https://forum.ethereum.org/discussion/1388/alethzero-super-easy-install-guide-for-osx) ([@stephantual](https://github.com/stephantual)) - + [Go-Ethereum simple build guide for OSX](http://forum.ethereum.org/discussion/905/go-ethereum-cli-ethereal-simple-build-guide-for-osx-now-with-one-line-install) ([@stephantual](https://github.com/stephantual)) - + [Building on Ubuntu](https://github.com/ethereum/cpp-ethereum/wiki/Building-on-Ubuntu#user-content-trusty-1404) -+ Builds - + [Ethdev Buildbot](http://build.ethdev.com/waterfall) - -### How to install the clients from source? - -+ [Building AlethZero (C++)](https://github.com/ethereum/cpp-ethereum/wiki) -+ [Building Mist (Go)](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum%28Go%29) -+ [Installing Pyethereum (Python)](https://github.com/ethereum/pyethereum#quickstart) -+ [Installing EthereumJ (Java)](https://github.com/ethereum/ethereumj#maven) -+ [Installing Ethereumjs-lib (JavaScript for Browser and Node)](https://github.com/ethereum/ethereumjs-lib#install) - -## Mining - -### How can I mine Ether? - -With AlethZero - -+ To process transactions - + Disable "Debug" > "Force Mining" - + Click "Mine" -+ To force mine (Use sparingly, unless stress testing) - + Enable "Debug" > "Force Mining" - + Click "Mine" - -With the eth client - -``` -# Only force mine to acquire ether or stress test -$ eth --force-mining --mining on [YOUR OPTIONS...] -``` - -### How to get free testnet Ether? - -+ [ZeroGox Wei Faucet](https://zerogox.com/ethereum/wei_faucet) ([@caktux](https://github.com/caktux)) - -## Contracts - -### Where can I learn about contract development? - -+ Articles - + [Ethereum Development Tutorial](https://github.com/ethereum/wiki/wiki/Ethereum-Development-Tutorial) -+ Videos - + [Ethereum](https://www.youtube.com/user/ethereumproject/videos) - + [EtherCasts](https://www.youtube.com/user/EtherCasts/videos) - -### Where can I learn Serpent, the Python-like language? - -+ Specifications - + [The Serpent Language](https://github.com/ethereum/wiki/wiki/Serpent) -+ Examples - + [Vitalik's Serpent examples](https://github.com/ethereum/serpent/tree/master/examples) -+ Tutorials - + [Pyethereum and Serpent Programming Guide](https://blog.ethereum.org/2014/04/10/pyethereum-and-serpent-programming-guide/) -+ Videos - + [Learn Ethereum with Vitalik](https://www.youtube.com/watch?v=nXYDfLCLmMs) - -### Where can I learn LLL, the Lisp-like language? - -+ Specifications - + [The LLL Language](https://github.com/ethereum/cpp-ethereum/wiki/LLL-PoC-6) -+ Examples - + [LLL examples for PoC 6](https://github.com/ethereum/cpp-ethereum/wiki/LLL%20Examples%20for%20PoC%205) -+ Videos - + [Programming Society with Asm](https://www.youtube.com/watch?v=xO1AxsYAkU8) - -### Where can I learn Solidity, the JavaScript-like language? - -+ Specifications - + [Solidity, Docs and ABI](https://github.com/ethereum/cpp-ethereum/wiki/Solidity%2C-Docs-and-ABI) - + [Solidity Features](https://github.com/ethereum/wiki/wiki/Solidity-Features) -+ Tutorials - + [Solidity Tutorial](https://github.com/ethereum/wiki/wiki/Solidity-Tutorial) - + [Contract Writing in Solidity](https://dappsforbeginners.wordpress.com) - -### How to test contracts? - -+ [EVM Contract Simulator](https://github.com/EtherCasts/evm-sim/) ([@EtherCasts](https://github.com/EtherCasts)) -+ [Pyethereum Tester](https://github.com/ethereum/pyethereum/blob/master/tests/test_contracts.py) ([@ethereum](https://github.com/ethereum)) - -### How to deploy contracts automatically? - -+ [Ethereum Package Manager](https://github.com/project-douglas/epm) - -### Where to find example contracts? - -+ Serpent - + [By Vitalik Buterin](https://github.com/ethereum/serpent/tree/master/examples) ([@vbuterin](https://github.com/vbuterin)) - + [By EtherCasts](https://github.com/EtherCasts) ([@EtherCasts](https://github.com/EtherCasts)) - + [By Rob Myers](https://github.com/robmyers/artworld-ethereum) ([@robmyers](https://github.com/robmyers)) - + [By Tyler Florez](https://github.com/qualiabyte/ethereum-contracts) ([@qualiabyte](https://github.com/qualiabyte)) -+ LLL - + [By Gavin Wood](https://github.com/ethereum/cpp-ethereum/wiki/LLL%20Examples%20for%20PoC%205) ([@gavofyork](https://github.com/gavofyork)) - + [By Dennis Mckinnon](https://github.com/dennismckinnon/Ethereum-Contracts) ([@dennismckinnon](https://github.com/dennismckinnon)) - + [By Project Douglas](https://github.com/project-douglas/eris/tree/master/contracts) ([@project-douglas](https://github.com/project-douglas)) - + [By Doug A.](https://github.com/d11e9/g3) ([@dlle9](https://github.com/d11e9)) - -## ÐApps - -### Where can I learn about the Ethereum APIs? - -+ [The PoC 6 API for C++](https://github.com/ethereum/cpp-ethereum/wiki/Client-Development-with-PoC-6) -+ [The PoC 5 API for Go](https://github.com/ethereum/go-ethereum/wiki/PoC-5-Public-Go-API) -+ [The PoC 6 API for QML](https://github.com/ethereum/go-ethereum/wiki/QML-PoC6-API) -+ [The PoC 7 API for JavaScript](https://github.com/ethereum/wiki/wiki/JavaScript-API) - -### Where can I learn about ÐApp development? - -+ [Writing Your Own Currency](http://hidskes.com/blog/2014/05/21/ethereum-dapp-development-for-web-developers/) ([@maran](https://github.com/maran)) - -### Where can I find ÐApp development tools? - -Official - -+ [AlethZero GUI client (C++)](https://github.com/ethereum/cpp-ethereum/wiki/Using-AlethZero) -+ [Eth command-line client (C++)](https://github.com/ethereum/cpp-ethereum/wiki/Using-Ethereum-CLI-Client) -+ [LLLC Compiler (C++)](https://github.com/ethereum/cpp-ethereum/blob/develop/lllc/main.cpp) -+ [Ethereum command-line client (Go)](https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options) -+ [Mist Browser (Go)](https://github.com/ethereum/go-ethereum) -+ [Pyeth command-line client (Python)](https://github.com/ethereum/pyethereum#interacting-with-the-network) -+ [Serpent Compiler (Python)](https://github.com/ethereum/wiki/wiki/Serpent) - -Community - -+ [C3D](https://github.com/project-douglas/c3d) ([@project-douglas](https://github.com/project-douglas)) -+ [Emacs LLL Mode](https://github.com/robmyers/lll-mode) ([@robmyers](https://github.com/robmyers)) -+ [Emacs Serpent Mode](https://github.com/robmyers/serpent-mode) ([@robmyers](https://github.com/robmyers)) -+ [EPM](https://github.com/project-douglas/epm) ([@project-douglas](https://github.com/project-douglas)) -+ [EPM Sublime Plugin](https://github.com/project-douglas/epm-sublime) ([@project-douglas](https://github.com/project-douglas)) -+ [Ethos Browser](https://github.com/projectdnet/ethos) ([@projectdnet](https://github.com/projectdnet)) -+ [EVM-Sim](https://github.com/EtherCasts/evm-sim/) ([@EtherCasts](https://github.com/EtherCasts)) -+ [MintChalk](http://www.mintchalk.com/) ([@mintchalk](https://github.com/mintchalk)) -+ [Poly-Eth](https://github.com/projectdnet/poly-eth) ([@projectdnet](https://github.com/projectdnet)) - -### Where can I find example ÐApps? - -+ [dapp-bin](https://github.com/ethereum/dapp-bin) ([@ethereum](https://github.com/ethereum)) -+ [GavCoin](http://gavwood.com/gavcoin.html) ([@gavofyork](https://github.com/gavofyork)) -+ [JeffCoin](https://github.com/obscuren/jeffcoin) ([@obscuren](https://github.com/obscuren)) -+ [Make It Rain](https://github.com/EtherCasts/make-it-rain) ([@EtherCasts](https://github.com/EtherCasts)) -+ [Chronos](https://github.com/mquandalle/chronos) ([@mquandalle](https://github.com/mquandalle)) -+ [Artworld-Ethereum](https://github.com/robmyers/artworld-ethereum) ([@robmyers](https://github.com/robmyers)) -+ [Eris](https://github.com/project-douglas/eris) ([@project-douglas](https://github.com/project-douglas), [@compleatang](https://github.com/compleatang), [@dennismckinnon](https://github.com/dennismckinnon)) -+ [CryptoCoinWatch](https://github.com/EtherCasts/cryptocoinwatch) ([@EtherCasts](https://github.com/EtherCasts)) -+ [Occam's Run](https://github.com/d11e9/Occams-Run) ([@d11e9](https://github.com/d11e9)) -+ [TrustDavis](https://github.com/EtherCasts/trustdavis) ([@EtherCasts](https://github.com/EtherCasts)) - -## IRC - -### How can I join the Ethereum IRC channels? - -+ [Chat with the ethereum dev community on IRC!](https://forum.ethereum.org/discussion/1495/chat-with-the-ethereum-dev-community-on-irc) - -### Where can I find the Ethereum IRC logs? - -+ [The ZeroGox logs](https://zerogox.com/bot/log) - -### Where can I learn about the ZeroGox bot? - -+ [The ZeroGox bot](https://zerogox.com/bot) - -# More Questions and Answers - -+ [FAQ by @fivedogit](https://docs.google.com/document/d/14EIe984_86Y-uuNm-a4EsVeD3eI4qAAlz_MZof1qkqM/) \ No newline at end of file diff --git a/First-steps-with-ethereum-JSON-RPC.md b/First-steps-with-ethereum-JSON-RPC.md deleted file mode 100644 index dc9aa988a..000000000 --- a/First-steps-with-ethereum-JSON-RPC.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -name: First Steps wih Ethereum JSON RPC -category: ---- - -# First steps with ethereum JSON-RPC - - -#### 1. clone cpp-ethereum or install it - -##### manual installation - -```bash -git clone https://github.com/ethereum/cpp-ethereum -cd cpp-ethereum -mkdir build -cd build -cmake .. -make -j 4 -``` - -##### automatic installation - -build instructions are [here](https://github.com/ethereum/cpp-ethereum/wiki/Installing-clients) - - -#### 2. run eth (headless client) - -```bash -eth -j -``` - -`-j` option will start ethereum node with jsonrpc http server at port 8080 - -etheruem should be ready to use now - -type in console to check if everything is working fine - -``` -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":83}' http://localhost:8080 -``` - -#### 3. mine and connect to the network - -try running - -```bash -eth -j -m true -f -b -``` - -where: -- `-m true` - to do anything in ethereum, you need some ethere, let's mine -- `-f` - mine with force, even if there are no transactions to mine -- `-b` - connect to ethereum network - -*with latest version of cpp-ethereum it may take some time to connect to network. If you see any delays with jsonrpc responses, or crashes contant us. We are probably aware of them, but it's good to know about any possible vulnerability* - -#### 4. json-rpc methods, that you might be intrested in: - -- [eth_sendTransaction](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sendtransaction) - used to send transaction / create contract -- [eth_newBlockFilter](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_newblockfilter) - be notified any time there is new block on the chain -- [eth_newFilter](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_newfilter) - create new custom filter and listen to blockchain events matching this filter -- [eth_compileSolidity](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_compilesolidity) - used to compile solidity code - - - - - - - - - - - - - - - - - - - diff --git a/Fortnight-In-Ethereum-Template.md b/Fortnight-In-Ethereum-Template.md deleted file mode 100644 index 6f6e934bf..000000000 --- a/Fortnight-In-Ethereum-Template.md +++ /dev/null @@ -1,412 +0,0 @@ ---- -name: Fortnight in Ethereum Template -category: ---- - -This document exists to collate information once a fortnight (biweekly) from the various different aspects/projects taking place in Ethereum which will allow everyone to better understand what everyone else is working on. - - -###Current Status of the project - -What is the overall current of status of the Ethereum project? What is the next goal? - - -##Clients/Protocol - -###CPP - -**What's the current status of what you're working on?** -Nearing release of PoC 9 (Mar 6): -* new PoW -* structured logging -* peer selection strategy for node discovery -* rlpx wireline protocol (interop w/Go client) - -**What progress has been made in the last two weeks?** -Release of PoC 8: -* Improved networking & peer discovery -* evm testing -* updates for compliance w/YP -* rpc/ethereum-js updates, bug fixes, interop -* dapp loading -* continued development of solidity features -* continued development for chromium support -* updates for natspec support - -**What are the next steps?** -Further preparation for release. - -###Go/Mist - -**What's the current status of what you're working on?** -Improving networking encryption, optimising block processing, refining Mist UI - -**What progress has been made in the last two weeks?** -Release of PoC 8 including: - - * Improved UI and UX - - * Multithreaded miner - - * Updated RPC interface - - * Improved networking & peer discovery - - * Moved from WebKit to Chromium rendering engine (QtWebEngine) - -**What are the next steps?** -Finalising command-line interface and polishing Mist components in preparation for beta - -###Node Ethereum - -**What's the current status of what you're working on?** -* Networking is the biggest issue ATM. -* RPC compliance - -**What progress has been made in the last two weeks?** -* adding rlpx - + Wrote DHT code (https://github.com/ethereum/ethereumjs-dht) -* Testing - + Fixed a several VM bugs caught be the tests -* Finalized a new ethereumjs-lib version - + Unified block/tx/code processing API - + simplified browser shims - + Cleaned up Docs - -**What are the next steps?** -* RLPx - + added encryption -* More RPC tests - -###Pythereum - -**Status** -PV 52 (currently no interop w/ cpp/go) - -**What's the current status of what you're working on?** -We are currently in a major cleanup and refactoring phase with the goals to: - -* replace threading by an event loop architecture - -* add rlpx/devp2p https://github.com/heikoheiko/pydevp2p - -* split pyetherum up into three repositories, the base library (vm, chain, ...), the networking stack (should work w/o the pyeth lib), and the actual python based client - -**What progress has been made in the last two weeks?** -* devp2p discovery & rlpx is mostly done but not yet integrated with the pyethereum client - -* Solidity & ABI support were added - -* restructured vm tests - -**What are the next steps?** -refactoring sprint to restore interop based on the new architecture - -**Other news?** -Jannik is doing a two month internship in the Berlin office and helps to clean up and document the code. - -###POC8 Protocol -**What's the current status of what you're working on?** -PoC8 protocol is done. - -**What progress has been made in the last two weeks?** -PoC8 has been released. - -**What are the next steps?** -PoC9. - -###POC9 Protocol -**What's the current status of what you're working on?** -There are a number of changes that security auditors have suggested, and we are currently in the process of implementing them. We are also in the process of finalizing our PoW implementation. - -**What progress has been made in the last two weeks?** -Work on mining, and security audit meetings in which we discussed some of the upcoming protocol changes. - -**What are the next steps?** -Finish it. - -###Mix - -**What's the current status of what you're working on?** -First public version was released with poc8 recently. Currently working on new features. - -**What progress has been made in the last two weeks?** -Done major UI redesign for poc8 release. -Deploy contracts to network story has been implemented. -Various issues for Windows and OS X platforms resolved. - -**What are the next steps?** -Solidity source level debugging story. - -###Swarm - -**What's the current status of what you're working on?** -It is in an advanced prototype stage, fully functional, but generating much more than necessary traffic over the network. - -**What progress has been made in the last two weeks?** -Integration with the newest developments in the go client, especially, but not exclusively the new peer discovery system that would allow us to optimize network traffic and client load. - -**What are the next steps?** -Besides merging with the main development branch, which requires unification of command line and configuration options with Whisper (i.e. a similar set of configuration options should be available for Swarm), some documentation needs to be written in order to help people play with it. - -###Whisper - -**What's the current status of what you're working on?** - -**What progress has been made in the last two weeks?** - -**What are the next steps?** - -###Yellow Paper (recent changes) - -**What's the current status of what you're working on?** -We're almost done implementing the new RLPx protocol -in go-ethereum. - -**What progress has been made in the last two weeks?** -We have released the node discovery part of RLPx in PoC 8 -and it seems to be working for most people. -We ran various simulations of peer connecting strategies to study their influence on network well-formedness. https://docs.google.com/spreadsheets/d/1Xsg0367XibBCg1HegKoInrarLmU_ozwlBLPatv0hhEY/edit?usp=sharing - -**What are the next steps?** -We will implement the remaining parts of the protocol (Encryption -Handshake, authenticated packets) and define a peer selection -strategy. - -###Dev P2P - -**What's the current status of what you're working on?** -We're almost done implementing the new RLPx protocol -in go-ethereum. - -**What progress has been made in the last two weeks?** -We have released the node discovery part of RLPx in PoC 8 -and it seems to be working for most people. - -**What are the next steps?** -We will implement the remaining parts of the protocol (Encrytion -Handshake, authenticated packets) and define a peer selection -strategy. - -##Languages - -###Solidity - -**What's the current status of what you're working on?** -Solidity is now able to compile the multisig wallet contract (preliminary version: https://github.com/chriseth/dapp-bin/blob/compilingWallet/wallet/wallet_work_in_progres.sol). - -**What progress has been made in the last two weeks?** -In the last two weeks, we completed enums, visibility specifiers, accessors and a first byte array type. Especially the "external" visibility specifier and the byte array made it possible to "store" call data for later use and implement the forwarding feature of the multisig wallet. - -**What are the next steps?** -The next big features are array types and debugging support. In general, we will probably focus less on generic language features and more on usability. - -###Serpent - -**What's the current status of what you're working on?** -Serpent is close to full-featured, and is the backbone of many projects including augur and btcrelay. Strings and arrays are fully supported, as is the PoC8 contract ABI. - -**What progress has been made in the last two weeks?** -Testing and bug fixing mostly. Also, the pyethereum.tester environment has been substantially improved, making it highly interoperable with serpent functions (and solidity functions). - -**What are the next steps?** -Perhaps proper strong typing, we'll see. But ultimately I would like to see serpent become a community project, and have many others and not just myself maintaining and contributing code. - - -##Release - -###System testing project - -**What's the current status of what you're working on?** -* Infrastructure to automatically - + provision N (5..200) ec2 instances - + with the latest go-client from buildbot - + create deterministic configurations for all N clients - + run basic test scenarios - + log events in a computer readable json format - + collect logs in a central elasticsearch database - + automatically analyze the logs to decide on scenario success - -* Implemented scenarios: - + Start clients - + Connect clients - -**What progress has been made in the last two weeks?** -* finalized log event spec (for the first scenarios) https://github.com/ethereum/system-testing/wiki/Log-Events -* added support for multiple clients -* added go client -* first working scenarios (start/connect clients) - -**What are the next steps?** -* More Basic Scenarios - + Chain consensus scenario with mining clients - + TX propagation scenario - -* Automatic triggering of all scenarios based on new buildbot builds -* Automatic notification of devs in case of failures - -Later advanced scenarios as listed here: https://github.com/ethereum/system-testing/issues?q=is%3Aopen+is%3Aissue+label%3A%22test+scenario%22 - -###Testing - -**What's the current status of what you're working on?** -After the creation of the tools for the block tests, I am now actually writing different tests to ensure that all clients have the same definition on a valid block (in form of an RLP). - -**What progress has been made in the last two weeks?** -Beside the creation of some transaction tests, Block tests have been added (https://github.com/ethereum/tests/wiki/Block-Tests). - -**What are the next steps?** -I will add Blockchain tests, which probably will be the last type of tests. With this we have VM tests, state tests, transaction tests, block tests and blockchain tests. This will be sufficient to test almost eveything written in the YP. - -###Build System - -**What's the current status of what you're working on?** -The build system has received major upgrades and is really starting to cover every aspect of the build process and packaging of the different projects on all platforms. OSX users now benefit from pre-compiled "bottles" using brew along with readily available binaries of Mist and AlethZero for the less technically inclined. There are also packages for Ubuntu for both projects, although the upgrade Qt 5.4 still has unresolved issues. The build server also uses https only for obvious reasons. -Pull requests are now being checked across 7 different builders with even more to come, assuring much better quality code merges. - -**What progress has been made in the last two weeks?** -Half of what is mentioned above, let's say it's all recent enough :) Joris Bontje has also made a very nice looking and useful Buildboard at http://ethereum-buildboard.meteor.com/ - -**What are the next steps?** -Full integration tests, from contract deployments, transactions to those, and full assertions of expected results in a DApp's UI. This should be in place by the end of the week if not today the 24th. - -###JSON RPC - -**What's the current status of what you're working on?** - -**What progress has been made in the last two weeks?** - -**What are the next steps?** - -###Security Audit - -**What's the current status of what you're working on?** -We are currently in the middle of the security audit, our main auditor is looking at the design and the code base, further auditors are looking at focus topics like networking. We are in continuous exchange, responding to raised issues, providing further required information. - -**What progress has been made in the last two weeks?** -Ongoing development of the p2p/networking protocol and PoW algorithm required some recent rearrangement of the auditing schedule. Issues raised by auditors and submitted by bounty hunters have been mitigated. - -**What are the next steps?** -We will focus on the networking and p2p/networking protocol to minimize delays. - -###Dapps - -**What's the current status of what you're working on?** -Improving and streamlining the ethreuem.js APIand RPC endpoints. - -**What progress has been made in the last two weeks?** -Build a full featured whisper chat dapp and the wallet dapp interface. - -**What are the next steps?** -Finalising the wallet app, when the ethereum.js api and RPC is working properly. - -###ET Hash - -**What's the current status of what you're working on?** -We are on Revision 16 now. - -**What progress has been made in the last two weeks?** -There is now a go client, an opencl client. - -**What are the next steps?** -We are working on integration with the Go client and hopefully other clients prior to launch. - -###Vapor - -**What is it?** -Dapp runtime environment + contract browser webapp -think MIST built on node-ethereum - -**What's the current status of what you're working on?** -Early stages. Currently working on basic PoC. - -**What progress has been made in the last two weeks?** -Decided on tools and created multi-target build system. -Started RPC communication with node-ethereum. -Initial wireframes and logos generated by designer (Jef Cavens) - -**What are the next steps?** -Finish basic identity management and wallet view. -Package node-ethereum with native builds. -Build Dapp runtime environment. - -###Launch -**Launch Date?** -Ask me after Zug! - -**Which Apps will be available?** -No idea, I just got hired and I don't know anything yet! - -**Which Exchanges will be integrated?** -I'll ask George! - -##Leadership - -###Foundation - -**What's the current status of what you're working on?** -Currently we are focusing our attention on the Genesis launch, making sure that all the aspects involved in the release are taken care off. We are also experimenting with an open collaboration system designed to create the favorable conditions for developers to unleash their creativity and build amazing things with ethereum. - -**What progress has been made in the last two weeks?** -Intense brainstorming and discussions regarding the launch strategy and how to best nurture the growth of the ethereum community and ecosystem as a whole. - -**What are the next steps?** -Coordinate with comms, dev and the community in order to concretize the ethereum Genesis launch strategy. Regarding post-Genesis plans, there will be a number of exciting announcements coming in the following weeks ^_^ - -##Communications - -###Meetups - -**What's the current status of what you're working on?** -Comms has been focused on ethereum.org and bounty sites for the last month and a half. I was tasked with design and front end development. Have moved back to meetups full time now. Working on Ethereum 101, Genesis Block Party, regrouping and strategizing for launch. - -**What progress has been made in the last two weeks?** -Have moved away from design and development. Developed idea for the Genesis Block Party and have begun to work with meetup organizers to have a day of meetups around launch. Group skypes have occurred every thursday, ramping up to daily meetings. - -**What are the next steps?** -Concretize the Block Party, Finish the slides for 101 series. Get swag together for launch parties. - -###Upcoming Events - -**What's the current status of what you're working on?** -Working with meetup organizers on Genesis Block Parties - -**What progress has been made in the last two weeks?** -Working with Sarah Masare from Silicon Valley, Cameron and Peter Van Garderen from Vancouver on formalizing the Genesis Block Party. - -**What are the next steps?** -Confirm release date, get swag printed, have meetups sign on for block party - -###Comms - -**What's the current status of what you're working on?** -Currently the comms team is working on the new Ethereum website (which is our main focus until complete in the next week or so). We're also continuing maintain the various social media outlets Ethereum utilises to update and interface with the community to reach out to various companies, journalists etc to spread the word of Ethereum. Ken Kappler continues to write various tutorials (which will continue to be released as we reach stability) and content for the future Ethereum Academy website. Unfortunately Stephan Tual has been taken ill and will be unavailable for a week or so :( (get well soon!) - -**What progress has been made in the last two weeks?** -Having completed the bounty website just before, Ian and Konstantine are nearing completion of the Ethereum.org website with content now being provided by myself, Gavin and Vitalik. -In the last two weeks we have also been working on reaching out to various exchanges and possible parters for Ethereum as we move forward to the genesis release. - -**What are the next steps?** -Release the website! Continue reaching out to various entites that could potentially align themselves with Ethereum. We also have raw video footage that will be processed once Ian is free for doing the website design. - -###Ether Academy Website/Ethdev Website - -**What's the current status of what you're working on?** -Jr Bedard (of ether.fund) has been contracted to build a new Code Academy type site for teaching developers to build smart contracts. - -**What progress has been made in the last two weeks?** -Development is continuing nicely, the framework of handling user accounts is almost in place. - -**What are the next steps?** -Design decisions, content creation. - -###In the Media - -**What's the current status of what you're working on?** -Putting together various responses for journalists (spectator, coin telegraph etc) that have been in contact. Working with companies using ethereum for joint press releases/coverage. - -**What progress has been made in the last two weeks?** -We had a great article in Vice/Motherboard... (motherboard.vice.com/read/smart-contracts-sound-boring-but-theyre-more-disruptive-than-bitcoin - -**What are the next steps?** -ojn \ No newline at end of file diff --git a/Generalized_Merkle_DHT.md b/Generalized_Merkle_DHT.md deleted file mode 100644 index 2bfd4a8df..000000000 --- a/Generalized_Merkle_DHT.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -name: Generalized Merkle DHT -category: ---- - -As blockchain technologies move beyond the "1.0" model of every node processing every transaction, and a more diverse ecosystem including "light clients" that achieve security by downloading only a small portion of the blockchain and extracting the rest of the data on-demand through hash-based authentication comes into play, and particularly in the long term as scalability models essentially turn _every_ node into a light client, there arises the need to develop a strong, robust and effective networking infrastructure to handle the load. Ideally, the core technology should be built to be maximally generalized, so that the same core code and network can be used for multiple blockchain, as well as non-blockchain, applications. - -The kernel of the work is the distributed hash table, as pioneered by projects such as [Kademlia](http://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf) and implemented in BitTorrent and now IPFS. The distributed hash table uses a network where nodes are organized to point to other nodes in such a way that, given a value `v` with a key `k`, a node knowing `k` can quickly discover the location of the node that stores `v`; usually we say `k = H(v)` for some hash function (eg. SHA256, SHA3). Theoretically, such a DHT can be used to very easily enable light client support for _any_ blockchain protocol with sufficiently high degrees of Merkle tree support, and even use one codebase for light and full clients, the only difference being that light clients would use the DHT as a "hard drive" in place of their actual computer disks. - -However, this model has an important flaw: it requires `log(n)` lookups in order to receive a proof. Hence, if the network latency is 500ms, and a tree has a depth of 10 nodes, then the total lookup and verification will take at least five seconds. Simpler light client protocols tend to avoid this obstacle by simply having a "request-response" model: light node A wants a proof for X, full node B provides _all_ relevant Merkle nodes, and light node A verifies. The DHT approach has the benefit of extreme generality; the dedicated Merkle proof approach has the benefit of higher speed. However, we can arguably combine the benefits of both. - -The protocol at base level is as follows: suppose there exists a program `P` with an initial state `S_0`, run in a virtual machine which has access to an `INVHASH` ("inverse hash") opcode. `P` may be a simple iterative descent script to fetch a Merkle tree node, or it may be a complete proof of transaction correctness, or even a search process. Suppose there exists a light client which wants `P(h)` given some "root hash" value `h`, together with a proof; we consider `h` part of `S_0`. The light client initializes `D <- {}`, `S <- S_0` and repeatedly undergoes the following process: - -1. Run `P` until it encounters either an end state (in which case exit) or an `INVHASH` opcode with argument `k`, such that the node does not know a value `v` such that `sha3(v) = k`. -2. Let `S_c` be the current state after this point. Set `S <- S_c` -3. Send a message `(P, S_c)` to another node on the network, using `k` as a pointer to finding that node (eg. via the Kademlia algorithm) -4. That node initializes `D' <- {}`, and runs `P` until it encounters an `INVHASH` opcode with argument `k`, such that the node does not know a value `v` such that `sha3(v) = k`. It immediately halts and replies back with `D'` -5. Merge `D'` into `D` (ie. set `D <- D U D'`), and go to step 1. - -Essentially, the light client repeatedly asks a node on the network "run this program as long as you can until you find a value you cannot resolve, then reply back to me with the values you did manage to resolve", and keeps on accumulating nodes in its hash until eventually it can locally run through the entire program. - -This process takes: - -* Linear time in the number of computational steps (as every step of execution, assuming honesty, is computed a maximum of exactly twice, once by the local node and once by the remote node) -* Anywhere from constant to linear time in the number of `INVHASH` executions, depending on what portion of all available key/value pairs every node has and how well they are clustered - -It can be viewed as a superset of a DHT and Bitcoin-style SPV protocols, and is adaptable to state get operations, transaction proofs, receipt lookups, search operations, trie next/prev operations, proofs of non-membership, and generally any kind of computation on blockchain data. If implemented correctly it can be used for both Ethereum, Bitcoin proposals such as tree chains, and even parts of a decentralized search engine. - -In order to prevent abuse, the program execution instance will naturally need to have a gas limit. There are two ways of doing this: - -1. Have a hard fixed limit (eg. 1 million), and rely on the same anti-DDoS techniques that are normally used for messages that have a bounded response time. -2. Require each `(P, S)` message to specify a gas limit, and require either proof of work or a micropayment in exchange. If there is not enough gas, then simply return just as if you have encountered an `INVHASH` you cannot resolve. However, this protocol may not be optimal when there is high uncertainty about when unresolvable `INVHASH` operations will pop up. -3. The sending party creates a ticket which says "I am willing to pay $X per step". The receiving party signs their reply message. The sender must then micro-pay after the fact. If the sender does not do so honestly, then the receiver can "go to blockchain court" and have the auditing contract verify the correct payment to be made, and if the correct payment was not in fact made force the sender to pay a fine. \ No newline at end of file diff --git a/Geth-Dapp-loading-proposal.md b/Geth-Dapp-loading-proposal.md deleted file mode 100644 index a24ca2799..000000000 --- a/Geth-Dapp-loading-proposal.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -name: Geth DAPP Loading Proposal -category: ---- - -To have a simple way to load and start Dapps vinay and I came up with a great idea: - -1. Dapp packages can be downloaded as .zip/.rlp/.dapp - - they will contain a `dapp.json` with author info and a dapp name and version. - - and a `swarm.json`, with all the file paths and hashes, [see here](https://github.com/ethereum/go-ethereum/wiki/URL-Scheme#server-config-examples)) - -2. run `$ geth install mydapp.zip`, which will verify, extract and copy the dapp locally somewhere. -**Note** This could also get a name reg domain and looks up the hash an content online, fetches it and installs it. - -3. run `$ geth start mydapp` will start a node, with the correct options (rpc, corsdomain etc) and start a local server which points with its root into the dapps folder and resolves path and files through the `swarm.json` - -4. goto `http://localhost:5555` to see you dapp running (needs to be thought of, as dapps would share localstorage, maybe use a different and reusable port per dapp) - -## Update - -- run `$ geth update mydapp.zip`, which will extract, and overwrites the old dapp files - -## Bundle dapp - -- run `$ geth bundle myDappFolder/dist/`, which will create a dapp bundle from a folder, to share with others. - -- run `$ geth deploy myDappFolder/dist/` could save it to pastebin and register it in namereg. diff --git a/Gitter-Channels.md b/Gitter-Channels.md deleted file mode 100644 index 89d323787..000000000 --- a/Gitter-Channels.md +++ /dev/null @@ -1,44 +0,0 @@ -https://gitter.im/ethereum - -# Node Software ("Clients") - -## Go - -https://gitter.im/ethereum/go-ethereum - -## CPP - -https://gitter.im/ethereum/cpp-ethereum - -## Python - -https://gitter.im/ethereum/pyethapp - the client - -https://gitter.im/ethereum/pyethereum - the core library (evm, blocks, txs, ...) - -https://gitter.im/ethereum/pydevp2p - p2p network - -# DApp Development - -https://gitter.im/ethereum/web3.js - -https://gitter.im/ethereum/mist - -https://gitter.im/ethereum/solidity - -https://gitter.im/ethereum/serpent - -# Other - -https://gitter.im/ethereum/porting - -https://gitter.im/ethereum/research - -# Protocol - -https://gitter.im/ethereum/devp2p - -https://gitter.im/ethereum/light-client - - - diff --git a/Glossary.md b/Glossary.md deleted file mode 100644 index 06dd59b44..000000000 --- a/Glossary.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -name: Glossary -category: ---- - -One of the things that cryptocurrency, and really any new genre of technology, is notorious for is the sheer quantity of vocabulary that gets generated to describe all of the new concepts. Anyone dealing with peer-to-peer internet software on anything more than a casual basis needs to deal with concepts of cryptography, including hashes, signatures and public and private keys, symmetric and asymmetric encryption, denial of service protection, as well as arcane constructions such as distributed hash tables and webs of trust. New Bitcoin users are forced to contend with learning not just the common basics of cryptography, but also additional internal jargon such as "blocks", "confirmations", "mining", "SPV clients" and "51% attacks", as well as economic concepts like incentive-compatibility and the fine nuances of centralization and decentralization. Ethereum, being a decentralized application development platform based on a generalization of a cryptocurrency, necessarily incorporates both of these sets of concepts, as well as adding many of its own. To help anyone new to Ethereum, whether they are in it as cryptocurrency enthusiasts, business owners, social or political visionaries, web developers or are simply ordinary people looking to see how the technology can improve their lives, the following list is intended to provide a basic summary of the vocabulary that Ethereum users often tend to use: - -### Cryptography - -See also: http://en.wikipedia.org/wiki/Public-key_cryptography - -* **Computational infeasibility**: a process is computationally infeasible if it would take an impracticably long time (eg. billions of years) to do it for anyone who might conceivably have an interest in carrying it out. Generally, 280 computational steps is considered the lower bound for computational infeasibility. -* **Hash**: a hash function (or hash algorithm) is a process by which a document (ie. a piece of data or file) is processed into a small piece of data (usually 32 bytes) which looks completely random, and from which no meaningful data can be recovered about the document, but which has the important property that the result of hashing one particular document is always the same. Additionally, it is crucially important that it is computationally infeasible to find two documents that have the same hash. Generally, changing even one letter in a document will completely randomize the hash; for example, the SHA3 hash of "Saturday" is `c38bbc8e93c09f6ed3fe39b5135da91ad1a99d397ef16948606cdcbd14929f9d`, whereas the SHA3 hash of Caturday is `b4013c0eed56d5a0b448b02ec1d10dd18c1b3832068fbbdc65b98fa9b14b6dbf`. Hashes are usually used as a way of creating a globally agreed-upon identifier for a particular document that cannot be forged. -* **Encryption**: encryption is a process by which a document (**plaintext**) is combined with a shorter string of data, called a **key** (eg. `c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4`), to produce an output (**ciphertext**) which can be "decrypted" back into the original plaintext by someone else who has the key, but which is incomprehensible and computationally infeasible to decrypt for anyone who does not have the key. -* **Public key encryption**: a special kind of encryption where there is a process for generating two keys at the same time (typically called a **private key** and a **public key**), such that documents encrypted using one key can be decrypted with the other. Generally, as suggested by the name, individuals publish their public keys and keep their private keys to themselves. -* **Digital signature**: a digital signing algorithm is a process by which a user can produce a short string of data called a "signature" of a document using a private key such that anyone with the corresponding public key, the signature and the document can verify that (1) the document was "signed" by the owner of that particular private key, and (2) the document was not changed after it was signed. Note that this differs from traditional signatures where you can scribble extra text onto a document after you sign it and there's no way to tell the difference; in a digital signature any change to the document will render the signature invalid. - -### Blockchains - -See also: https://bitcoin.org/en/vocabulary - -* **Address**: an address is essentially the representation of a public key belonging to a particular user; for example, the address associated with the private key given above is `cd2a3d9f938e13cd947ec05abc7fe734df8dd826`. Note that in practice, the address is technically the hash of a public key, but for simplicity it's better to ignore this distinction. -* **Transaction**: a transaction is a document authorizing some particular action associated with the blockchain. In a currency, the dominant transaction type is sending currency units or tokens to someone else; in other systems actions like registering domain names, making and fulfilling trade offers and entering into contracts are also valid transaction types. -* **Block**: a block is a package of data that contains zero or more transactions, the hash of the previous block ("parent"), and optionally other data. The total set of blocks, with every block except for the initial "genesis block" containing the hash of its parent, is called the **blockchain** and contains the entire transaction history of a network. Note that some blockchain-based cryptocurrencies instead use the word "ledger" for a blockchain; the two are roughly equivalent, although in systems that use the term "ledger" each block generally contains a full copy of the current state (eg. currency balances, partially fulfilled contracts, registrations) of every account allowing users to discard outdated historical data. -* **Account**: an account is the entry in a ledger, indexed by its address, that contains the complete data about the state of that account. In a currency system, this involves currency balances and perhaps unfulfilled trade orders; in other cases more complex relationships may be stored inside of accounts. -* **Proof of work**: one important property of a block in Bitcoin, Ethereum and many other crypto-ledgers is that the hash of the block must be smaller than some target value. The reason this is necessary is that in a decentralized system anyone can produce blocks, so in order to prevent the network from being flooded with blocks, and to provide a way of measuring how much consensus there is behind a particular version of the blockchain, it must in some way be hard to produce a block. Because hashes are pseudorandom, finding a block whose hash is less than `0000000100000000000000000000000000000000000000000000000000000000` takes an average of 4.3 billion attempts. In all such systems, the target value self-adjusts so that on average one node in the network finds a block every N minutes (eg. N = 10 for Bitcoin and 1 for Ethereum). -* **Nonce**: a meaningless value in a block which can be adjusted in order to try to satisfy the proof of work condition -* **Mining**: mining is the process of repeatedly aggregating transactions, constructing a block and trying difference nonces until a nonce is found that satisfies the proof of work condition. If a miner gets lucky and produces a valid block, they are granted a certain number of coins as a reward as well as all of the transaction fees in the block, and all miners start trying to create a new block containing the hash of the newly generated block as their parent. -* **Stale**: a stale is a block that is created when there is already another block with the same parent out there; stales typically get discarded and are wasted effort. -* **Fork**: a situation where two blocks are generated pointing to the same block as their parent, and some portion of miners see one block first and some see the other. This may lead to two blockchains growing at the same time. Generally, it is mathematically near-certain that a fork will resolve itself within four blocks as miners on one chain will eventually get lucky and that chain will grow longer and all miners switch to it; however, forks may last longer if miners disagree on whether or not a particular block is valid. -* **Double spend**: a deliberate fork, where a user with a large amount of mining power sends a transaction to purchase some produce, then after receiving the product creates another transaction sending the same coins to themselves. The attacker then creates a block, at the same level as the block containing the original transaction but containing the second transaction instead, and starts mining on the fork. If the attacker has more than 50% of all mining power, the double spend is guaranteed to succeed eventually at any block depth. Below 50%, there is some probability of success, but it is usually only substantial at a depth up to about 2-5; for this reason, most cryptocurrency exchanges, gambling sites and financial services wait until six blocks have been produced ("six confirmations") before accepting a payment. -* **SPV client** (or **light client**) - a client that downloads only a small part of the blockchain, allowing users of low-power or low-storage hardware like smartphones and laptops to maintain almost the same guarantee of security by sometimes selectively downloading small parts of the state without needing to spend megabytes of bandwidth and gigabytes of storage on full blockchain validation and maintennance. - -### Ethereum Blockchain - -See also: http://ethereum.org/ethereum.html - -* **Serialization**: the process of converting a data structure into a sequence of bytes. Ethereum internally uses an encoding format called recursive-length prefix encoding (RLP), described [here](https://github.com/ethereum/wiki/wiki/RLP) -* **Patricia tree** (or **trie**): a data structure which stores the state of every account. The trie is built by starting from each individual node, then splitting the nodes into groups of up to 16 and hashing each group, then making hashes of hashes and so forth until there is one final "root hash" for the entire trie. The trie has the important properties that (1) there is exactly one possible trie and therefore one possible root hash for each set of data, (2) it is very easy to update, add or remove nodes in the trie and generate the new root hash, (3) there is no way to modify any part of the tree without changing the root hash, so if the root hash is included in a signed document or a valid block the signature or proof of work secures the entire tree, and (4) one can provide just the "branch" of a tree going down to a particular node as cryptographic proof that that node is indeed in the tree with that exact content. Patricia trees are also used to store the internal storage of accounts as well as transactions and uncles. See [here](http://easythereentropy.wordpress.com/2014/06/04/understanding-the-ethereum-trie/) for a more detailed description. -* **GHOST**: GHOST is a protocol by which blocks can contain a hash of not just their parent, but also hashes for stales that are other children of the parent's parent (called **uncles**). This ensures that stales still contribute to blockchain security, and mitigates a problem with fast blockchains that large miners have an advantage because they hear about their own blocks immediately and so are less likely to generate stales. -* **Uncle**: a child of a parent of a parent of a block that is not the parent, or more generally a child of an ancestor that is not an ancestor. If A is an uncle of B, B is a **nephew** of A. -* **Account nonce**: a transaction counter in each account. This prevents replay attacks where a transaction sending eg. 20 coins from A to B can be replayed by B over and over to continually drain A's balance. -* **EVM code**: Ethereum virtual machine code, the programming language in which accounts on the Ethereum blockchain can contain code. The EVM code associated with an account is executed every time a message is sent to that account, and has the ability to read/write storage and itself send messages. -* **Message**: a sort of "virtual transaction" sent by EVM code from one account to another. Note that "transactions" and "messages" in Ethereum are different; a "transaction" in Ethereum parlance specifically refers to a physical digitally signed piece of data that goes in the blockchain, and every transaction triggers an associated message, but messages can also be sent by EVM code, in which case they are never represented in data anywhere. -* **Storage**: a key/value database contained in each account, where keys and values are both 32-byte strings but can otherwise contain anything. -* **Externally owned account**: an account controlled by a private key. Externally owned accounts cannot contain EVM code. -* **Contract**: an account which contains, and is controlled by, EVM code. Contracts cannot be controlled by private keys directly; unless built into the EVM code, a contract has no owner once released. -* **Ether**: the primary internal cryptographic token of the Ethereum network. Ether is used to pay transaction and computation fees for Ethereum transactions. -* **Gas**: a measurement roughly equivalent to computational steps. Every transaction is required to include a gas limit and a fee that it is willing to pay per gas; miners have the choice of including the transaction and collecting the fee or not. If the total number of gas used by the computation spawned by the transaction, including the original message and any sub-messages that may be triggered, is less than or equal to the gas limit, then the transaction processes. If the total gas exceeds the gas limit, then all changes are reverted, except that the transaction is still valid and the fee can still be collected by the miner. Every operation has a gas expenditure; for most operations it is 1, although some expensive operations have expenditures up to 100 and a transaction itself has an expenditure of 500. - -### Non-blockchain - -* **EtherBrowser**: the upcoming primary client for Ethereum, which will exist in the form of a web browser that can be used to access both normal websites and applications built on top of the Ethereum platform -* **Whisper**: an upcoming P2P messaging protocol that will be integrated into the EtherBrowser -* **Swarm**: an upcoming P2P data storage protocol optimized for static web hosting that will be integrated into the EtherBrowser -* **Solidity**, **LLL**, **Serpent** and **Mutan**: prorgamming languages for writing contract code which can be compiled into EVM code. Serpent can also be compiled into LLL. -* **PoC**: proof-of-concept, another name for a pre-launch release - -### Surrounding concepts: applications and governance - -* **Decentralized application**: a program which is run by many people which either uses or creates a decentralized network for some specific purpose (eg. connecting buyers and sellers in some marketplace, sharing files, online file storage, maintaining a currency). Ethereum-based decentralized applications (also called Đapps, where the Đ is the Norse letter "eth") typically consist of an HTML/Javascript webpage, and if viewed inside the EtherBrowser the browser recognizes special Javascript APIs for sending transactions to the blockchain, reading data from the blockchain and interacting with Whisper and Swarm. A Đapp typically also has a specific associated contract on the blockchain, though Đapps that facilitate the creation of many contracts are quite possible. -* **Decentralized organization**: an organization that has no centralized leadership, instead using a combination of formal democratic voting processes and stigmergic self-organization as their primary operating principles. A less impressive but sometimes confused concept is a "geographically distributed organization", an organization where people work far apart from each other and which may even have no office at all; GDOs can still have formal centralized leadership. -* **Theseus criterion**: a test for determining how decentralized an organization is. The test is as follows: suppose the organization has N people, and aliens try to pick K people in the organization at a time (eg. once per week) and zap them out of existence, replacing each group with K new people who know nothing about the organization. For how high K can the organization function? Dictatorships fail at K = 1 once the dictator is zapped away; the US government does slightly better but would still be in serious trouble if all 638 members of the Senate and Congress were to disappear, where as something like Bitcoin or BitTorrent is resilient for extremely high K because new agents can simply follow their economic incentives to fill in the missing roles. A stricter test, the **Byzantine Theseus criterion**, involves randomly substituting K users at a time with malicious actors for some time before replacing them with new users. -* **Decentralized autonomous organization**: decentralized organizations where the method of governance is in some fashion "autonomous", ie. it's not controlled by some form of discussion process or committee. -* **No common language criterion**: a test for determining how autonomous an organization is. The test is as follows: suppose the N people in the organization speak N different languages, with none in common. Can the organization still function? -* **Delegative democracy** (or **liquid democracy**): a governance mechanism for DOs and DAOs where everyone votes on everything by default, but where individuals [can select specific individuals](http://en.wikipedia.org/wiki/Delegative_democracy) to vote for them on specific issues. The idea is to generalize the tradeoff between full direct democracy with every individual having equal power and the expert opinion and quick decision making ability provided by specific individuals, allowing people to defer to friends, politicians, subject matter experts or anyone else to exactly the extent that they want to. -* **Futarchy**: a governance mechanism [originally proposed](http://hanson.gmu.edu/futarchy.html) by Robin Hanson for managing political organizations, but which is actually extremely applicable for DOs and DAOs: rule by prediction market. Essentially, some easily measurable success metrics are chosen, and tokens are released which will pay out some time in the future (eg. after 1 year) depending on the values of those success metrics, with one such token for each possible action to take. Each of these tokens are traded against a corresponding dollar token, which pays out exactly $1 if the corresponding measure is taken (if the corresponding measure is not taken, both types of tokens pay $0, so the probability of the action actually being taken does not affect the price). The action that the market predicts will have the best results, as judged by the token's high price on its market, is the action that will be taken. This provides another, autonomous, mechanism for selecting for and simultaneously rewarding expert opinion. - -### Economics - -* **Token system**: essentially, a fungible virtual good that can be traded. More formally, a token system is a database mapping addresses to numbers with the property that the primary allowed operation is a transfer of N tokens from A to B, with the conditions that N is non-negative, N is not greater than A's current balance, and a document authorizing the transfer is digitally signed by A. Secondary "issuance" and "consumption" operations may also exist, transaction fees may also be collected, and simultaneous multi-transfers with many parties may be possible. Typical use cases include currencies, cryptographic tokens inside of networks, company shares and digital gift cards. -* **Namespace**: a database mapping names to values. In the simplest example anyone can register an entry if the name has not already been taken (perhaps after paying some fee). If a name has been taken then it can only be changed (if at all) by the account that made the original registration (in many systems, ownership can also be transferred). Namespaces can be used to store usernames, public keys, internet domain names, token systems or other namespaces, and many other applications. -* **Identity**: a set of cryptographically verifiable interactions that have the property that they were all created by the same person -* **Unique identity**: a set of cryptographically verifiable interactions that have the property that they were all created by the same person, with the added constraint that one person cannot have multiple unique identities -* **Incentive compatibility**: a protocol is incentive-compatible if everyone is better off "following the rules" than attempting to cheat, at least unless a very large number of people agree to cheat together at the same time. -* **Basic income**: the idea of issuing some quantity of tokens to every unique identity every period of time (eg. months), with the ultimate intent being that people who do not wish to work or cannot work can survive on this allowance alone. These tokens can simply be crafted out of thin air, or they can come from some revenue stream (eg. profit from some revenue-generating entity, or a government); in order for the BI to be sufficient for a person to live on it alone, a combination of revenue streams will likely have to be used. -* **Public good**: a service which provides a very small benefit to a very large number of people, such that no individual has a large effect on whether or not the good is produced and so no one has the incentive to help pay for it. -* **Reputation**: the property of an identity that other entities believe that identity to be either (1) competent at some specific task, or (2) trustworthy in some context, ie. not likely to betray others even if short-term profitable. -* **Web of trust**: the idea that if A highly rates B, and B highly rates C, then A is likely to trust C. Complicated and powerful mechanisms for determining the reliability of specific individuals in specific concepts can theoretically be gathered from this principle. -* **Escrow**: if two low-reputation entities are engaged in commerce, the payer may wish to leave the funds with a high-reputation third party and instruct that party to send the funds to the payee only when the product is delivered. This reduces the risk of the payer or payee committing fraud. -* **Deposit**: digital property placed into a contract involving another party such that if certain conditions are not satisfied that property is automatically forfeited to the counterparty -* **Hostage**: digital property placed into a contract such that if certain conditions are not satisfied that property is automatically either destroyed or donated to charity or basic income funds, perhaps with widely distributed benefit but necessarily with no significant benefit to any specific individual. diff --git a/HPOC_2015.md b/HPOC_2015.md deleted file mode 100644 index 5714df7b1..000000000 --- a/HPOC_2015.md +++ /dev/null @@ -1,92 +0,0 @@ ---- -name: HPOC 2015 -category: ---- - -### HPoC 2015 - -Last year we released the "Hard Problems of Cryptocurrency" document, detailing what we thought were some of the harder technical and economic problems keeping cryptocurrency and cryptoeconomic technology from mainstream viability. The list included issues such as scalability, more efficient consensus algorithms, public goods incentivization, reputation systems, among a number of other challenges. Over the past year, a large portion of these problems have arguably been solved, or at least research has been brought forward to the point where additional progress is no longer a matter of zero-to-one fundamental breakthroughs, but rather tweaking and empirical testing through real-world implementation. At the same time, there are a substantial number of challenges that still remain, although the problems here are substantially more specific and less broadly reaching than previously. - -### Meta-consensus - -In order to remain relevant in a rapidly evolving technological landscape, software must update, and software that does not update has no alternative but to slowly fade away and die as it is replaced by superior technology. There is no reason why this principle should not apply to decentralized crypto-protocols as well. However, the need to make upgrades to decentralized crypto-systems leads to a natural question: who controls the updating process? As of the time of this writing, the Bitcoin community is going through the process of deciding whether or not to increase the maximum block size from 1 MB to 20 MB, and the lack of a deliberately instituted decision-making process has lead to the situation where the de-facto decision-making process essentially amounts to political debate among a small number of core developers. - -Is there a way of building _intra-protocol meta-consensus_ - that is, a mechanism inside the protocol that facilitates agreement on upgrades to the protocol, perhaps using some kind of consensus voting? Such a system would have a number of benefits, including greater flexibility, less reliance on political processes that end up being centralization risks, and can arguably ensure a greater voice to all participants in the protocol, not just those that are socially well-connected (see Jo Freeman's [The Tyranny of Structurelessness](http://www.jofreeman.com/joreen/tyranny.htm) for more on this). - -Desirable properties of meta-consensus include: - -* Incentives to agree on beneficial protocol changes -* Some kind of guarantee that applications built under the old protocol will remain maximally effective under the new protocol. Note that a part of this will likely be some kind of object-oriented encapsulation mechanisms in order to steer developers away from using features which are highly protocol-specific -* Resistance against the mechanism being corrupted in some sense and forced to lead to an undesirable protocol change -* The ability for users to automatically upgrade to a newly chosen protocol without having to download a new client - -Existing work on this includes [Arthur Breitman's Tezos](http://tezos.com/), Bitshares' [delegated proof of stake](https://bitshares.org/blog/delegated-proof-of-stake/), and the not-yet-released Ethereum 2.0 proposal. - -### Public Goods Preference Revelation and Incentivization - -The other major problem in crypto-protocol development is the analogous funding problem: how will protocol upgrades, and more generally public-good ecosystem middleware, be paid for? In the initial phase of development, the concept of "crowdsales" has proven to be absolutely invaluable, providing millions of dollars of funding for efforts which would have otherwise been relegated to being little more than volunteer side projects. However, crowdsales by themselves have a fundamental problem: they are front-loaded, creating heavy incentives for short-term marketing but less so for long-term performance, and they are limited one-time events from which the funds received eventually run out. And even if the funds could somehow be managed so as not to run out, crypto-protocol development would be permanently centralized in a single organization. What would be ideal is, once again, some kind of intra-protocol mechanism for incentivizing the development of public goods. - -Public goods incentivization has a long and established literature, including numerous [results](http://www.ebour.com.ar/pdfs/Yan%20Chen%20Incentive%20Compatible%20Mechanisms%20for%20Public%20Goods.pdf) [from](http://www.coll.mpg.de/book/ci21-mechanism-design-approach-public-good-provision) [mechanism](http://www.econ.ucsb.edu/~tedb/Courses/UCSBpf/pflectures/revelation.pdf) [design](http://people.hbs.edu/jgreen/Preferences_Public_Goods_1976.pdf) and [assurance contract theory](http://en.wikipedia.org/wiki/Assurance_contract) on the topic of both how to fund the development of public goods and on the equally important question of deciding which public goods are worth funding in the first place. In a blockchain context, the funding problem is somewhat easier than in a private-market context, because we have the ability to "tax" all currency holders via inflation and taking the excess of transaction fees minus consensus costs, but the preference revelation problem is much harder; a human government can try to use informal judgement to figure out which public goods are worth supporting and which ones are not, but a blockchain literally cannot tell the difference between a trustworthy development fund, an untrustworthy development fund, a tobacco lobbying company, the "zero address" from which coins can never be spent and a scammer. Hence, it must rely entirely on some kind of mechanism design to elicit this information from the community. - -The challenge here is applying these guarantees to a blockchain context. Particular challenges include: - -* Being incentive-compatible even given the assumption that users can securely and trustlessly bribe each other, eg. via contracts (cooperative game theory can help here) -* Being incentive-compatible even given the assumption that the attacker may have a superior ability to coordinate versus the individual participants (cf. P + epsilon attacks; cooperative game theory may be insufficient here as it generally assumes that collections of users can either coordinate totally or not coordinate at all) -* Avoiding Caplanian "rational irrationality" critiques, ie. providing sufficiently large incentives for users to learn about which funds are worth supporting and not simply immediately click on what looks nicer - -The general model can be thought of as follows: - -* There exist N public goods, represented by addresses owned by funds that promise to spend the money on particular public goods (eg. development). Anyone can register an address in this set, perhaps after paying some fee -* Users need to, using some mechanism, select how to split up funding pool D between these goods (D may be a maximum size; the mechanism may end up "burning" some of D) -* Attackers creating fake "public goods" that really just send money to themselves can be seen simply as being public goods with a payoff ratio of 1 that happens to be concentrated entirely in a single player. The reason why attackers winning is socially bad is that other "legitimate" public goods will have much higher payoff ratios -* If necessary, we can rely on the users having security deposits, eg. being validators - -### Coercion-proof Voting - -Ari Juels in 2001 came up with a [protocol](http://www.arijuels.com/wp-content/uploads/2013/09/JCJ10.pdf) for "coercion-resistant electronic elections" - a way of doing voting online such that not only is it possible for users to vote without revealing to others who they voted for, but it is in fact not possible to prove to anyone else who you voted for _even if you wanted to_ - making it impossible to coerce or bribe people to vote. One possible route to solving the preference revelation problem, as well as voting games in general, is to implement this kind of scheme, making it much harder to coordinate. It is by no means a complete solution, since a user that controls two identities can still have those two identities securely collude with each other, but combined with a wealth deconcentration assumption it would make systems substantially more robust. - -The challenge is, is it possible to implement some kind of coercion-resistant electronic election into a decentralized public blockchain context? The primary challenge here is the complete lack of any specific parties that have private keys and can be trusted not to collude with each other; the system would need to be completely public. - -Note: an alternative to making _cryptographically_ coercion-resistant electronic elections is making _cryptoeconomically_ coercion-resistant electronic elections: come up with some kind of mechanism such that if a voter proves to another party any nonzero quantity of information about who they voted for, that party can exploit them for an expected nonzero return at their expense (if this exploitation can be made to be _unprovable_, then even better, as it reduces the possibility of effective circumvention through reputation). - -### Anti-pre-revelation - -There are many protocols such as [Schellingcoin](https://blog.ethereum.org/2014/03/28/schellingcoin-a-minimal-trust-universal-data-feed/), [Augur](http://augur.net), N-of-N protocols in random number generation, etc, that rely on some notion of users first cryptographically "committing" to some value `x`, eg. by submitting `H(x)` for some hash function, and then in a later stage "revealing" the value for `x` that they submitted - with non-revelation or incorrect revelation being punishable by security deposit loss. However, many of these protocols only work effectively if users' answers during the first phase are private; if users can collude to share information, and particularly if they can _provably_ share information, then the mechanism's effectiveness decreases as collusion becomes easier. - -Suppose a commit-reveal protocol where all users must supply either 0 or 1, and they are "supposed to" randomly choose this value. In the first step, each user must pick a (irrelevant) salt `s`, and provide `H([s, v])` where `v` is either 0 or 1. In the second step, the user must supply their values of `s` and `v`, and have them be checked against the commitment. The sum of all values `v` mod 2 is then taken as a single bit of random output. Here, hypothetically all players can talk to each other and provably coordinate on voting either 0 or 1. However, we can design an anti-pre-revelation protocol as follows: any party can choose to register a bet against any other party that they will vote on some specific value with at last a 60% probability (ie. if A bets that B will bet 0, then if B ends up providing `v = 0` then B gets 2 units out of A's security deposit, and if B ends up providing `v = 1` then A gets 3 units out of B's security deposit). Hence, if party `P[i]` reveals to party `P[j]` their `v` value, or even a zero-knowledge proof of their `v` value with more than 60% probability, they can be exploited (note that the 60% margin can be cut down further to make _any nonzero revelation_ costly by using [scoring rule theory](http://en.wikipedia.org/wiki/Scoring_rule)). - -A challenge is to either take this path and try to expand it into an environment where the potential value space is much larger and probabilities of voting may not be known a priori, or find some other approach to make it cryptographically impossible or cryptoeconomically expensive to reveal one's hidden value before one is supposed to. Tailoring to specific applications (eg. linear Schellingcoin price voting) is suboptimal but acceptable. A particular problem is the existence of zero-knowledge proofs: one can use zk-SNARKs (or simply plain ZKPs) in order to reveal any information about `v` and prove that this information is correct by using the provided hash `H([s, v])` _without revealing anything about `s`_ or any information about `v` that is undesired; hence, a solution should be secure against _all_ kinds of partial information revelation that may be useful, and not simply revealing the exact value of `v`. - -### Random Number Generation - -A number of protocols, including consensus protocols, blockchain-based lotteries, scalable sampling schemes, etc, require some kind of random number generation in the protocol. Proof of work provides an answer easily, because one cannot compute ahead of time what the result will be, and once a result is found not revealing it carries a large opportunity cost. However, proof of work is extremely expensive, requiring constant expenditure equal to the security margin. - -An alternative is N-of-N commit-reveal, as exemplified in Tomlion's RANDAO protocol, works as follows: - -1. `n` players `P[1] ... P[n]` with security deposits of size `D` in the protocol choose random values `V[1] ... V[n]` with `0 <= v[i] < 2**256`, and `P[i]` submits `H(V[i])` during round one. -2. In round two, every player who submitting a value `H(V[i])` must submit `V[i]`. -3. If all players submit their value correctly, then `(V[1] + ... + V[n]) % 2**256` is taken as a random seed, and all players are rewarded with `D * i` where `i` is an interest rate (eg. 0.0001 per period). -4. If not all players submitted their value correctly, then all players who participated get `D * i`, all players who did not participate lose their entire deposit and are kicked out, and the remaining players repeat the game until eventually all N players cooperate and reveal their values. - -If you are the last player to participate, then you can manipulate the value at a very high cost, and even then only by replacing it with a random value next time around (ie. one can avoid unfavorable values, but one cannot target favorable values or even choose between two known values). However, the mechanism has the limitations that (i) it relies on a non-collusion assumption, (ii) the randomness that it provides is not nearly as fast as proof of work randomness, making it useless for some specific intra-block applications where proof of work shines, and (iii) it can lead to honest players losing large amounts of money from a network attack. Mitigating problem (iii) necessarily involves exacerbating problem (ii), and vice versa. - -The open-ended challenge is to come up with a mechanism inside of a cryptoeconomic context which provides random numbers as output with maximally relaxed security assumptions and maximal robustness and resilience to attackers - ideally, a mechanism with the same properties as proof of work but without (or with only a negligible fraction of) its cost. - -### Anti-censorship - -Public blockchains particularly have a strong need to be censorship-resistant, ie. to be able to get transactions into the chain even if powerful parties do not want them included. This is important not just for controversial Wikileaks-style applications; even ordinary financial applications, commit-reveal protocols, etc, could have their security threatened if there was a way of effectively preventing "challenge" messages from entering the blockchain. - -If the set of participants willing to collude to censor is smaller than 33%, then the problem is fairly trivial. If the set is greater than 33%, however, then we know that those participants have the power to shut down the network, albeit at very high cost to themselves. Hence, the problem becomes somewhat different: how do we make it impossible for colluding censors to censor specific transactions _without censoring everything else as well_? - -One possible route to take is some kind of commit-reveal protocol, where users submit a hash of a transaction plus proof that the transaction is available, and then the transaction sender is somehow bound to include the transaction itself once it is revealed (ie. blocks that do not include the transaction will be invalid). However, this has the problem that (i) proof of availability is very hard to implement, and (ii) colluding censors can simply require the submission of a transaction alongside its proof. In general, any protocol will likely be vulnerable to "colluding censors can simply require a zero-knowledge proof of X", but the challenge is making such a requirement maximally inconvenient for all parties to implement. - -### Privacy - -Blockchains are often hailed as an alternative to centralized networks that rely on trusting specific parties. However, one of the major areas in which people actually do strongly distrust centralized parties in real life is in the area of privacy, and blockchain protocols by themsleves are even more public than centralized systems. Hence, blockchain-based solutions to privacy will likely need to go a bit beyond simply creating a decentralized database and being done with it; effort must be made into creating protocols for maximally broad categories of applications (eg. payments, financial contracts, identity and reputation info publication) that combine blockchain-based data publication with protocols that preserve individual privacy, and allow individuals maximum freedom in what facts about themselves to expose to what parties. - -Sub-problems of this problem include: - -* Fully anonymous currency (for existing work see Zerocash; Zerocash's largest current flaw is arguably the long 90s transaction signing period arising from its usage of zkSNARKs) -* A privacy-preserving reputation system that allows users to create "zero-knowledge reputation certificates" proving that they have some reputation score according to the target's desired metric but revealing minimal other personal information -* A financial contract system that allows users to hide the code and contents of their contracts to a maximal possible extent -* A maximally privacy-preserving decentralized internet-of-things platform diff --git a/Home.md b/Home.md deleted file mode 100644 index c4b23330b..000000000 --- a/Home.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -name: Home -category: ---- - -# Welcome to the Ethereum Wiki - - -This is the community-maintained wiki covering all sorts of information on the next-generation peer-to-peer technology platform build by ÐΞV including **Ethereum**, _the generalized blockchain for smart contract development_, and **Whisper**, _the private low-level datagram communication platform_. - -Users signed in with GitHub can edit and add pages using the [browser](https://help.github.com/articles/editing-wiki-pages-via-the-online-interface) or [locally](https://help.github.com/articles/adding-and-editing-wiki-pages-locally). - -## Status - -### Frontier - -Version 1.0 of Ethereum aka Frontier was released on July 30th 2015! Development continues towards the versions named Homestead, Metropolis and Serenity (v1.1). Frontier is aimed at exchangers and [miners](https://github.com/ethereum/wiki/wiki/Mining). Homestead is aiming for [Ðapps developers](https://github.com/ethereum/wiki/wiki/Ethereum-Development-Tutorial), while Metropolis is aiming for end users with the release of the Mist browser. Serenity is meant to move from consensus through [Proof-of-Work](https://github.com/ethereum/wiki/wiki/Ethash) to [Proof-of-Stake](https://blog.ethereum.org/2015/08/01/introducing-casper-friendly-ghost/). - -## Getting started -To get the basic concepts of Ethereum visit the Ethereum homepage over at [http://ethereum.org](http://ethereum.org/). If you want to get a deeper understanding, start by read the [whitepaper](https://github.com/ethereum/wiki/wiki/White-Paper) and the [design rationale](https://github.com/ethereum/wiki/wiki/Design-Rationale). For a more formal review, read the [yellow paper](http://gavwood.com/Paper.pdf). See the [development tutorial](https://github.com/ethereum/wiki/wiki/Ethereum-Development-Tutorial) for quick start to developing smart contracts. - -## Don't get lost -Check the [Glossary](https://github.com/ethereum/wiki/wiki/Glossary) and our [FAQ](https://github.com/ethereum/wiki/wiki/FAQ). There are separate wikis for information relevant to the [C++](https://github.com/ethereum/cpp-ethereum/wiki) and [Go](https://github.com/ethereum/go-ethereum/wiki) implementations (Python and Javascript coming soon), - -## Downloads -Bleeding edge code can be cloned from the develop branch of their git repositories: -- https://github.com/ethereum/cpp-ethereum -- https://github.com/ethereum/go-ethereum -- https://github.com/ethereum/pyethapp -To see the state of the latest Ethereum builds, see the [build server](http://build.ethdev.com/console). diff --git a/ICAP:-Inter-exchange-Client-Address-Protocol.md b/ICAP:-Inter-exchange-Client-Address-Protocol.md deleted file mode 100644 index d68a810be..000000000 --- a/ICAP:-Inter-exchange-Client-Address-Protocol.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -name: ICAP Inter Exchange Client Address Protocol -category: ---- - -Transferring funds between third-party accounts, especially those of exchanges, places considerable burden on the user and is error prone, due to the way in which deposits are identified to the client account. This problem was tackled by the existing banking industry through having a common code known as *IBAN*. This code amalgamated the institution and client account along with a error-detection mechanism practically eliminating trivial errors and providing considerable convenience for the user. Unfortunately, this is a heavily regulated and centralised service accessible only to large, well-established institutions. The present protocol, ICAP, may be viewed as a decentralised version of it suitable for any institutions containing funds on the Ethereum system. - -### IBAN - -For a good overview of the IBAN system, please see [Wikipedia's IBAN article](https://en.wikipedia.org/wiki/International_Bank_Account_Number). An IBAN code consists of up to 34 case insensitive alpha-numeric characters. It contains three pieces of information: - -- The country code; a top-level identifier for the context of the following (ISO 3166-1 alpha-2); -- The error-detection code; uses the *mod-97-10* checksumming protocol (ISO/IEC 7064:2003); -- The basic bank account number (BBAN); an identifier of the institution, branch and client account, whose composition is dependent on the aforementioned country. - -For the UK, the BBAN is composed of: - -- Institution identifier, 4-character alphabetical, e.g. `MIDL` (ironically) represents HSBC bank. -- Sort-code (branch identifier within the institution), a 6-digit decimal number, e.g. `402702` would be the Lancaster branch of HSBC. -- Account number (client identifier within the branch), an 8-digit decimal number. - -# Proposed Design - -Introduce a new IBAN country code: *XE*, formulated as the Ethereum *E* prefixed with the "extended" *X*, as used in non-jurisdictional currencies (e.g. XRP, XCP). - -There will be three BBAN possibilities for this code; *direct*, *basic* and *indirect*. - -#### Direct - -The BBAN for this code when direct will be 30 characters and will comprise one field: - -- Account identifier, 30 characters alphanumeric (< 155-bit). This will be interpreted as a big-endian encoded base-36 integer representing the least significant bits of a 160-bit Ethereum address. As such, these Ethereum addresses will generally begin with a zero byte. - -e.g. XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS corresponds to the address `00c5496aee77c1ba1f0854206a26dda82a81d6d8`. - -#### Basic - -The same as the direct encoding, except that the code is 31 characters (making it non-compliant for IBAN) and composes the same, single, field: - -- Account identifier, 31 characters alphanumeric (< 161-bit). This will be interpreted as a big-endian encoded base-36 integer representing a 160-bit Ethereum address. - -#### Indirect - -The BBAN for this code when indirect will be 16 characters and will comprise three fields: - -- Asset identifier, 3-character alphanumeric (< 16-bit); -- Institution identifier, 4-character alphanumeric (< 21-bit); -- Institution client identifier, 9-character alphanumeric (< 47-bit); - -Including the four initial characters, this leads to a final client-account address length of 20 characters, of the form: - -``` -XE81ETHXREGGAVOFYORK -``` - -Split into: - -- `XE` The country code for Ethereum; -- `66` The checksum; -- `ETH` The asset identifier within the client account - in this case, "ETH" is the only valid asset identifier, since Ethereum's base registry contract supports only this asset; -- `XREG` The institution code for the account - in this case, Ethereum's base registry contract; -- `GAVOFYORK` The client identifier within the institution - in this case, a direct payment with no additional data to whatever primary address is associated with the name "GAVOFYORK" in Ethereum's base registry contract; - -## Notes - -Institution codes beginning with `X` are reserved for system use. - -## Other forms - -### URI - -General URIs can be formed though the URI scheme name `iban`, followed by the colon character `:`, followed by the 20-character alphanumeric identifier, thus for the example above, we would use: - -``` -iban:XE81ETHXREGGAVOFYORK -``` - -### QR Code - -A QR code may be generated directly from the URI using standard QR encodings. For example, the example above `iban:XE81ETHXREGGAVOFYORK` would have the corresponding QR code: - -![QR code for iban:XE81ETHXREGGAVOFYORK](http://opensecrecy.com/qr-XE81ETHXREGGAVOFYORK.gif) - -# Transaction Semantics - -The mechanism for indirect asset transfer over three routing protocols are specified, all of which are specific to the Ethereum domain (country-code of `XE`). One is for currency transfers directly to an included address ("direct"), another is for clients with the system address found through a Registry-lookup system of the client-ID, denoted by asset class `ETH`, whereas the last is for transfers to an intermediary with associated data to specify client, denoted by asset class `XET` (the latter two are "indirect"). - -## Direct - -If the IBAN code is 34 characters, it is a direct address; a direct transfer is made to the address which, when base-36 encoded gives exactly the data segment (the last 30 characters) of the IBAN code. - -## Indirect ETH Asset: Simple transfers - -Within the ETH asset code of Ethereum's country-code (XE), i.e. as long as the code begins with `XE**ETH` (where `**` is the valid checksum), then we can define the required transaction to be the deposit address given by a call to the *registry contract* denoted by the institution code. For institutions not beginning with `X`, this corresponds to the primary address associated with the *Ethereum standard name*: - -[institution code] `/` [client identifier] - -The *Ethereum standard name* is simply the normal hierarchical lookup mechanism, as specified in the Ethereum standard interfaces document. - -We define a *registry contract* as a contract fulfilling the Registry interface as specified in the Ethereum standard interfaces document. - -**TODO**: JS code for specifying the transfer. - -## Indirect XET Asset: Institution transfers - -For the `XET` asset code within the Ethereum country code (i.e. while the code begins XE**XET), then we can derive the transaction that must be made through a lookup to the Ethereum `iban` registry contract. For a given institution, this contract specifies two values: the deposit call signature hash and the institution's Ethereum address. - -At present, only a single such deposit call is defined, which is: - -``` -function deposit(uint64 clientAccount) -``` - -whose signature hash is `0x13765838`. The transaction to transfer the assets should be formed as an ether-laden call to the institution's Ethereum address using the `deposit` method as specified above, with the client account determined through the value of the big-endian, base-36 interpretation of the alpha-numeric *Institution client identifier*, literally using the value of the characters `0` to `9`, then evaluating 'A' (or 'a') as 10, 'B' (or 'b') as 11 and so forth. - -**TODO**: JS code for specifying the transfer. \ No newline at end of file diff --git a/IPv6.md b/IPv6.md deleted file mode 100644 index 855661d3e..000000000 --- a/IPv6.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: IPv6 -category: ---- - -### Goals - -Allow IPv6 to be used over the ethereum peer network - -### Basic Design - -Allow IP addresses to be specified either as a 4-byte array (IPv4) or a 16-byte array (IPv6). - -### Needed Changes - -**Peers** -[`0x05`, [`ip1`: `B_4` OR `B_16`, `port1`: `P`, `id1`: `B_64`], [`ip2`: `B_4` OR `B_16`, `port2`: `P`, `id2`: `B_64`], ... ] Specifies a number of known peers. -* `ip` is either a 4-byte array 'ABCD' that should be interpreted as the IPv4 address A.B.C.D or a 8-byte array 'ABCDEFGHIJKLMNOP' that should be interpreted as the IPv6 address AB:CD:EF:GH:IJ:KL:MN:OP. -* `port` is a 2-byte array that should be interpreted as a 16-bit big-endian integer. -* `id` is the 512-bit hash that acts as the unique identifier of the node. diff --git a/JSON-RPC-Error-Codes-Improvement-Proposal.md b/JSON-RPC-Error-Codes-Improvement-Proposal.md deleted file mode 100644 index ad45ac86b..000000000 --- a/JSON-RPC-Error-Codes-Improvement-Proposal.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -name: JSON RPC Error Codes Improvement Proposal -category: ---- - -To help developers add proper error handling in the dapp side, we need to implement custom error codes for the returned JSON RPC errors. - -## JSON RPC Standard errors - -| Code | Possible Return message | Description | -| --------|-------------------------|-------------| -|-32700 | Parse error | Invalid JSON was received by the server. An error occurred on the server while parsing the JSON text. | -|-32600 | Invalid Request | The JSON sent is not a valid Request object. | -|-32601 | Method not found | The method does not exist / is not available. | -|-32602 | Invalid params | Invalid method parameter(s). | -|-32603 | Internal error | Internal JSON-RPC error. | -|-32000 to -32099 | `Server error`. Reserved for implementation-defined server-errors. | - -## Custom error codes: - -| Code | Possible Return message | Description | -| --------|-------------------------|-------------| -|1 | Unauthorized | Should be used when some action is not authorized, e.g. sending from a locked account. -|2 | Action not allowed | Should be used when some action is not allowed, e.g. preventing an action, while another depending action is processing on, like sending again when a confirmation popup is shown to the user (?). -|3 | Execution error | Will contain a subset of custom errors in the data field. See below. | - -### Custom error fields - -Custom error `3` can contain custom error(s) to further explain what went wrong. -They will be contained in the `data` field of the RPC error message as follows: - -```js -{ - code: 3, - message: 'Execution error', - data: [{ - code: 102, - message: 'Innsufficient gas', - reason: 'GAS' - }, - { - code: 103, - message: 'Gas limit exceeded', - reason: 'GAS' - }] -} -``` - -| Code | Reson values | Possible Return message | Description | -| --------|--------------|-------------------------|-------------| -|100 | ? | X doesn't exist | Should be used when something which should be there is not found. (Doesn't apply for not found transactions or blocks. They return a success with value `null`) -|101 | `ETHER` ? | Requires X | Should be used for actions which require somethin else, e.g. gas or a value. -|102 | `GAS`, `ETHER` | X to low | Should be used when a to low value of something was given, e.g. an to low gas amount. -|103 | `GAS` | X limit exceeded | Should be used when a limit is exceeded, e.g. for the gas limit in a block. -|104 | `CODE` ? | Rejected | Should be used when an action was rejected, e.g. because of its content (to long contract code, containing wrong characters ?, should differ from `-32602` - Invalid params). - - -## Possible future error codes? - -| Code | Possible Return message | Description | -| --------|-------------------------|-------------| -|105 | Timeout | Should be used when an action timedout. -|106 | Conflict | Should be used when an action conflicts with another (ongoing?) action. \ No newline at end of file diff --git a/JSON-RPC.md b/JSON-RPC.md deleted file mode 100644 index 33f9d64d1..000000000 --- a/JSON-RPC.md +++ /dev/null @@ -1,2381 +0,0 @@ ---- -name: JSON RPC -category: ---- - -# JSON RPC API - -[JSON](http://json.org/) is a lightweight data-interchange format. It can represent numbers, strings, ordered sequences of values, and collections of name/value pairs. - -[JSON-RPC](http://www.jsonrpc.org/specification) is a stateless, light-weight remote procedure call (RPC) protocol. Primarily this specification defines several data structures and the rules around their processing. It is transport agnostic in that the concepts can be used within the same process, over sockets, over HTTP, or in many various message passing environments. It uses JSON ([RFC 4627](http://www.ietf.org/rfc/rfc4627.txt)) as data format. - -## JavaScript API - -To talk to an ethereum node from inside a JavaScript application use the [web3.js](https://github.com/ethereum/web3.js) library, which gives an convenient interface for the RPC methods. -See the [JavaScript API](https://github.com/ethereum/wiki/wiki/JavaScript-API) for more. - -## JSON-RPC Endpoint - -Default JSON-RPC endpoints: -``` -C++: http://localhost:8545 -Go: http://localhost:8545 -Py: http://localhost:4000 -``` - -### Go - -You can start the HTTP JSON-RPC with the `--rpc` flag -```bash -geth --rpc -``` - -change the default port (8545) and listing address (localhost) with: - -```bash -geth --rpc --rpcaddr --rpcport -``` - -If accessing the RPC from a browser, CORS will need to be enabled with the appropriate domain set. Otherwise, JavaScript calls are limit by the same-origin policy and requests will fail: - -```bash -geth --rpc --rpccorsdomain "http://localhost:3000" -``` - -The JSON RPC can also be started from the [geth console](https://github.com/ethereum/go-ethereum/wiki/JavaScript-Console) using the `admin.startRPC(addr, port)` command. - - -### C++ - -You can start it by running `eth` application with `-j` option: -```bash -./eth -j -``` - -You can also specify JSON-RPC port (default is 8545): -```bash -./eth -j --json-rpc-port 8079 -``` - -### Python -In python the JSONRPC server is currently started by default and listens on `127.0.0.1:4000` - -You can change the port and listen address by giving a config option. - -`pyethapp -c jsonrpc.listen_port=4002 -c jsonrpc.listen_host=127.0.0.2 run` - -## JSON-RPC support - -| | cpp-ethereum | go-ethereum | py-ethereum| -|-------|:------------:|:-----------:|:-----------:| -| JSON-RPC 1.0 | ✓ | | | -| JSON-RPC 2.0 | ✓ | ✓ | ✓ | -| Batch requests | ✓ | ✓ | ✓ | -| HTTP | ✓ | ✓ | ✓ | - -## Output HEX values - -At present there are two key datatypes that are passed over JSON: unformatted byte arrays and quantities. Both are passed with a hex encoding, however with different requirements to formatting: - -When encoding **QUANTITIES** (integers, numbers): encode as hex, prefix with "0x", the most compact representation (slight exception: zero should be represented as "0x0"). Examples: -- 0x41 (65 in decimal) -- 0x400 (1024 in decimal) -- WRONG: 0x (should always have at least one digit - zero is "0x0") -- WRONG: 0x0400 (no leading zeroes allowed) -- WRONG: ff (must be prefixed 0x) - -When encoding **UNFORMATTED DATA** (byte arrays, account addresses, hashes, bytecode arrays): encode as hex, prefix with "0x", two hex digits per byte. Examples: -- 0x41 (size 1, "A") -- 0x004200 (size 3, "\0B\0") -- 0x (size 0, "") -- WRONG: 0xf0f0f (must be even number of digits) -- WRONG: 004200 (must be prefixed 0x) - -Currently [cpp-ethereum](https://github.com/ethereum/cpp-ethereum) and [go-ethereum](https://github.com/ethereum/go-ethereum) provides JSON-RPC communication only over http. - -## The default block parameter - -The following methods have a extra default block parameter: - -- [eth_getBalance](#eth_getbalance) -- [eth_getCode](#eth_getcode) -- [eth_getTransactionCount](#eth_gettransactioncount) -- [eth_getStorageAt](#eth_getstorageat) -- [eth_call](#eth_call) - -When requests are made that act on the state of ethereum, the last default block parameter determines the height of the block. - -The following options are possible for the defaultBlock parameter: - -- `HEX String` - an integer block number -- `String "earliest"` for the earliest/genesis block -- `String "latest"` - for the latest mined block -- `String "pending"` - for the pending state/transactions - -## JSON-RPC methods - -* [web3_clientVersion](#web3_clientversion) -* [web3_sha3](#web3_sha3) -* [net_version](#net_version) -* [net_peerCount](#net_peercount) -* [net_listening](#net_listening) -* [eth_protocolVersion](#eth_protocolversion) -* [eth_syncing](#eth_syncing) -* [eth_coinbase](#eth_coinbase) -* [eth_mining](#eth_mining) -* [eth_hashrate](#eth_hashrate) -* [eth_gasPrice](#eth_gasprice) -* [eth_accounts](#eth_accounts) -* [eth_blockNumber](#eth_blocknumber) -* [eth_getBalance](#eth_getbalance) -* [eth_getStorageAt](#eth_getstorageat) -* [eth_getTransactionCount](#eth_gettransactioncount) -* [eth_getBlockTransactionCountByHash](#eth_getblocktransactioncountbyhash) -* [eth_getBlockTransactionCountByNumber](#eth_getblocktransactioncountbynumber) -* [eth_getUncleCountByBlockHash](#eth_getunclecountbyblockhash) -* [eth_getUncleCountByBlockNumber](#eth_getunclecountbyblocknumber) -* [eth_getCode](#eth_getcode) -* [eth_sign](#eth_sign) -* [eth_sendTransaction](#eth_sendtransaction) -* [eth_sendRawTransaction](#eth_sendrawtransaction) -* [eth_call](#eth_call) -* [eth_estimateGas](#eth_estimategas) -* [eth_getBlockByHash](#eth_getblockbyhash) -* [eth_getBlockByNumber](#eth_getblockbynumber) -* [eth_getTransactionByHash](#eth_gettransactionbyhash) -* [eth_getTransactionByBlockHashAndIndex](#eth_gettransactionbyblockhashandindex) -* [eth_getTransactionByBlockNumberAndIndex](#eth_gettransactionbyblocknumberandindex) -* [eth_getTransactionReceipt](#eth_gettransactionreceipt) -* [eth_getUncleByBlockHashAndIndex](#eth_getunclebyblockhashandindex) -* [eth_getUncleByBlockNumberAndIndex](#eth_getunclebyblocknumberandindex) -* [eth_getCompilers](#eth_getcompilers) -* [eth_compileLLL](#eth_compilelll) -* [eth_compileSolidity](#eth_compilesolidity) -* [eth_compileSerpent](#eth_compileserpent) -* [eth_newFilter](#eth_newfilter) -* [eth_newBlockFilter](#eth_newblockfilter) -* [eth_newPendingTransactionFilter](#eth_newpendingtransactionfilter) -* [eth_uninstallFilter](#eth_uninstallfilter) -* [eth_getFilterChanges](#eth_getfilterchanges) -* [eth_getFilterLogs](#eth_getfilterlogs) -* [eth_getLogs](#eth_getlogs) -* [eth_getWork](#eth_getwork) -* [eth_submitWork](#eth_submitwork) -* [eth_submitHashrate](#eth_submithashrate) -* [db_putString](#db_putstring) -* [db_getString](#db_getstring) -* [db_putHex](#db_puthex) -* [db_getHex](#db_gethex) -* [shh_post](#shh_post) -* [shh_version](#shh_version) -* [shh_newIdentity](#shh_newidentity) -* [shh_hasIdentity](#shh_hasidentity) -* [shh_newGroup](#shh_newgroup) -* [shh_addToGroup](#shh_addtogroup) -* [shh_newFilter](#shh_newfilter) -* [shh_uninstallFilter](#shh_uninstallfilter) -* [shh_getFilterChanges](#shh_getfilterchanges) -* [shh_getMessages](#shh_getmessages) - -## JSON RPC API Reference - -*** - -#### web3_clientVersion - -Returns the current client version. - -##### Parameters -none - -##### Returns - -`String` - The current client version - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":67}' - -// Result -{ - "id":67, - "jsonrpc":"2.0", - "result": "Mist/v0.9.3/darwin/go1.4.1" -} -``` - -*** - -#### web3_sha3 - -Returns Keccak-256 (*not* the standardized SHA3-256) of the given data. - -##### Parameters - -1. `String` - the data to convert into a SHA3 hash - -```js -params: [ - '0x68656c6c6f20776f726c64' -] -``` - -##### Returns - -`DATA` - The SHA3 result of the given string. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"web3_sha3","params":["0x68656c6c6f20776f726c64"],"id":64}' - -// Result -{ - "id":64, - "jsonrpc": "2.0", - "result": "0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad" -} -``` - -*** - -#### net_version - -Returns the current network protocol version. - -##### Parameters -none - -##### Returns - -`String` - The current network protocol version - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"net_version","params":[],"id":67}' - -// Result -{ - "id":67, - "jsonrpc": "2.0", - "result": "59" -} -``` - -*** - -#### net_listening - -Returns `true` if client is actively listening for network connections. - -##### Parameters -none - -##### Returns - -`Boolean` - `true` when listening, otherwise `false`. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"net_listening","params":[],"id":67}' - -// Result -{ - "id":67, - "jsonrpc":"2.0", - "result":true -} -``` - -*** - -#### net_peerCount - -Returns number of peers currenly connected to the client. - -##### Parameters -none - -##### Returns - -`QUANTITY` - integer of the number of connected peers. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"net_peerCount","params":[],"id":74}' - -// Result -{ - "id":74, - "jsonrpc": "2.0", - "result": "0x2" // 2 -} -``` - -*** - -#### eth_protocolVersion - -Returns the current ethereum protocol version. - -##### Parameters -none - -##### Returns - -`String` - The current ethereum protocol version - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_protocolVersion","params":[],"id":67}' - -// Result -{ - "id":67, - "jsonrpc": "2.0", - "result": "54" -} -``` - -*** - -#### eth_syncing - -Returns an object object with data about the sync status or FALSE. - - -##### Parameters -none - -##### Returns - -`Object|Boolean`, An object with sync status data or `FALSE`, when not syncing: - - `startingBlock`: `QUANTITY` - The block at which the import started (will only be reset, after the sync reached his head) - - `currentBlock`: `QUANTITY` - The current block, same as eth_blockNumber - - `highestBlock`: `QUANTITY` - The estimated highest block - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_isSyncing","params":[],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": { - startingBlock: '0x384', - currentBlock: '0x386', - highestBlock: '0x454' - } -} -// Or when not syncing -{ - "id":1, - "jsonrpc": "2.0", - "result": false -} -``` - -*** - -#### eth_coinbase - -Returns the client coinbase address. - - -##### Parameters -none - -##### Returns - -`DATA`, 20 bytes - the current coinbase address. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_coinbase","params":[],"id":64}' - -// Result -{ - "id":64, - "jsonrpc": "2.0", - "result": "0x407d73d8a49eeb85d32cf465507dd71d507100c1" -} -``` - -*** - -#### eth_mining - -Returns `true` if client is actively mining new blocks. - -##### Parameters -none - -##### Returns - -`Boolean` - returns `true` of the client is mining, otherwise `false`. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_mining","params":[],"id":71}' - -// Result -{ - "id":71, - "jsonrpc": "2.0", - "result": true -} - -``` - -*** - -#### eth_hashrate - -Returns the number of hashes per second that the node is mining with. - -##### Parameters -none - -##### Returns - -`QUANTITY` - number of hashes per second. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_hashrate","params":[],"id":71}' - -// Result -{ - "id":71, - "jsonrpc": "2.0", - "result": "0x38a" -} - -``` - -*** - -#### eth_gasPrice - -Returns the current price per gas in wei. - -##### Parameters -none - -##### Returns - -`QUANTITY` - integer of the current gas price in wei. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_gasPrice","params":[],"id":73}' - -// Result -{ - "id":73, - "jsonrpc": "2.0", - "result": "0x09184e72a000" // 10000000000000 -} -``` - -*** - -#### eth_accounts - -Returns a list of addresses owned by client. - - -##### Parameters -none - -##### Returns - -`Array of DATA`, 20 Bytes - addresses owned by the client. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_accounts","params":[],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": ["0x407d73d8a49eeb85d32cf465507dd71d507100c1"] -} -``` - -*** - -#### eth_blockNumber - -Returns the number of most recent block. - -##### Parameters -none - -##### Returns - -`QUANTITY` - integer of the current block number the client is on. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":83}' - -// Result -{ - "id":83, - "jsonrpc": "2.0", - "result": "0x4b7" // 1207 -} -``` - -*** - -#### eth_getBalance - -Returns the balance of the account of given address. - -##### Parameters - -1. `DATA`, 20 Bytes - address to check for balance. -2. `QUANTITY|TAG` - integer block number, or the string `"latest"`, `"earliest"` or `"pending"`, see the [default block parameter](#the-default-block-parameter) - -```js -params: [ - '0x407d73d8a49eeb85d32cf465507dd71d507100c1', - 'latest' -] -``` - -##### Returns - -`QUANTITY` - integer of the current balance in wei. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBalance","params":["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "latest"],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x0234c8a3397aab58" // 158972490234375000 -} -``` - -*** - -#### eth_getStorageAt - -Returns the value from a storage position at a given address. - - -##### Parameters - -1. `DATA`, 20 Bytes - address of the storage. -2. `QUANTITY` - integer of the position in the storage. -3. `QUANTITY|TAG` - integer block number, or the string `"latest"`, `"earliest"` or `"pending"`, see the [default block parameter](#the-default-block-parameter) - - -```js -params: [ - '0x407d73d8a49eeb85d32cf465507dd71d507100c1', - '0x0', // storage position at 0 - '0x2' // state at block number 2 -] -``` - -##### Returns - -`DATA` - the value at this storage position. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getStorageAt","params":["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "0x0", "0x2"],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x03" -} -``` - -*** - -#### eth_getTransactionCount - -Returns the number of transactions *sent* from an address. - - -##### Parameters - -1. `DATA`, 20 Bytes - address. -2. `QUANTITY|TAG` - integer block number, or the string `"latest"`, `"earliest"` or `"pending"`, see the [default block parameter](#the-default-block-parameter) - -```js -params: [ - '0x407d73d8a49eeb85d32cf465507dd71d507100c1', - 'latest' // state at the latest block -] -``` - -##### Returns - -`QUANTITY` - integer of the number of transactions send from this address. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionCount","params":["0x407d73d8a49eeb85d32cf465507dd71d507100c1","latest"],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x1" // 1 -} -``` - -*** - -#### eth_getBlockTransactionCountByHash - -Returns the number of transactions in a block from a block matching the given block hash. - - -##### Parameters - -1. `DATA`, 32 Bytes - hash of a block - -```js -params: [ - '0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238' -] -``` - -##### Returns - -`QUANTITY` - integer of the number of transactions in this block. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockTransactionCountByHash","params":["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0xb" // 11 -} -``` - -*** - -#### eth_getBlockTransactionCountByNumber - -Returns the number of transactions in a block from a block matching the given block number. - - -##### Parameters - -1. `QUANTITY|TAG` - integer of a block number, or the string `"earliest"`, `"latest"` or `"pending"`, as in the [default block parameter](#the-default-block-parameter). - -```js -params: [ - '0xe8', // 232 -] -``` - -##### Returns - -`QUANTITY` - integer of the number of transactions in this block. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockTransactionCountByNumber","params":["0xe8"],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0xa" // 10 -} -``` - -*** - -#### eth_getUncleCountByBlockHash - -Returns the number of uncles in a block from a block matching the given block hash. - - -##### Parameters - -1. `DATA`, 32 Bytes - hash of a block - -```js -params: [ - '0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238' -] -``` - -##### Returns - -`QUANTITY` - integer of the number of uncles in this block. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getUncleCountByBlockHash","params":["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"],"id"Block:1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x1" // 1 -} -``` - -*** - -#### eth_getUncleCountByBlockNumber - -Returns the number of uncles in a block from a block matching the given block number. - - -##### Parameters - -1. `QUANTITY` - integer of a block number, or the string "latest", "earliest" or "pending", see the [default block parameter](#the-default-block-parameter) - -```js -params: [ - '0xe8', // 232 -] -``` - -##### Returns - -`QUANTITY` - integer of the number of uncles in this block. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getUncleCountByBlockNumber","params":["0xe8"],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x1" // 1 -} -``` - -*** - -#### eth_getCode - -Returns code at a given address. - - -##### Parameters - -1. `DATA`, 20 Bytes - address -2. `QUANTITY|TAG` - integer block number, or the string `"latest"`, `"earliest"` or `"pending"`, see the [default block parameter](#the-default-block-parameter) - -```js -params: [ - '0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b', - '0x2' // 2 -] -``` - -##### Returns - -`DATA` - the code from the given address. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getCode","params":["0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0x2"],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x600160008035811a818181146012578301005b601b6001356025565b8060005260206000f25b600060078202905091905056" -} -``` - -*** - -#### eth_sign - -Signs data with a given address. - -**Note** the address to sign must be unlocked. - -##### Parameters - -1. `DATA`, 20 Bytes - address -2. `DATA`, Data to sign - -##### Returns - -`DATA`: Signed data - -##### Example - -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_sign","params":["0xd1ade25ccd3d550a7eb532ac759cac7be09c2719", "Schoolbus"],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x2ac19db245478a06032e69cdbd2b54e648b78431d0a47bd1fbab18f79f820ba407466e37adbe9e84541cab97ab7d290f4a64a5825c876d22109f3bf813254e8601" -} -``` - - - -*** - -#### eth_sendTransaction - -Creates new message call transaction or a contract creation, if the data field contains code. - -##### Parameters - -1. `Object` - The transaction object - - `from`: `DATA`, 20 Bytes - The address the transaction is send from. - - `to`: `DATA`, 20 Bytes - (optional when creating new contract) The address the transaction is directed to. - - `gas`: `QUANTITY` - (optional, default: 90000) Integer of the gas provided for the transaction execution. It will return unused gas. - - `gasPrice`: `QUANTITY` - (optional, default: To-Be-Determined) Integer of the gasPrice used for each paid gas - - `value`: `QUANTITY` - (optional) Integer of the value send with this transaction - - `data`: `DATA` - (optional) The compiled code of a contract - - `nonce`: `QUANTITY` - (optional) Integer of a nonce. This allows to overwrite your own pending transactions that use the same nonce. - -```js -params: [{ - "from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", - "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", - "gas": "0x76c0", // 30400, - "gasPrice": "0x9184e72a000", // 10000000000000 - "value": "0x9184e72a", // 2441406250 - "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" -}] -``` - -##### Returns - -`DATA`, 32 Bytes - the transaction hash, or the zero hash if the transaction is not yet available. - -Use [eth_getTransactionReceipt](#eth_gettransactionreceipt) to get the contract address, after the transaction was mined, when you created a contract. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_sendTransaction","params":[{see above}],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331" -} -``` - -*** - -#### eth_sendRawTransaction - -Creates new message call transaction or a contract creation for signed transactions. - -##### Parameters - -1. `Object` - The transaction object - - `data`: `DATA`, The signed transaction data. - -```js -params: [{ - "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" -}] -``` - -##### Returns - -`DATA`, 32 Bytes - the transaction hash, or the zero hash if the transaction is not yet available. - -Use [eth_getTransactionReceipt](#eth_gettransactionreceipt) to get the contract address, after the transaction was mined, when you created a contract. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_sendRawTransaction","params":[{see above}],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331" -} -``` - -*** - -#### eth_call - -Executes a new message call immediately without creating a transaction on the block chain. - - -##### Parameters - -1. `Object` - The transaction call object - - `from`: `DATA`, 20 Bytes - (optional) The address the transaction is send from. - - `to`: `DATA`, 20 Bytes - The address the transaction is directed to. - - `gas`: `QUANTITY` - (optional) Integer of the gas provided for the transaction execution. eth_call consumes zero gas, but this parameter may be needed by some executions. - - `gasPrice`: `QUANTITY` - (optional) Integer of the gasPrice used for each paid gas - - `value`: `QUANTITY` - (optional) Integer of the value send with this transaction - - `data`: `DATA` - (optional) The compiled code of a contract -2. `QUANTITY|TAG` - integer block number, or the string `"latest"`, `"earliest"` or `"pending"`, see the [default block parameter](#the-default-block-parameter) - -##### Returns - -`DATA` - the return value of executed contract. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_call","params":[{see above}],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x0" -} -``` - -*** - -#### eth_estimateGas - -Makes a call or transaction, which won't be added to the blockchain and returns the used gas, which can be used for estimating the used gas. - -##### Parameters - -See [eth_call](#eth_call) parameters, expect that all properties are optional. - -##### Returns - -`QUANTITY` - the amount of gas used. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_estimateGas","params":[{see above}],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x5208" // 21000 -} -``` - -*** - -#### eth_getBlockByHash - -Returns information about a block by hash. - - -##### Parameters - -1. `DATA`, 32 Bytes - Hash of a block. -2. `Boolean` - If `true` it returns the full transaction objects, if `false` only the hashes of the transactions. - -```js -params: [ - '0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331', - true -] -``` - -##### Returns - -`Object` - A block object, or `null` when no block was found: - - - `number`: `QUANTITY` - the block number. `null` when its pending block. - - `hash`: `DATA`, 32 Bytes - hash of the block. `null` when its pending block. - - `parentHash`: `DATA`, 32 Bytes - hash of the parent block. - - `nonce`: `DATA`, 8 Bytes - hash of the generated proof-of-work. `null` when its pending block. - - `sha3Uncles`: `DATA`, 32 Bytes - SHA3 of the uncles data in the block. - - `logsBloom`: `DATA`, 256 Bytes - the bloom filter for the logs of the block. `null` when its pending block. - - `transactionsRoot`: `DATA`, 32 Bytes - the root of the transaction trie of the block. - - `stateRoot`: `DATA`, 32 Bytes - the root of the final state trie of the block. - - `receiptsRoot`: `DATA`, 32 Bytes - the root of the receipts trie of the block. - - `miner`: `DATA`, 20 Bytes - the address of the beneficiary to whom the mining rewards were given. - - `difficulty`: `QUANTITY` - integer of the difficulty for this block. - - `totalDifficulty`: `QUANTITY` - integer of the total difficulty of the chain until this block. - - `extraData`: `DATA` - the "extra data" field of this block. - - `size`: `QUANTITY` - integer the size of this block in bytes. - - `gasLimit`: `QUANTITY` - the maximum gas allowed in this block. - - `gasUsed`: `QUANTITY` - the total used gas by all transactions in this block. - - `timestamp`: `QUANTITY` - the unix timestamp for when the block was collated. - - `transactions`: `Array` - Array of transaction objects, or 32 Bytes transaction hashes depending on the last given parameter. - - `uncles`: `Array` - Array of uncle hashes. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockByHash","params":["0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", true],"id":1}' - -// Result -{ -"id":1, -"jsonrpc":"2.0", -"result": { - "number": "0x1b4", // 436 - "hash": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", - "parentHash": "0x9646252be9520f6e71339a8df9c55e4d7619deeb018d2a3f2d21fc165dde5eb5", - "nonce": "0xe04d296d2460cfb8472af2c5fd05b5a214109c25688d3704aed5484f9a7792f2", - "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "logsBloom": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", - "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot": "0xd5855eb08b3387c0af375e9cdb6acfc05eb8f519e419b874b6ff2ffda7ed1dff", - "miner": "0x4e65fda2159562a496f9f3522f89122a3088497a", - "difficulty": "0x027f07", // 163591 - "totalDifficulty": "0x027f07", // 163591 - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000", - "size": "0x027f07", // 163591 - "gasLimit": "0x9f759", // 653145 - "minGasPrice": "0x9f759", // 653145 - "gasUsed": "0x9f759", // 653145 - "timestamp": "0x54e34e8e" // 1424182926 - "transactions": [{...},{ ... }] - "uncles": ["0x1606e5...", "0xd5145a9..."] - } -} -``` - -*** - -#### eth_getBlockByNumber - -Returns information about a block by block number. - -##### Parameters - -1. `QUANTITY|TAG` - integer of a block number, or the string `"earliest"`, `"latest"` or `"pending"`, as in the [default block parameter](#the-default-block-parameter). -2. `Boolean` - If `true` it returns the full transaction objects, if `false` only the hashes of the transactions. - -```js -params: [ - '0x1b4', // 436 - true -] -``` - -##### Returns - -See [eth_getBlockByHash](#eth_getblockbyhash) - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0x1b4", true],"id":1}' -``` - -Result see [eth_getBlockByHash](#eth_getblockbyhash) - -*** - -#### eth_getTransactionByHash - -Returns the information about a transaction requested by transaction hash. - - -##### Parameters - -1. `DATA`, 32 Bytes - hash of a transaction - -```js -params: [ - "0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238" -] -``` - -##### Returns - -`Object` - A transaction object, or `null` when no transaction was found: - - - `hash`: `DATA`, 32 Bytes - hash of the transaction. - - `nonce`: `QUANTITY` - the number of transactions made by the sender prior to this one. - - `blockHash`: `DATA`, 32 Bytes - hash of the block where this transaction was in. `null` when its pending. - - `blockNumber`: `QUANTITY` - block number where this transaction was in. `null` when its pending. - - `transactionIndex`: `QUANTITY` - integer of the transactions index position in the block. `null` when its pending. - - `from`: `DATA`, 20 Bytes - address of the sender. - - `to`: `DATA`, 20 Bytes - address of the receiver. `null` when its a contract creation transaction. - - `value`: `QUANTITY` - value transferred in Wei. - - `gasPrice`: `QUANTITY` - gas price provided by the sender in Wei. - - `gas`: `QUANTITY` - gas provided by the sender. - - `input`: `DATA` - the data send along with the transaction. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionByHash","params":["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"],"id":1}' - -// Result -{ -"id":1, -"jsonrpc":"2.0", -"result": { - "hash":"0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b", - "nonce":"0x", - "blockHash": "0xbeab0aa2411b7ab17f30a99d3cb9c6ef2fc5426d6ad6fd9e2a26a6aed1d1055b", - "blockNumber": "0x15df", // 5599 - "transactionIndex": "0x1", // 1 - "from":"0x407d73d8a49eeb85d32cf465507dd71d507100c1", - "to":"0x85h43d8a49eeb85d32cf465507dd71d507100c1", - "value":"0x7f110" // 520464 - "gas": "0x7f110" // 520464 - "gasPrice":"0x09184e72a000", - "input":"0x603880600c6000396000f300603880600c6000396000f3603880600c6000396000f360", - } -} -``` - -*** - -#### eth_getTransactionByBlockHashAndIndex - -Returns information about a transaction by block hash and transaction index position. - - -##### Parameters - -1. `DATA`, 32 Bytes - hash of a block. -2. `QUANTITY` - integer of the transaction index position. - -```js -params: [ - '0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331', - '0x0' // 0 -] -``` - -##### Returns - -See [eth_getBlockByHash](#eth_gettransactionbyhash) - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionByBlockHashAndIndex","params":[0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b, "0x0"],"id":1}' -``` - -Result see [eth_getTransactionByHash](#eth_gettransactionbyhash) - -*** - -#### eth_getTransactionByBlockNumberAndIndex - -Returns information about a transaction by block number and transaction index position. - - -##### Parameters - -1. `QUANTITY|TAG` - a block number, or the string `"earliest"`, `"latest"` or `"pending"`, as in the [default block parameter](#the-default-block-parameter). -2. `QUANTITY` - the transaction index position. - -```js -params: [ - '0x29c', // 668 - '0x0' // 0 -] -``` - -##### Returns - -See [eth_getBlockByHash](#eth_gettransactionbyhash) - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionByBlockNumberAndIndex","params":["0x29c", "0x0"],"id":1}' -``` - -Result see [eth_getTransactionByHash](#eth_gettransactionbyhash) - -*** - -#### eth_getTransactionReceipt - -Returns the receipt of a transaction by transaction hash. - -**Note** That the receipt is not available for pending transactions. - - -##### Parameters - -1. `DATA`, 32 Bytes - hash of a transaction - -```js -params: [ - '0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238' -] -``` - -##### Returns - -`Object` - A transaction receipt object, or `null` when no receipt was found: - - - `transactionHash `: `DATA`, 32 Bytes - hash of the transaction. - - `transactionIndex`: `QUANTITY` - integer of the transactions index position in the block. - - `blockHash`: `DATA`, 32 Bytes - hash of the block where this transaction was in. - - `blockNumber`: `QUANTITY` - block number where this transaction was in. - - `cumulativeGasUsed `: `QUANTITY ` - The total amount of gas used when this transaction was executed in the block. - - `gasUsed `: `QUANTITY ` - The amount of gas used by this specific transaction alone. - - `contractAddress `: `DATA`, 20 Bytes - The contract address created, if the transaction was a contract creation, otherwise `null`. - - `logs`: `Array` - Array of log objects, which this transaction generated. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionReceipt","params":["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"],"id":1}' - -// Result -{ -"id":1, -"jsonrpc":"2.0", -"result": { - transactionHash: '0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238', - transactionIndex: '0x1', // 1 - blockNumber: '0xb', // 11 - blockHash: '0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b', - cumulativeGasUsed: '0x33bc', // 13244 - gasUsed: '0x4dc', // 1244 - contractAddress: '0xb60e8dd61c5d32be8058bb8eb970870f07233155' // or null, if none was created - logs: [{ - // logs as returned by getFilterLogs, etc. - }, ...] - } -} -``` - -*** - -#### eth_getUncleByBlockHashAndIndex - -Returns information about a uncle of a block by hash and uncle index position. - - -##### Parameters - - -1. `DATA`, 32 Bytes - hash a block. -2. `QUANTITY` - the uncle's index position. - -```js -params: [ - '0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b', - '0x0' // 0 -] -``` - -##### Returns - -See [eth_getBlockByHash](#eth_getblockbyhash) - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getUncleByBlockHashAndIndex","params":["0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b", "0x0"],"id":1}' -``` - -Result see [eth_getBlockByHash](#eth_getblockbyhash) - -**Note**: An uncle doesn't contain individual transactions. - -*** - -#### eth_getUncleByBlockNumberAndIndex - -Returns information about a uncle of a block by number and uncle index position. - - -##### Parameters - -1. `QUANTITY|TAG` - a block number, or the string `"earliest"`, `"latest"` or `"pending"`, as in the [default block parameter](#the-default-block-parameter). -2. `QUANTITY` - the uncle's index position. - -```js -params: [ - '0x29c', // 668 - '0x0' // 0 -] -``` - -##### Returns - -See [eth_getBlockByHash](#eth_getblockbyhash) - -**Note**: An uncle doesn't contain individual transactions. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getUncleByBlockNumberAndIndex","params":["0x29c", "0x0"],"id":1}' -``` - -Result see [eth_getBlockByHash](#eth_getblockbyhash) - -*** - -#### eth_getCompilers - -Returns a list of available compilers in the client. - -##### Parameters -none - -##### Returns - -`Array` - Array of available compilers. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getCompilers","params":[],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": ["solidity", "lll", "serpent"] -} -``` - -*** - -#### eth_compileSolidity - -Returns compiled solidity code. - -##### Parameters - -1. `String` - The source code. - -```js -params: [ - "contract test { function multiply(uint a) returns(uint d) { return a * 7; } }", -] -``` - -##### Returns - -`DATA` - The compiled source code. - -##### Example -```js -// Request -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}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": { - "code": "0x605880600c6000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa114602e57005b603d6004803590602001506047565b8060005260206000f35b60006007820290506053565b91905056", - "info": { - "source": "contract test {\n function multiply(uint a) constant returns(uint d) {\n return a * 7;\n }\n}\n", - "language": "Solidity", - "languageVersion": "0", - "compilerVersion": "0.9.19", - "abiDefinition": [ - { - "constant": true, - "inputs": [ - { - "name": "a", - "type": "uint256" - } - ], - "name": "multiply", - "outputs": [ - { - "name": "d", - "type": "uint256" - } - ], - "type": "function" - } - ], - "userDoc": { - "methods": {} - }, - "developerDoc": { - "methods": {} - } - } - -} -``` - -*** - -#### eth_compileLLL - -Returns compiled LLL code. - -##### Parameters - -1. `String` - The source code. - -```js -params: [ - "(returnlll (suicide (caller)))", -] -``` - -##### Returns - -`DATA` - The compiled source code. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_compileSolidity","params":["(returnlll (suicide (caller)))"],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x603880600c6000396000f3006001600060e060020a600035048063c6888fa114601857005b6021600435602b565b8060005260206000f35b600081600702905091905056" // the compiled source code -} -``` - -*** - -#### eth_compileSerpent - -Returns compiled serpent code. - -##### Parameters - -1. `String` - The source code. - -```js -params: [ - "/* some serpent */", -] -``` - -##### Returns - -`DATA` - The compiled source code. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_compileSerpent","params":["/* some serpent */"],"id":1}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x603880600c6000396000f3006001600060e060020a600035048063c6888fa114601857005b6021600435602b565b8060005260206000f35b600081600702905091905056" // the compiled source code -} -``` - -*** - -#### eth_newFilter - -Creates a filter object, based on filter options, to notify when the state changes (logs). -To check if the state has changed, call [eth_getFilterChanges](#eth_getfilterchanges). - -##### Parameters - -1. `Object` - The filter options: - - `fromBlock`: `QUANTITY|TAG` - (optional, default: `"latest"`) Integer block number, or `"latest"` for the last mined block or `"pending"`, `"earliest"` for not yet mined transactions. - - `toBlock`: `QUANTITY|TAG` - (optional, default: `"latest"`) Integer block number, or `"latest"` for the last mined block or `"pending"`, `"earliest"` for not yet mined transactions. - - `address`: `DATA|Array`, 20 Bytes - (optional) Contract address or a list of addresses from which logs should originate. - - `topics`: `Array of DATA`, - (optional) Array of 32 Bytes `DATA` topics. Each topic can also be an array of DATA with "or" options. - -```js -params: [{ - "fromBlock": "0x1", - "toBlock": "0x2", - "address": "0x8888f1f195afa192cfee860698584c030f4c9db1", - "topics": ["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b", null, [0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b, 0x000000000000000000000000aff3454fce5edbc8cca8697c15331677e6ebccc]] -}] -``` - -##### Returns - -`QUANTITY` - A filter id. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_newFilter","params":[{"topics":["0x12341234"]}],"id":73}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x1" // 1 -} -``` - -*** - -#### eth_newBlockFilter - -Creates a filter in the node, to notify when a new block arrives. -To check if the state has changed, call [eth_getFilterChanges](#eth_getfilterchanges). - -##### Parameters -None - -##### Returns - -`QUANTITY` - A filter id. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_newBlockFilter","params":[],"id":73}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x1" // 1 -} -``` - -*** - -#### eth_newPendingTransactionFilter - -Creates a filter in the node, to notify when new pending transactions arrive. -To check if the state has changed, call [eth_getFilterChanges](#eth_getfilterchanges). - -##### Parameters -None - -##### Returns - -`QUANTITY` - A filter id. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_newPendingTransactionFilter","params":[],"id":73}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0x1" // 1 -} -``` - -*** - -#### eth_uninstallFilter - -Uninstalls a filter with given id. Should always be called when watch is no longer needed. -Additonally Filters timeout when they aren't requested with [eth_getFilterChanges](#eth_getfilterchanges) for a period of time. - - -##### Parameters - -1. `QUANTITY` - The filter id. - -```js -params: [ - "0xb" // 11 -] -``` - -##### Returns - -`Boolean` - `true` if the filter was successfully uninstalled, otherwise `false`. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_uninstallFilter","params":["0xb"],"id":73}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": true -} -``` - -*** - -#### eth_getFilterChanges - -Polling method for a filter, which returns an array of logs which occurred since last poll. - - -##### Parameters - -1. `QUANTITY` - the filter id. - -```js -params: [ - "0x16" // 22 -] -``` - -##### Returns - -`Array` - Array of log objects, or an empty array if nothing has changed since last poll. - -- For filters created with `eth_newBlockFilter` the return are block hashes (`DATA`, 32 Bytes), e.g. `["0x3454645634534..."]`. -- For filters created with `eth_newPendingTransactionFilter ` the return are transaction hashes (`DATA`, 32 Bytes), e.g. `["0x6345343454645..."]`. -- For filters created with `eth_newFilter` logs are objects with following params: - - - `type`: `TAG` - `pending` when the log is pending. `mined` if log is already mined. - - `logIndex`: `QUANTITY` - integer of the log index position in the block. `null` when its pending log. - - `transactionIndex`: `QUANTITY` - integer of the transactions index position log was created from. `null` when its pending log. - - `transactionHash`: `DATA`, 32 Bytes - hash of the transactions this log was created from. `null` when its pending log. - - `blockHash`: `DATA`, 32 Bytes - hash of the block where this log was in. `null` when its pending. `null` when its pending log. - - `blockNumber`: `QUANTITY` - the block number where this log was in. `null` when its pending. `null` when its pending log. - - `address`: `DATA`, 20 Bytes - address from which this log originated. - - `data`: `DATA` - contains one or more 32 Bytes non-indexed arguments of the log. - - `topics`: `Array of DATA` - Array of 0 to 4 32 Bytes `DATA` of indexed log arguments. (In *solidity*: The first topic is the *hash* of the signature of the event (e.g. `Deposit(address,bytes32,uint256)`), except you declared the event with the `anonymous` specifier.) - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getFilterChanges","params":["0x16"],"id":73}' - -// Result -{ - "id":1, - "jsonrpc":"2.0", - "result": [{ - "logIndex": "0x1", // 1 - "blockNumber":"0x1b4" // 436 - "blockHash": "0x8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcfdf829c5a142f1fccd7d", - "transactionHash": "0xdf829c5a142f1fccd7d8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcf", - "transactionIndex": "0x0", // 0 - "address": "0x16c5785ac562ff41e2dcfdf829c5a142f1fccd7d", - "data":"0x0000000000000000000000000000000000000000000000000000000000000000", - "topics": ["0x59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a5"] - },{ - ... - }] -} -``` - -*** - -#### eth_getFilterLogs - -Returns an array of all logs matching filter with given id. - - -##### Parameters - -1. `QUANTITY` - The filter id. - -```js -params: [ - "0x16" // 22 -] -``` - -##### Returns - -See [eth_getFilterChanges](#eth_getfilterchanges) - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getFilterLogs","params":["0x16"],"id":74}' -``` - -Result see [eth_getFilterChanges](#eth_getfilterchanges) - -*** - -#### eth_getLogs - -Returns an array of all logs matching a given filter object. - -##### Parameters - -1. `Object` - the filter object, see [eth_newFilter parameters](#eth_newfilter). - -```js -params: [{ - "topics": ["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b"] -}] -``` - -##### Returns - -See [eth_getFilterChanges](#eth_getfilterchanges) - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getLogs","params":[{"topics":["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b"]}],"id":74}' -``` - -Result see [eth_getFilterChanges](#eth_getfilterchanges) - -*** - -#### eth_getWork - -Returns the hash of the current block, the seedHash, and the boundary condition to be met ("target"). - -##### Parameters -none - -##### Returns - -`Array` - Array with the following properties: - 1. `DATA`, 32 Bytes - current block header pow-hash - 2. `DATA`, 32 Bytes - the seed hash used for the DAG. - 3. `DATA`, 32 Bytes - the boundary condition ("target"), 2^256 / difficulty. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getWork","params":[],"id":73}' - -// Result -{ - "id":1, - "jsonrpc":"2.0", - "result": [ - "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", - "0x5EED00000000000000000000000000005EED0000000000000000000000000000", - "0xd1ff1c01710000000000000000000000d1ff1c01710000000000000000000000" - ] -} -``` - -*** - -#### eth_submitWork - -Used for submitting a proof-of-work solution. - - -##### Parameters - -1. `DATA`, 8 Bytes - The nonce found (64 bits) -2. `DATA`, 32 Bytes - The header's pow-hash (256 bits) -3. `DATA`, 32 Bytes - The mix digest (256 bits) - -```js -params: [ - "0x0000000000000001", - "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", - "0xD1FE5700000000000000000000000000D1FE5700000000000000000000000000" -] -``` - -##### Returns - -`Boolean` - returns `true` if the provided solution is valid, otherwise `false`. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0", "method":"eth_submitWork", "params":["0x0000000000000001", "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", "0xD1GE5700000000000000000000000000D1GE5700000000000000000000000000"],"id":73}' - -// Result -{ - "id":1, - "jsonrpc":"2.0", - "result": true -} -``` - -*** - -#### eth_submitHashrate - -Used for submitting mining hashrate. - - -##### Parameters - -1. `Hashrate`, a hexadecimal string representation (32 bytes) of the hash rate -2. `ID`, String - A random hexadecimal(32 bytes) ID identifying the client - -```js -params: [ - "0x0000000000000000000000000000000000000000000000000000000000500000", - "0x59daa26581d0acd1fce254fb7e85952f4c09d0915afd33d3886cd914bc7d283c" -] -``` - -##### Returns - -`Boolean` - returns `true` if submitting went through succesfully and `false` otherwise. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0", "method":"eth_submitHashrate", "params":["0x0000000000000000000000000000000000000000000000000000000000500000", "0x59daa26581d0acd1fce254fb7e85952f4c09d0915afd33d3886cd914bc7d283c"],"id":73}' - -// Result -{ - "id":73, - "jsonrpc":"2.0", - "result": true -} -``` - -*** - -#### db_putString - -Stores a string in the local database. - -**Note** this function is deprecated and will be removed in the future. - -##### Parameters - -1. `String` - Database name. -2. `String` - Key name. -3. `String` - String to store. - -```js -params: [ - "testDB", - "myKey", - "myString" -] -``` - -##### Returns - -`Boolean` - returns `true` if the value was stored, otherwise `false`. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"db_putString","params":["testDB","myKey","myString"],"id":73}' - -// Result -{ - "id":1, - "jsonrpc":"2.0", - "result": true -} -``` - -*** - -#### db_getString - -Returns string from the local database. - -**Note** this function is deprecated and will be removed in the future. - -##### Parameters - -1. `String` - Database name. -2. `String` - Key name. - -```js -params: [ - "testDB", - "myKey", -] -``` - -##### Returns - -`String` - The previously stored string. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"db_getString","params":["testDB","myKey"],"id":73}' - -// Result -{ - "id":1, - "jsonrpc":"2.0", - "result": "myString" -} -``` - -*** - -#### db_putHex - -Stores binary data in the local database. - -**Note** this function is deprecated and will be removed in the future. - - -##### Parameters - -1. `String` - Database name. -2. `String` - Key name. -3. `DATA` - The data to store. - -```js -params: [ - "testDB", - "myKey", - "0x68656c6c6f20776f726c64" -] -``` - -##### Returns - -`Boolean` - returns `true` if the value was stored, otherwise `false`. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"db_putHex","params":["testDB","myKey","0x68656c6c6f20776f726c64"],"id":73}' - -// Result -{ - "id":1, - "jsonrpc":"2.0", - "result": true -} -``` - -*** - -#### db_getHex - -Returns binary data from the local database. - -**Note** this function is deprecated and will be removed in the future. - - -##### Parameters - -1. `String` - Database name. -2. `String` - Key name. - -```js -params: [ - "testDB", - "myKey", -] -``` - -##### Returns - -`DATA` - The previously stored data. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"db_getHex","params":["testDB","myKey"],"id":73}' - -// Result -{ - "id":1, - "jsonrpc":"2.0", - "result": "0x68656c6c6f20776f726c64" -} -``` - -*** - -#### shh_version - -Returns the current whisper protocol version. - -##### Parameters -none - -##### Returns - -`String` - The current whisper protocol version - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"shh_version","params":[],"id":67}' - -// Result -{ - "id":67, - "jsonrpc": "2.0", - "result": "2" -} -``` - -*** - -#### shh_post - -Sends a whisper message. - -##### Parameters - -1. `Object` - The whisper post object: - - `from`: `DATA`, 60 Bytes - (optional) The identity of the sender. - - `to`: `DATA`, 60 Bytes - (optional) The identity of the receiver. When present whisper will encrypt the message so that only the receiver can decrypt it. - - `topics`: `Array of DATA` - Array of `DATA` topics, for the receiver to identify messages. - - `payload`: `DATA` - The payload of the message. - - `priority`: `QUANTITY` - The integer of the priority in a rang from ... (?). - - `ttl`: `QUANTITY` - integer of the time to live in seconds. - -```js -params: [{ - from: "0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1", - to: "0x3e245533f97284d442460f2998cd41858798ddf04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a0d4d661997d3940272b717b1", - topics: ["0x776869737065722d636861742d636c69656e74", "0x4d5a695276454c39425154466b61693532"], - payload: "0x7b2274797065223a226d6", - priority: "0x64", - ttl: "0x64", -}] -``` - -##### Returns - -`Boolean` - returns `true` if the message was send, otherwise `false`. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"shh_post","params":[{"from":"0xc931d93e97ab07fe42d923478ba2465f2..","topics": ["0x68656c6c6f20776f726c64"],"payload":"0x68656c6c6f20776f726c64","ttl":"0x64","priority":"0x64"}],"id":73}' - -// Result -{ - "id":1, - "jsonrpc":"2.0", - "result": true -} -``` - -*** - -#### shh_newIdentity - -Creates new whisper identity in the client. - -##### Parameters -none - -##### Returns - -`DATA`, 60 Bytes - the address of the new identiy. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"shh_newIdentity","params":[],"id":73}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0xc931d93e97ab07fe42d923478ba2465f283f440fd6cabea4dd7a2c807108f651b7135d1d6ca9007d5b68aa497e4619ac10aa3b27726e1863c1fd9b570d99bbaf" -} -``` - -*** - -#### shh_hasIdentity - -Checks if the client hold the private keys for a given identity. - - -##### Parameters - -1. `DATA`, 60 Bytes - The identity address to check. - -```js -params: [ - "0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1" -] -``` - -##### Returns - -`Boolean` - returns `true` if the client holds the privatekey for that identity, otherwise `false`. - - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"shh_hasIdentity","params":["0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1"],"id":73}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": true -} -``` - -*** - -#### shh_newGroup - -(?) - -##### Parameters -none - -##### Returns - -`DATA`, 60 Bytes - the address of the new group. (?) - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"shh_newGroup","params":[],"id":73}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": "0xc65f283f440fd6cabea4dd7a2c807108f651b7135d1d6ca90931d93e97ab07fe42d923478ba2407d5b68aa497e4619ac10aa3b27726e1863c1fd9b570d99bbaf" -} -``` - -*** - -#### shh_addToGroup - -(?) - -##### Parameters - -1. `DATA`, 60 Bytes - The identity address to add to a group (?). - -```js -params: [ - "0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1" -] -``` - -##### Returns - -`Boolean` - returns `true` if the identity was successfully added to the group, otherwise `false` (?). - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"shh_addToGroup","params":["0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1"],"id":73}' - -// Result -{ - "id":1, - "jsonrpc": "2.0", - "result": true -} -``` - -*** - -#### shh_newFilter - -Creates filter to notify, when client receives whisper message matching the filter options. - - -##### Parameters - -1. `Object` - The filter options: - - `to`: `DATA`, 60 Bytes - (optional) Identity of the receiver. *When present it will try to decrypt any incoming message if the client holds the private key to this identity.* - - `topics`: `Array of DATA` - Array of `DATA` topics which the incoming message's topics should match. You can use the following combinations: - - `[A, B] = A && B` - - `[A, [B, C]] = A && (B || C)` - - `[null, A, B] = ANYTHING && A && B` `null` works as a wildcard - -```js -params: [{ - "topics": ['0x12341234bf4b564f'], - "to": "0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1" -}] -``` - -##### Returns - -`QUANTITY` - The newly created filter. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"shh_newFilter","params":[{"topics": ['0x12341234bf4b564f'],"to": "0x2341234bf4b2341234bf4b564f..."}],"id":73}' - -// Result -{ - "id":1, - "jsonrpc":"2.0", - "result": "0x7" // 7 -} -``` - -*** - -#### shh_uninstallFilter - -Uninstalls a filter with given id. Should always be called when watch is no longer needed. -Additonally Filters timeout when they aren't requested with [shh_getFilterChanges](#shh_getfilterchanges) for a period of time. - - -##### Parameters - -1. `QUANTITY` - The filter id. - -```js -params: [ - "0x7" // 7 -] -``` - -##### Returns - -`Boolean` - `true` if the filter was successfully uninstalled, otherwise `false`. - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"shh_uninstallFilter","params":["0x7"],"id":73}' - -// Result -{ - "id":1, - "jsonrpc":"2.0", - "result": true -} -``` - -*** - -#### shh_getFilterChanges - -Polling method for whisper filters. Returns new messages since the last call of this method. - -**Note** calling the [shh_getMessages](#shh_getmessages) method, will reset the buffer for this method, so that you won't receive duplicate messages. - - -##### Parameters - -1. `QUANTITY` - The filter id. - -```js -params: [ - "0x7" // 7 -] -``` - -##### Returns - -`Array` - Array of messages received since last poll: - - - `hash`: `DATA`, 32 Bytes (?) - The hash of the message. - - `from`: `DATA`, 60 Bytes - The sender of the message, if a sender was specified. - - `to`: `DATA`, 60 Bytes - The receiver of the message, if a receiver was specified. - - `expiry`: `QUANTITY` - Integer of the time in seconds when this message should expire (?). - - `ttl`: `QUANTITY` - Integer of the time the message should float in the system in seconds (?). - - `sent`: `QUANTITY` - Integer of the unix timestamp when the message was sent. - - `topics`: `Array of DATA` - Array of `DATA` topics the message contained. - - `payload`: `DATA` - The payload of the message. - - `workProved`: `QUANTITY` - Integer of the work this message required before it was send (?). - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"shh_getFilterChanges","params":["0x7"],"id":73}' - -// Result -{ - "id":1, - "jsonrpc":"2.0", - "result": [{ - "hash": "0x33eb2da77bf3527e28f8bf493650b1879b08c4f2a362beae4ba2f71bafcd91f9", - "from": "0x3ec052fc33..", - "to": "0x87gdf76g8d7fgdfg...", - "expiry": "0x54caa50a", // 1422566666 - "sent": "0x54ca9ea2", // 1422565026 - "ttl": "0x64" // 100 - "topics": ["0x6578616d"], - "payload": "0x7b2274797065223a226d657373616765222c2263686...", - "workProved": "0x0" - }] -} -``` - -*** - -#### shh_getMessages - -Get all messages matching a filter, which are still existing in the node's buffer. - -**Note** calling this method, will also reset the buffer for the [shh_getFilterChanges](#shh_getfilterchanges) method, so that you won't receive duplicate messages. - -##### Parameters - -1. `QUANTITY` - The filter id. - -```js -params: [ - "0x7" // 7 -] -``` - -##### Returns - -See [shh_getFilterChanges](#shh_getfilterchanges) - -##### Example -```js -// Request -curl -X POST --data '{"jsonrpc":"2.0","method":"shh_getMessages","params":["0x7"],"id":73}' -``` - -Result see [shh_getFilterChanges](#shh_getfilterchanges) diff --git a/JavaScript-API.md b/JavaScript-API.md deleted file mode 100644 index 213269b39..000000000 --- a/JavaScript-API.md +++ /dev/null @@ -1,2416 +0,0 @@ ---- -name: Javascript API -category: ---- - -# Web3 JavaScript Ðapp API - -To make your Ðapp work on Ethereum, you can use the `web3` object provided by the [web3.js library](https://github.com/ethereum/web3.js). Under the hood it communicates to a local node through [RPC calls](https://github.com/ethereum/wiki/wiki/JSON-RPC). web3.js works with any Ethereum node, which exposes an RPC layer. - -`web3` contains the `eth` object - `web3.eth` (for specifically Ethereum blockchain interactions) and the `shh` object - `web3.shh` (for Whisper interaction). Over time we'll introduce other objects for each of the other web3 protocols. Working [examples can be found here](https://github.com/ethereum/web3.js/tree/master/example). - -If you want to look at some more sophisticated examples using web3.js check out these [useful Ðapp patterns](https://github.com/ethereum/wiki/wiki/Useful-Ðapp-Patterns). - -## Using callbacks - -As this API is designed to work with a local RPC node and all its functions are by default use synchronous HTTP requests.con - -If you want to make an asynchronous request, you can pass an optional callback as the last parameter to most functions. -All callbacks are using an [error first callback](http://fredkschott.com/post/2014/03/understanding-error-first-callbacks-in-node-js/) style: - -```js -web3.eth.getBlock(48, function(error, result){ - if(!error) - console.log(result) - else - console.error(error); -}) -``` - -## Batch requests - -Batch requests allow queuing up requests and processing them at once. - -```js -var batch = web3.createBatch(); -batch.add(web3.eth.getBalance.request('0x0000000000000000000000000000000000000000', 'latest', callback)); -batch.add(web3.eth.contract(abi).at(address).balance.request(address, callback2)); -batch.execute(); -``` - -## A note on big numbers in web3.js - -You will always get a BigNumber object for balance values as JavaScript is not able to handle big numbers correctly. -Look at the following examples: - -```js -"101010100324325345346456456456456456456" -// "101010100324325345346456456456456456456" -101010100324325345346456456456456456456 -// 1.0101010032432535e+38 -``` - -web3.js depends on the [BigNumber Library](https://github.com/MikeMcl/bignumber.js/) and adds it automatically. - -```js -var balance = new BigNumber('131242344353464564564574574567456'); -// or var balance = web3.eth.getBalance(someAddress); - -balance.plus(21).toString(10); // toString(10) converts it to a number string -// "131242344353464564564574574567477" -``` - -The next example wouldn't work as we have more than 20 floating points, therefore it is recommended that you always keep your balance in *wei* and only transform it to other units when presenting to the user: -```js -var balance = new BigNumber('13124.234435346456466666457455567456'); - -balance.plus(21).toString(10); // toString(10) converts it to a number string, but can only show max 20 floating points -// "13145.23443534645646666646" // you number would be cut after the 20 floating point -``` - -## Web3 Javascript Ðapp API Reference - -* [web3](#web3) - * [version](#web3versionapi) - * [api](#web3versionapi) - * [node](#web3versionnode) - * [network](#web3versionnetwork) - * [ethereum](#web3versionethereum) - * [whisper](#web3versionwhisper) - * [isConnected()](#web3isconnected) - * [setProvider(provider)](#web3setprovider) - * [currentProvider](#web3currentprovider) - * [reset()](#web3reset) - * [sha3(string)](#web3sha3) - * [toHex(stringOrNumber)](#web3tohex) - * [toAscii(hexString)](#web3toascii) - * [fromAscii(textString, [padding])](#web3fromascii) - * [toDecimal(hexString)](#web3todecimal) - * [toChecksumAddress(string)](#web3tochecksumaddress) - * [fromDecimal(number)](#web3fromdecimal) - * [fromWei(numberStringOrBigNumber, unit)](#web3fromwei) - * [toWei(numberStringOrBigNumber, unit)](#web3towei) - * [toBigNumber(numberOrHexString)](#web3tobignumber) - * [isAddress(hexString)](#web3isAddress) - * [net](#web3net) - * [listening/getListening](#web3netlistening) - * [peerCount/getPeerCount](#web3ethpeercount) - * [eth](#web3eth) - * [defaultAccount](#web3ethdefaultaccount) - * [defaultBlock](#web3ethdefaultblock) - * [syncing/getSyncing](#web3ethsyncing) - * [isSyncing](#web3ethissyncing) - * [coinbase/getCoinbase](#web3ethcoinbase) - * [hashrate/getHashrate](#web3ethhashrate) - * [gasPrice/getGasPrice](#web3ethgasprice) - * [accounts/getAccounts](#web3ethaccounts) - * [mining/getMining](#web3ethmining) - * [blockNumber/getBlockNumber](#web3ethblocknumber) - * [register(hexString)](#web3ethregister) (Not implemented yet) - * [unRegister(hexString)](#web3ethunregister) (Not implemented yet) - * [getBalance(address)](#web3ethgetbalance) - * [getStorageAt(address, position)](#web3ethgetstorageat) - * [getCode(address)](#web3ethgetcode) - * [getBlock(hash/number)](#web3ethgetblock) - * [getBlockTransactionCount(hash/number)](#web3ethgetblocktransactioncount) - * [getUncle(hash/number)](#web3ethgetuncle) - * [getBlockUncleCount(hash/number)](#web3ethgetblockunclecount) - * [getTransaction(hash)](#web3ethgettransaction) - * [getTransactionFromBlock(hashOrNumber, indexNumber)](#web3ethgettransactionfromblock) - * [getTransactionReceipt(hash)](#web3ethgettransactionreceipt) - * [getTransactionCount(address)](#web3ethgettransactioncount) - * [sendTransaction(object)](#web3ethsendtransaction) - * [call(object)](#web3ethcall) - * [estimateGas(object)](#web3ethestimategas) - * [filter(array (, options) )](#web3ethfilter) - - [watch(callback)](#web3ethfilter) - - [stopWatching(callback)](#web3ethfilter) - - [get()](#web3ethfilter) - * [contract(abiArray)](#web3ethcontract) - * [contract.myMethod()](#contract-methods) - * [contract.myEvent()](#contract-events) - * [contract.allEvents()](#contract-allevents) - * [getCompilers()](#web3ethgetcompilers) - * [compile.lll(string)](#web3ethcompilelll) - * [compile.solidity(string)](#web3ethcompilesolidity) - * [compile.serpent(string)](#web3ethcompileserpent) - * [namereg](#web3ethnamereg) - * [sendIBANTransaction](#web3ethsendibantransaction) - * [iban](#web3ethiban) - * [fromAddress](#web3ethibanfromaddress) - * [fromBban](#web3ethibanfrombban) - * [createIndirect](#web3ethibancreateindirect) - * [isValid](#web3ethibanisvalid) - * [isDirect](#web3ethibanisdirect) - * [isIndirect](#web3ethibanisindirect) - * [checksum](#web3ethibanchecksum) - * [institution](#web3ethibaninstitution) - * [client](#web3ethibanclient) - * [address](#web3ethibanaddress) - * [toString](#web3ethibantostring) - * [db](#web3db) - * [putString(name, key, value)](#web3dbputstring) - * [getString(name, key)](#web3dbgetstring) - * [putHex(name, key, value)](#web3dbputhex) - * [getHex(name, key)](#web3dbgethex) - * [shh](#web3shh) - * [post(postObject)](#web3shhpost) - * [newIdentity()](#web3shhnewidentity) - * [hasIdentity(hexString)](#web3shhhaveidentity) - * [newGroup(_id, _who)](#web3shhnewgroup) - * [addToGroup(_id, _who)](#web3shhaddtogroup) - * [filter(object/string)](#web3shhfilter) - * [watch(callback)](#web3shhfilter) - * [stopWatching(callback)](#web3shhfilter) - * [get(callback)](#web3shhfilter) - -### Usage - -#### web3 -The `web3` object provides all methods. - -##### Example - -```js -var Web3 = require('web3'); -// create an instance of web3 using the HTTP provider. -// NOTE in mist web3 is already available, so check first if it's available before instantiating -var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); -``` - -*** - -#### web3.version.api - -```js -web3.version.api -// or async -web3.version.getApi(callback(error, result){ ... }) -``` - -##### Returns - -`String` - The ethereum js api version. - -##### Example - -```js -var version = web3.version.api; -console.log(version); // "0.2.0" -``` - -*** - -#### web3.version.node - - web3.version.node - // or async - web3.version.getClient(callback(error, result){ ... }) - - -##### Returns - -`String` - The client/node version. - -##### Example - -```js -var version = web3.version.node; -console.log(version); // "Mist/v0.9.3/darwin/go1.4.1" -``` - -*** - -#### web3.version.network - - web3.version.network - // or async - web3.version.getNetwork(callback(error, result){ ... }) - - -##### Returns - -`String` - The network protocol version. - -##### Example - -```js -var version = web3.version.network; -console.log(version); // 54 -``` - -*** - -#### web3.version.ethereum - - web3.version.ethereum - // or async - web3.version.getEthereum(callback(error, result){ ... }) - - -##### Returns - -`String` - The ethereum protocol version. - -##### Example - -```js -var version = web3.version.ethereum; -console.log(version); // 60 -``` - -*** - -#### web3.version.whisper - - web3.version.whisper - // or async - web3.version.getWhisper(callback(error, result){ ... }) - - -##### Returns - -`String` - The whisper protocol version. - -##### Example - -```js -var version = web3.version.whisper; -console.log(version); // 20 -``` - -*** -#### web3.isConnected - - web3.isConnected() - -Should be called to check if a connection to a node exists - -##### Parameters -none - -##### Returns - -`Boolean` - -##### Example - -```js -if(!web3.isConnected()) { - - // show some dialog to ask the user to start a node - -} else { - - // start web3 filters, calls, etc - -} -``` - -*** - -#### web3.setProvider - - web3.setProvider(provider) - -Should be called to set provider. - -##### Parameters -none - -##### Returns - -`undefined` - -##### Example - -```js -web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545')); // 8080 for cpp/AZ, 8545 for go/mist -``` - -*** - -#### web3.currentProvider - - web3.currentProvider - -Will contain the current provider, if one is set. This can be used to check if mist etc. set already a provider. - - -##### Returns - -`Object` - The provider set or `null`; - -##### Example - -```js -// Check if mist etc. already set a provider -if(!web3.currentProvider) - web3.setProvider(new web3.providers.HttpProvider("http://localhost:8545")); - -``` - -*** - -#### web3.reset - - web3.reset(keepIsSyncing) - -Should be called to reset state of web3. Resets everything except manager. Uninstalls all filters. Stops polling. - -##### Parameters - -1. `Boolean` - If `true` it will uninstall all filters, but will keep the [web3.eth.isSyncing()](#web3ethissyncing) polls - -##### Returns - -`undefined` - -##### Example - -```js -web3.reset(); -``` - -*** - -#### web3.sha3 - - web3.sha3(string [, callback]) - -##### Parameters - -1. `String` - The string to hash using the SHA3 algorithm -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -`String` - The SHA3 of the given data. - -##### Example - -```js -var str = web3.sha3("Some ASCII string to be hashed"); -console.log(str); // "0x536f6d6520415343494920737472696e6720746f20626520686173686564" - -var hash = web3.sha3(str); -console.log(hash); // "0xb21dbc7a5eb6042d91f8f584af266f1a512ac89520f43562c6c1e37eab6eb0c4" -``` - -*** - -#### web3.toHex - - web3.toHex(mixed); - -Converts any value into HEX. - -##### Parameters - -1. `String|Number|Object|Array|BigNumber` - The value to parse to HEX. If its an object or array it will be `JSON.stringify` first. If its a BigNumber it will make it the HEX value of a number. - -##### Returns - -`String` - The hex string of `mixed`. - -##### Example - -```js -var str = web3.toHex({test: 'test'}); -console.log(str); // '0x7b2274657374223a2274657374227d' -``` - -*** - -#### web3.toAscii - - web3.toAscii(hexString); - -Converts a HEX string into a ASCII string. - -##### Parameters - -1. `String` - A HEX string to be converted to ascii. - -##### Returns - -`String` - An ASCII string made from the given `hexString`. - -##### Example - -```js -var str = web3.toAscii("0x657468657265756d000000000000000000000000000000000000000000000000"); -console.log(str); // "ethereum" -``` - -*** - -#### web3.fromAscii - - web3.fromAscii(string [, padding]); - -Converts any ASCII string to a HEX string. - -##### Parameters - -1. `String` - An ASCII string to be converted to HEX. -2. `Number` - The number of bytes the returned HEX string should have. - -##### Returns - -`String` - The converted HEX string. - -##### Example - -```js -var str = web3.fromAscii('ethereum'); -console.log(str); // "0x657468657265756d" - -var str2 = web3.fromAscii('ethereum', 32); -console.log(str2); // "0x657468657265756d000000000000000000000000000000000000000000000000" -``` - -*** - -#### web3.toChecksumAddress - - web3.toChecksumAddress(hexString); - -Converts a string to the checksummed address equivalent. - -##### Parameters - -1. `String` - A string to be converted to a checksummed address. - - -##### Returns - -`String` - A string containing the checksummed address. - -##### Example - -```js -var myAddress = web3.toChecksumAddress('0xa0c876ec9f2d817c4304a727536f36363840c02c'); -console.log(myAddress); // '0xA0C876eC9F2d817c4304A727536f36363840c02c' -``` - -*** - -#### web3.toDecimal - - web3.toDecimal(hexString); - -Converts a HEX string to its number representation. - -##### Parameters - -1. `String` - An HEX string to be converted to a number. - - -##### Returns - -`Number` - The number representing the data `hexString`. - -##### Example - -```js -var number = web3.toDecimal('0x15'); -console.log(number); // 21 -``` - -*** - -#### web3.fromDecimal - - web3.fromDecimal(number); - -Converts a number or number string to its HEX representation. - -##### Parameters - -1. `Number|String` - A number to be converted to a HEX string. - -##### Returns - -`String` - The HEX string representing of the given `number`. - -##### Example - -```js -var value = web3.fromDecimal('21'); -console.log(value); // "0x15" -``` - -*** - -#### web3.fromWei - - web3.fromWei(number, unit) - -Converts a number of wei into the following ethereum units: - -- `kwei`/`ada` -- `mwei`/`babbage` -- `gwei`/`shannon` -- `szabo` -- `finney` -- `ether` -- `kether`/`grand`/`einstein` -- `mether` -- `gether` -- `tether` - -##### Parameters - -1. `Number|String|BigNumber` - A number or BigNumber instance. -2. `String` - One of the above ether units. - - -##### Returns - -`String|BigNumber` - Either a number string, or a BigNumber instance, depending on the given `number` parameter. - -##### Example - -```js -var value = web3.fromWei('21000000000000', 'finney'); -console.log(value); // "0.021" -``` - -*** - -#### web3.toWei - - web3.toWei(number, unit) - -Converts an ethereum unit into wei. Possible units are: - -- `kwei`/`ada` -- `mwei`/`babbage` -- `gwei`/`shannon` -- `szabo` -- `finney` -- `ether` -- `kether`/`grand`/`einstein` -- `mether` -- `gether` -- `tether` - -##### Parameters - -1. `Number|String|BigNumber` - A number or BigNumber instance. -2. `String` - One of the above ether units. - -##### Returns - -`String|BigNumber` - Either a number string, or a BigNumber instance, depending on the given `number` parameter. - -##### Example - -```js -var value = web3.toWei('1', 'ether'); -console.log(value); // "1000000000000000000" -``` - -*** - -#### web3.toBigNumber - - web3.toBigNumber(numberOrHexString); - -Converts a given number into a BigNumber instance. - -See the [note on BigNumber](#a-note-on-big-numbers-in-javascript). - -##### Parameters - -1. `Number|String` - A number, number string or HEX string of a number. - - -##### Returns - -`BigNumber` - A BigNumber instance representing the given value. - - -##### Example - -```js -var value = web3.toBigNumber('200000000000000000000001'); -console.log(value); // instanceOf BigNumber -console.log(value.toNumber()); // 2.0000000000000002e+23 -console.log(value.toString(10)); // '200000000000000000000001' -``` - -*** - -### web3.net - -#### web3.net.listening - - web3.net.listening - // or async - web3.net.getListening(callback(error, result){ ... }) - -This property is read only and says whether the node is actively listening for network connections or not. - -##### Returns - -`Boolean` - `true` if the client is actively listening for network connections, otherwise `false`. - -##### Example - -```js -var listening = web3.net.listening; -console.log(listening); // true of false -``` - -*** - -#### web3.net.peerCount - - web3.net.peerCount - // or async - web3.net.getPeerCount(callback(error, result){ ... }) - -This property is read only and returns the number of connected peers. - -##### Returns - -`Number` - The number of peers currently connected to the client. - -##### Example - -```js -var peerCount = web3.net.peerCount; -console.log(peerCount); // 4 -``` - -*** - -### web3.eth - -Contains the ethereum blockchain related methods. - -##### Example - -```js -var eth = web3.eth; -``` - -*** - -#### web3.eth.defaultAccount - - web3.eth.defaultAccount - -This default address is used for the following methods (optionally you can overwrite it by specifying the `from` property): - -- [web3.eth.sendTransaction()](#web3ethsendtransaction) -- [web3.eth.call()](#web3ethcall) - -##### Values - -`String`, 20 Bytes - Any address you own, or where you have the private key for. - -*Default is* `undefined`. - -##### Returns - -`String`, 20 Bytes - The currently set default address. - -##### Example - -```js -var defaultAccount = web3.eth.defaultAccount; -console.log(defaultAccount); // '' - -// set the default block -web3.eth.defaultAccount = '0x8888f1f195afa192cfee860698584c030f4c9db1'; -``` - -*** - -#### web3.eth.defaultBlock - - web3.eth.defaultBlock - -This default block is used for the following methods (optionally you can overwrite the defaultBlock by passing it as the last parameter): - -- [web3.eth.getBalance()](#web3ethgetbalance) -- [web3.eth.getCode()](#web3ethgetcode) -- [web3.eth.getTransactionCount()](#web3ethgettransactioncount) -- [web3.eth.getStorageAt()](#web3ethgetstorageat) -- [web3.eth.call()](#web3ethcall) - -##### Values - -Default block parameters can be one of the following: - -- `Number` - a block number -- `String` - `"earliest"`, the genisis block -- `String` - `"latest"`, the latest block (current head of the blockchain) -- `String` - `"pending"`, the currently mined block (including pending transactions) - -*Default is* `latest` - -##### Returns - -`Number|String` - The default block number to use when querying a state. - -##### Example - -```js -var defaultBlock = web3.eth.defaultBlock; -console.log(defaultBlock); // 'latest' - -// set the default block -web3.eth.defaultBlock = 231; -``` - -*** - -#### web3.eth.syncing - - web3.eth.syncing - // or async - web3.eth.getSyncing(callback(error, result){ ... }) - -This property is read only and returns the either a sync object, when the node is syncing or `false`. - -##### Returns - -`Object|Boolean` - A sync object as follows, when the node is currently syncing or `false`: - - `startingBlock`: `Number` - The block number where the sync started. - - `currentBlock`: `Number` - The block number where at which block the node currently synced to already. - - `highestBlock`: `Number` - The estimated block number to sync to. - -##### Example - -```js -var sync = web3.eth.syncing; -console.log(sync); -/* -{ - startingBlock: 300, - currentBlock: 312, - highestBlock: 512 -} -*/ -``` - -*** - -#### web3.eth.isSyncing - - web3.eth.isSyncing(callback); - -This convenience function calls the `callback` everytime a sync starts, updates and stops. - -##### Returns - -`Object` - a isSyncing object with the following methods: - - * `syncing.addCallback()`: Adds another callback, which will be called when the node starts or stops syncing. - * `syncing.stopWatching()`: Stops the syncing callbacks. - -##### Callback return value - -- `Boolean` - The callback will be fired with `true` when the syncing starts and with `false` when it stopped. -- `Object` - While syncing it will return the syncing object: - - `startingBlock`: `Number` - The block number where the sync started. - - `currentBlock`: `Number` - The block number where at which block the node currently synced to already. - - `highestBlock`: `Number` - The estimated block number to sync to. - - -##### Example - -```js -web3.eth.isSyncing(function(error, sync){ - if(!error) { - // stop all app activity - if(sync === true) { - // we use `true`, so it stops all filters, but not the web3.eth.syncing polling - web3.reset(true); - - // show sync info - } else if(sync) { - console.log(sync.currentBlock); - - // re-gain app operation - } else { - // run your app init function... - } - } -}); -``` - -*** - -#### web3.eth.coinbase - - web3.eth.coinbase - // or async - web3.eth.getCoinbase(callback(error, result){ ... }) - -This property is read only and returns the coinbase address were the mining rewards go to. - -##### Returns - -`String` - The coinbase address of the client. - -##### Example - -```js -var coinbase = web3.eth.coinbase; -console.log(coinbase); // "0x407d73d8a49eeb85d32cf465507dd71d507100c1" -``` - -*** - -#### web3.eth.mining - - web3.eth.mining - // or async - web3.eth.getMining(callback(error, result){ ... }) - - -This property is read only and says whether the node is mining or not. - - -##### Returns - -`Boolean` - `true` if the client is mining, otherwise `false`. - -##### Example - -```js -var mining = web3.eth.mining; -console.log(mining); // true or false -``` - -*** - -#### web3.eth.hashrate - - web3.eth.hashrate - // or async - web3.eth.getHashrate(callback(error, result){ ... }) - -This property is read only and returns the number of hashes per second that the node is mining with. - - -##### Returns - -`Number` - number of hashes per second. - -##### Example - -```js -var hashrate = web3.eth.hashrate; -console.log(hashrate); // 493736 -``` - -*** - -#### web3.eth.gasPrice - - web3.eth.gasPrice - // or async - web3.eth.getGasPrice(callback(error, result){ ... }) - - -This property is read only and returns the current gas price. -The gas price is determined by the x latest blocks median gas price. - -##### Returns - -`BigNumber` - A BigNumber instance of the current gas price in wei. - -See the [note on BigNumber](#a-note-on-big-numbers-in-javascript). - -##### Example - -```js -var gasPrice = web3.eth.gasPrice; -console.log(gasPrice.toString(10)); // "10000000000000" -``` - -*** - -#### web3.eth.accounts - - web3.eth.accounts - // or async - web3.eth.getAccounts(callback(error, result){ ... }) - -This property is read only and returns a list of accounts the node controls. - -##### Returns - -`Array` - An array of addresses controlled by client. - -##### Example - -```js -var accounts = web3.eth.accounts; -console.log(accounts); // ["0x407d73d8a49eeb85d32cf465507dd71d507100c1"] -``` - -*** - -#### web3.eth.blockNumber - - web3.eth.blockNumber - // or async - web3.eth.getBlockNumber(callback(error, result){ ... }) - -This property is read only and returns the current block number. - -##### Returns - -`Number` - The number of the most recent block. - -##### Example - -```js -var number = web3.eth.blockNumber; -console.log(number); // 2744 -``` - -*** - -#### web3.eth.register - - web3.eth.register(addressHexString [, callback]) - -(Not Implemented yet) -Registers the given address to be included in `web3.eth.accounts`. This allows non-private-key owned accounts to be associated as an owned account (e.g., contract wallets). - -##### Parameters - -1. `String` - The address to register -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -? - - -##### Example - -```js -web3.eth.register("0x407d73d8a49eeb85d32cf465507dd71d507100ca") -``` - -*** - -#### web3.eth.unRegister - - web3.eth.unRegister(addressHexString [, callback]) - - -(Not Implemented yet) -Unregisters a given address. - -##### Parameters - -1. `String` - The address to unregister. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -? - - -##### Example - -```js -web3.eth.unregister("0x407d73d8a49eeb85d32cf465507dd71d507100ca") -``` - -*** - -#### web3.eth.getBalance - - web3.eth.getBalance(addressHexString [, defaultBlock] [, callback]) - -Get the balance of an address at a given block. - -##### Parameters - -1. `String` - The address to get the balance of. -2. `Number|String` - (optional) If you pass this parameter it will not use the default block set with [web3.eth.defaultBlock](#web3ethdefaultblock). -3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - A BigNumber instance of the current balance for the given address in wei. - -See the [note on BigNumber](#a-note-on-big-numbers-in-javascript). - -##### Example - -```js -var balance = web3.eth.getBalance("0x407d73d8a49eeb85d32cf465507dd71d507100c1"); -console.log(balance); // instanceof BigNumber -console.log(balance.toString(10)); // '1000000000000' -console.log(balance.toNumber()); // 1000000000000 -``` - -*** - -#### web3.eth.getStorageAt - - web3.eth.getStorageAt(addressHexString, position [, defaultBlock] [, callback]) - -Get the storage at a specific position of an address. - -##### Parameters - -1. `String` - The address to get the storage from. -2. `Number` - The index position of the storage. -3. `Number|String` - (optional) If you pass this parameter it will not use the default block set with [web3.eth.defaultBlock](#web3ethdefaultblock). -4. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -`String` - The value in storage at the given position. - -##### Example - -```js -var state = web3.eth.getStorageAt("0x407d73d8a49eeb85d32cf465507dd71d507100c1", 0); -console.log(state); // "0x03" -``` - -*** - -#### web3.eth.getCode - - web3.eth.getCode(addressHexString [, defaultBlock] [, callback]) - -Get the code at a specific address. - -##### Parameters - -1. `String` - The address to get the code from. -2. `Number|String` - (optional) If you pass this parameter it will not use the default block set with [web3.eth.defaultBlock](#web3ethdefaultblock). -3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - The data at given address `addressHexString`. - -##### Example - -```js -var code = web3.eth.getCode("0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8"); -console.log(code); // "0x600160008035811a818181146012578301005b601b6001356025565b8060005260206000f25b600060078202905091905056" -``` - -*** - -#### web3.eth.getBlock - - web3.eth.getBlock(blockHashOrBlockNumber [, returnTransactionObjects] [, callback]) - -Returns a block matching the block number or block hash. - -##### Parameters - -1. `String|Number` - The block number or hash. Or the string `"earliest"`, `"latest"` or `"pending"` as in the [default block parameter](#web3ethdefaultblock). -2. `Boolean` - (optional, default `false`) If `true`, the returned block will contain all transactions as objects, if `false` it will only contains the transaction hashes. -3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Object` - The block object: - - - `number`: `Number` - the block number. `null` when its pending block. - - `hash`: `String`, 32 Bytes - hash of the block. `null` when its pending block. - - `parentHash`: `String`, 32 Bytes - hash of the parent block. - - `nonce`: `String`, 8 Bytes - hash of the generated proof-of-work. `null` when its pending block. - - `sha3Uncles`: `String`, 32 Bytes - SHA3 of the uncles data in the block. - - `logsBloom`: `String`, 256 Bytes - the bloom filter for the logs of the block. `null` when its pending block. - - `transactionsRoot`: `String`, 32 Bytes - the root of the transaction trie of the block - - `stateRoot`: `String`, 32 Bytes - the root of the final state trie of the block. - - `miner`: `String`, 20 Bytes - the address of the beneficiary to whom the mining rewards were given. - - `difficulty`: `BigNumber` - integer of the difficulty for this block. - - `totalDifficulty`: `BigNumber` - integer of the total difficulty of the chain until this block. - - `extraData`: `String` - the "extra data" field of this block. - - `size`: `Number` - integer the size of this block in bytes. - - `gasLimit`: `Number` - the maximum gas allowed in this block. - - `gasUsed`: `Number` - the total used gas by all transactions in this block. - - `timestamp`: `Number` - the unix timestamp for when the block was collated. - - `transactions`: `Array` - Array of transaction objects, or 32 Bytes transaction hashes depending on the last given parameter. - - `uncles`: `Array` - Array of uncle hashes. - -##### Example - -```js -var info = web3.eth.block(3150); -console.log(info); -/* -{ - "number": 3, - "hash": "0xef95f2f1ed3ca60b048b4bf67cde2195961e0bba6f70bcbea9a2c4e133e34b46", - "parentHash": "0x2302e1c0b972d00932deb5dab9eb2982f570597d9d42504c05d9c2147eaf9c88", - "nonce": "0xfb6e1a62d119228b", - "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "transactionsRoot": "0x3a1b03875115b79539e5bd33fb00d8f7b7cd61929d5a3c574f507b8acf415bee", - "stateRoot": "0xf1133199d44695dfa8fd1bcfe424d82854b5cebef75bddd7e40ea94cda515bcb", - "miner": "0x8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty": BigNumber, - "totalDifficulty": BigNumber, - "size": 616, - "extraData": "0x", - "gasLimit": 3141592, - "gasUsed": 21662, - "timestamp": 1429287689, - "transactions": [ - "0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b" - ], - "uncles": [] -} -*/ -``` - -*** - -#### web3.eth.getBlockTransactionCount - - web3.eth.getBlockTransactionCount(hashStringOrBlockNumber [, callback]) - -Returns the number of transaction in a given block. - -##### Parameters - -1. `String|Number` - The block number or hash. Or the string `"earliest"`, `"latest"` or `"pending"` as in the [default block parameter](#web3ethdefaultblock). -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Number` - The number of transactions in the given block. - -##### Example - -```js -var number = web3.eth.getBlockTransactionCount("0x407d73d8a49eeb85d32cf465507dd71d507100c1"); -console.log(number); // 1 -``` - -*** - -#### web3.eth.getUncle - - web3.eth.getUncle(blockHashStringOrNumber, uncleNumber [, returnTransactionObjects] [, callback]) - -Returns a blocks uncle by a given uncle index position. - -##### Parameters - -1. `String|Number` - The block number or hash. Or the string `"earliest"`, `"latest"` or `"pending"` as in the [default block parameter](#web3ethdefaultblock). -2. `Number` - The index position of the uncle. -3. `Boolean` - (optional, default `false`) If `true`, the returned block will contain all transactions as objects, if `false` it will only contains the transaction hashes. -4. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -`Object` - the returned uncle. For a return value see [web3.eth.getBlock()](#web3ethgetblock). - -**Note**: An uncle doesn't contain individual transactions. - -##### Example - -```js -var uncle = web3.eth.getUncle(500, 0); -console.log(uncle); // see web3.eth.getBlock - -``` - -*** - -##### web3.eth.getTransaction - - web3.eth.getTransaction(transactionHash [, callback]) - -Returns a transaction matching the given transaction hash. - -##### Parameters - -1. `String` - The transaction hash. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -`Object` - A transaction object its hash `transactionHash`: - - - `hash`: `String`, 32 Bytes - hash of the transaction. - - `nonce`: `Number` - the number of transactions made by the sender prior to this one. - - `blockHash`: `String`, 32 Bytes - hash of the block where this transaction was in. `null` when its pending. - - `blockNumber`: `Number` - block number where this transaction was in. `null` when its pending. - - `transactionIndex`: `Number` - integer of the transactions index position in the block. `null` when its pending. - - `from`: `String`, 20 Bytes - address of the sender. - - `to`: `String`, 20 Bytes - address of the receiver. `null` when its a contract creation transaction. - - `value`: `BigNumber` - value transferred in Wei. - - `gasPrice`: `BigNumber` - gas price provided by the sender in Wei. - - `gas`: `Number` - gas provided by the sender. - - `input`: `String` - the data sent along with the transaction. - - -##### Example - -```js -var blockNumber = 668; -var indexOfTransaction = 0 - -var transaction = web3.eth.getTransaction(blockNumber, indexOfTransaction); -console.log(transaction); -/* -{ - "hash": "0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b", - "nonce": 2, - "blockHash": "0xef95f2f1ed3ca60b048b4bf67cde2195961e0bba6f70bcbea9a2c4e133e34b46", - "blockNumber": 3, - "transactionIndex": 0, - "from": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "to": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f", - "value": BigNumber, - "gas": 314159, - "gasPrice": BigNumber, - "input": "0x57cb2fc4" -} -*/ - -``` - -*** - -#### web3.eth.getTransactionFromBlock - - getTransactionFromBlock(hashStringOrNumber, indexNumber [, callback]) - -Returns a transaction based on a block hash or number and the transactions index position. - -##### Parameters - -1. `String` - A block number or hash. Or the string `"earliest"`, `"latest"` or `"pending"` as in the [default block parameter](#web3ethdefaultblock). -2. `Number` - The transactions index position. -3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Object` - A transaction object, see [web3.eth.getTransaction](#web3ethgettransaction): - - -##### Example - -```js -var transaction = web3.eth.getTransactionFromBlock('0x4534534534', 2); -console.log(transaction); // see web3.eth.getTransaction - -``` - -*** - -#### web3.eth.getTransactionReceipt - - web3.eth.getTransactionReceipt(hashString [, callback]) - -Returns the receipt of a transaction by transaction hash. - -**Note** That the receipt is not available for pending transactions. - - -##### Parameters - -1. `String` - The transaction hash. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Object` - A transaction receipt object, or `null` when no receipt was found: - - - `blockHash`: `String`, 32 Bytes - hash of the block where this transaction was in. - - `blockNumber`: `Number` - block number where this transaction was in. - - `transactionHash`: `String`, 32 Bytes - hash of the transaction. - - `transactionIndex`: `Number` - integer of the transactions index position in the block. - - `from`: `String`, 20 Bytes - address of the sender. - - `to`: `String`, 20 Bytes - address of the receiver. `null` when its a contract creation transaction. - - `cumulativeGasUsed `: `Number ` - The total amount of gas used when this transaction was executed in the block. - - `gasUsed `: `Number ` - The amount of gas used by this specific transaction alone. - - `contractAddress `: `String` - 20 Bytes - The contract address created, if the transaction was a contract creation, otherwise `null`. - - `logs `: `Array` - Array of log objects, which this transaction generated. - -##### Example -```js -var receipt = web3.eth.getTransactionReceipt('0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b'); -console.log(receipt); -{ - "transactionHash": "0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b", - "transactionIndex": 0, - "blockHash": "0xef95f2f1ed3ca60b048b4bf67cde2195961e0bba6f70bcbea9a2c4e133e34b46", - "blockNumber": 3, - "contractAddress": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "cumulativeGasUsed": 314159, - "gasUsed": 30234, - "logs": [{ - // logs as returned by getFilterLogs, etc. - }, ...] -} -``` - -*** - -#### web3.eth.getTransactionCount - - web3.eth.getTransactionCount(addressHexString [, defaultBlock] [, callback]) - -Get the numbers of transactions sent from this address. - -##### Parameters - -1. `String` - The address to get the numbers of transactions from. -2. `Number|String` - (optional) If you pass this parameter it will not use the default block set with [web3.eth.defaultBlock](#web3ethdefaultblock). -3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Number` - The number of transactions sent from the given address. - -##### Example - -```js -var number = web3.eth.getTransactionCount("0x407d73d8a49eeb85d32cf465507dd71d507100c1"); -console.log(number); // 1 -``` - -*** - -#### web3.eth.sendTransaction - - web3.eth.sendTransaction(transactionObject [, callback]) - -Sends a transaction to the network. - -##### Parameters - -1. `Object` - The transaction object to send: - - `from`: `String` - The address for the sending account. Uses the [web3.eth.defaultAccount](#web3ethdefaultaccount) property, if not specified. - - `to`: `String` - (optional) The destination address of the message, left undefined for a contract-creation transaction. - - `value`: `Number|String|BigNumber` - (optional) The value transferred for the transaction in Wei, also the endowment if it's a contract-creation transaction. - - `gas`: `Number|String|BigNumber` - (optional, default: To-Be-Determined) The amount of gas to use for the transaction (unused gas is refunded). - - `gasPrice`: `Number|String|BigNumber` - (optional, default: To-Be-Determined) The price of gas for this transaction in wei, defaults to the mean network gas price. - - `data`: `String` - (optional) Either a [byte string](https://github.com/ethereum/wiki/wiki/Solidity,-Docs-and-ABI) containing the associated data of the message, or in the case of a contract-creation transaction, the initialisation code. - - `nonce`: `Number` - (optional) Integer of a nonce. This allows to overwrite your own pending transactions that use the same nonce. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - The 32 Bytes transaction hash as HEX string. - -If the transaction was a contract creation use [web3.eth.getTransactionReceipt()](#web3gettransactionreceipt) to get the contract address, after the transaction was mined. - -##### Example - -```js - -// compiled solidity source code using https://chriseth.github.io/cpp-ethereum/ -var code = "603d80600c6000396000f3007c01000000000000000000000000000000000000000000000000000000006000350463c6888fa18114602d57005b600760043502 -8060005260206000f3"; - -web3.eth.sendTransaction({data: code}, function(err, address) { - if (!err) - console.log(address); // "0x7f9fade1c0d57a7af66ab4ead7c2eb7b11a91385" -}); -``` - -*** - -#### web3.eth.call - - web3.eth.call(callObject [, defaultBlock] [, callback]) - -Executes a message call transaction, which is directly executed in the VM of the node, but never mined into the blockchain. - -##### Parameters - -1. `Object` - A transaction object see [web3.eth.sendTransaction](#web3ethsendtransaction), with the difference that for calls the `from` property is optional as well. -2. `Number|String` - (optional) If you pass this parameter it will not use the default block set with [web3.eth.defaultBlock](#web3ethdefaultblock). -3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - The returned data of the call, e.g. a codes functions return value. - -##### Example - -```js -var result = web3.eth.call({ - to: "0xc4abd0339eb8d57087278718986382264244252f", - data: "0xc6888fa10000000000000000000000000000000000000000000000000000000000000003" -}); -console.log(result); // "0x0000000000000000000000000000000000000000000000000000000000000015" -``` - -*** - -#### web3.eth.estimateGas - - web3.eth.estimateGas(callObject [, defaultBlock] [, callback]) - -Executes a message call or transaction, which is directly executed in the VM of the node, but never mined into the blockchain and returns the amount of the gas used. - -##### Parameters - -See [web3.eth.sendTransaction](#web3ethsendtransaction), expect that all properties are optional. - -##### Returns - -`Number` - the used gas for the simulated call/transaction. - -##### Example - -```js -var result = web3.eth.estimateGas({ - to: "0xc4abd0339eb8d57087278718986382264244252f", - data: "0xc6888fa10000000000000000000000000000000000000000000000000000000000000003" -}); -console.log(result); // "0x0000000000000000000000000000000000000000000000000000000000000015" -``` - -*** - -#### web3.eth.filter - -```js -// can be 'latest' or 'pending' -var filter = web3.eth.filter(filterString); -// OR object are log filter options -var filter = web3.eth.filter(options); - -// watch for changes -filter.watch(function(error, result){ - if (!error) - console.log(result); -}); - -// Additionally you can start watching right away, by passing a callback: -web3.eth.filter(options, function(error, result){ - if (!error) - console.log(result); -}); -``` - -##### Parameters - -1. `String|Object` - The string `"latest"` or `"pending"` to watch for changes in the latest block or pending transactions respectively. Or a filter options object as follows: - * `fromBlock`: `Number|String` - The number of the earliest block (`latest` may be given to mean the most recent and `pending` currently mining, block). By default `latest`. - * `toBlock`: `Number|String` - The number of the latest block (`latest` may be given to mean the most recent and `pending` currently mining, block). By default `latest`. - * `address`: `String` - An address or a list of addresses to only get logs from particular account(s). - * `topics`: `Array of Strings` - An array of values which must each appear in the log entries. The order is important, if you want to leave topics out use `null`, e.g. `[null, '0x00...']`. You can also pass another array for each topic with options for that topic e.g. `[null, ['option1', 'option2']]` - -##### Returns - -`Object` - A filter object with the following methods: - - * `filter.get(callback)`: Returns all of the log entries that fit the filter. - * `filter.watch(callback)`: Watches for state changes that fit the filter and calls the callback. See [this note](#using-callbacks) for details. - * `filter.stopWatching()`: Stops the watch and uninstalls the filter in the node. Should always be called once it is done. - -##### Watch callback return value - -- `String` - When using the `"latest"` parameter, it returns the block hash of the last incoming block. -- `String` - When using the `"pending"` parameter, it returns a transaction hash of the last add pending transaction. -- `Object` - When using manual filter options, it returns a log object as follows: - - `logIndex`: `Number` - integer of the log index position in the block. `null` when its pending log. - - `transactionIndex`: `Number` - integer of the transactions index position log was created from. `null` when its pending log. - - `transactionHash`: `String`, 32 Bytes - hash of the transactions this log was created from. `null` when its pending log. - - `blockHash`: `String`, 32 Bytes - hash of the block where this log was in. `null` when its pending. `null` when its pending log. - - `blockNumber`: `Number` - the block number where this log was in. `null` when its pending. `null` when its pending log. - - `address`: `String`, 32 Bytes - address from which this log originated. - - `data`: `String` - contains one or more 32 Bytes non-indexed arguments of the log. - - `topics`: `Array of Strings` - Array of 0 to 4 32 Bytes `DATA` of indexed log arguments. (In *solidity*: The first topic is the *hash* of the signature of the event (e.g. `Deposit(address,bytes32,uint256)`), except you declared the event with the `anonymous` specifier.) - -**Note** For event filter return values see [Contract Events](#contract-events) - -##### Example - -```js -var filter = web3.eth.filter('pending'); - -filter.watch(function (error, log) { - console.log(log); // {"address":"0x0000000000000000000000000000000000000000", "data":"0x0000000000000000000000000000000000000000000000000000000000000000", ...} -}); - -// get all past logs again. -var myResults = filter.get(function(error, logs){ ... }); - -... - -// stops and uninstalls the filter -filter.stopWatching(); - -``` - -*** - -#### web3.eth.contract - - web3.eth.contract(abiArray) - -Creates a contract object for a solidity contract, which can be used to initiate contracts on an address. -You can read more about events [here](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI#example-javascript-usage). - -##### Parameters - -1. `Array` - ABI array with descriptions of functions and events of the contract. - -##### Returns - -`Object` - A contract object, which can be initiated as follows: - -```js -var MyContract = web3.eth.contract(abiArray); - -// instantiate by address -var contractInstance = MyContract.at([address]); - -// deploy new contract -var contractInstance = MyContract.new([contructorParam1] [, contructorParam2], {data: '0x12345...', from: myAccount, gas: 1000000}); - -// Get the data to deploy the contract manually -var contractData = MyContract.new.getData([contructorParam1] [, contructorParam2], {data: '0x12345...'}); -// contractData = '0x12345643213456000000000023434234' -``` - -And then you can either initiate an existing contract on an address, -or deploy the contract using the compiled byte code: - -```js -// Instantiate from an existing address: -var myContractInstance = MyContract.at(myContractAddress); - - -// Or deploy a new contract: - -// Deploy the contract asyncronous: -var myContractReturned = MyContract.new(param1, param2, { - data: myContractCode, - gas: 300000, - from: mySenderAddress}, function(err, myContract){ - if(!err) { - // NOTE: The callback will fire twice! - // Once the contract has the transactionHash property set and once its deployed on an address. - - // e.g. check tx hash on the first call (transaction send) - if(!myContract.address) { - console.log(myContract.transactionHash) // The hash of the transaction, which deploys the contract - - // check address on the second call (contract deployed) - } else { - console.log(myContract.address) // the contract address - } - - // Note that the returned "myContractReturned" === "myContract", - // so the returned "myContractReturned" object will also get the address set. - } - }); - -// Deploy contract syncronous: The address will be added as soon as the contract is mined. -// Additionally you can watch the transaction by using the "transactionHash" property -var myContractInstance = MyContract.new(param1, param2, {data: myContractCode, gas: 300000, from: mySenderAddress}); -myContractInstance.transactionHash // The hash of the transaction, which created the contract -myContractInstance.address // undefined at start, but will be auto-filled later -``` - -**Note** When you deploy a new contract, you should check for the next 12 blocks or so if the contract code is still at the address (using [web3.eth.getCode()](#web3ethgetcode)), to make sure a fork didn't change that. - -##### Example - -```js -// contract abi -var abi = [{ - name: 'myConstantMethod', - type: 'function', - constant: true, - inputs: [{ name: 'a', type: 'string' }], - outputs: [{name: 'd', type: 'string' }] -}, { - name: 'myStateChangingMethod', - type: 'function', - constant: false, - inputs: [{ name: 'a', type: 'string' }, { name: 'b', type: 'int' }], - outputs: [] -}, { - name: 'myEvent', - type: 'event', - inputs: [{name: 'a', type: 'int', indexed: true},{name: 'b', type: 'bool', indexed: false] -}]; - -// creation of contract object -var MyContract = web3.eth.contract(abi); - -// initiate contract for an address -var myContractInstance = MyContract.at('0xc4abd0339eb8d57087278718986382264244252f'); - -// call constant function -var result = myContractInstance.myConstantMethod('myParam'); -console.log(result) // '0x25434534534' - -// send a transaction to a function -myContractInstance.myStateChangingMethod('someParam1', 23, {value: 200, gas: 2000}); - -// short hand style -web3.eth.contract(abi).at(address).myAwesomeMethod(...); - -// create filter -var filter = myContractInstance.myEvent({a: 5}, function (error, result) { - if (!error) - console.log(result); - /* - { - address: '0x8718986382264244252fc4abd0339eb8d5708727', - topics: "0x12345678901234567890123456789012", "0x0000000000000000000000000000000000000000000000000000000000000005", - data: "0x0000000000000000000000000000000000000000000000000000000000000001", - ... - } - */ -}); -``` - -*** - -#### Contract Methods - -```js -// Automatically determines the use of call or sendTransaction based on the method type -myContractInstance.myMethod(param1 [, param2, ...] [, transactionObject] [, callback]); - -// Explicitly calling this method -myContractInstance.myMethod.call(param1 [, param2, ...] [, transactionObject] [, callback]); - -// Explicitly sending a transaction to this method -myContractInstance.myMethod.sendTransaction(param1 [, param2, ...] [, transactionObject] [, callback]); - -// Explicitly sending a transaction to this method -myContractInstance.myMethod.sendTransaction(param1 [, param2, ...] [, transactionObject] [, callback]); - -// Get the call data, so you can call the contract through some other means -var myCallData = myContractInstance.myMethod.getData(param1 [, param2, ...]); -// myCallData = '0x45ff3ff6000000000004545345345345..' -``` - -The contract object exposes the contracts methods, which can be called using parameters and a transaction object. - -##### Parameters - -- `String|Number` - (optional) Zero or more parameters of the function. -- `Object` - (optional) The (previous) last parameter can be a transaction object, see [web3.eth.sendTransaction](#web3ethsendtransaction) parameter 1 for more. -- `Function` - (optional) If you pass a callback as the last parameter the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - If its a call the result data, if its a send transaction a created contract address, or the transaction hash, see [web3.eth.sendTransaction](#web3ethsendtransaction) for details. - - -##### Example - -```js -// creation of contract object -var MyContract = web3.eth.contract(abi); - -// initiate contract for an address -var myContractInstance = MyContract.at('0x78e97bcc5b5dd9ed228fed7a4887c0d7287344a9'); - -var result = myContractInstance.myConstantMethod('myParam'); -console.log(result) // '0x25434534534' - -myContractInstance.myStateChangingMethod('someParam1', 23, {value: 200, gas: 2000}, function(err, result){ ... }); -``` - -*** - - -#### Contract Events - -```js -var event = myContractInstance.MyEvent({valueA: 23} [, additionalFilterObject]) - -// watch for changes -event.watch(function(error, result){ - if (!error) - console.log(result); -}); - -// Or pass a callback to start watching immediately -var event = myContractInstance.MyEvent([{valueA: 23}] [, additionalFilterObject] , function(error, result){ - if (!error) - console.log(result); -}); - -``` - -You can use events like [filters](#web3ethfilter) and they have the same methods, but you pass different objects to create the event filter. - -##### Parameters - -1. `Object` - Indexed return values you want to filter the logs by, e.g. `{'valueA': 1, 'valueB': [myFirstAddress, mySecondAddress]}`. By default all filter values are set to `null`. It means, that they will match any event of given type sent from this contract. -2. `Object` - Additional filter options, see [filters](#web3ethfilter) parameter 1 for more. By default filterObject has field 'address' set to address of the contract. Also first topic is the signature of event. -3. `Function` - (optional) If you pass a callback as the last parameter it will immediately start watching and you don't need to call `myEvent.watch(function(){})`. See [this note](#using-callbacks) for details. - -##### Callback return - - -`Object` - An event object as follows: - -- `args`: `Object` - The arguments coming from the event. -- `event`: `String` - The event name. -- `logIndex`: `Number` - integer of the log index position in the block. -- `transactionIndex`: `Number` - integer of the transactions index position log was created from. -- `transactionHash`: `String`, 32 Bytes - hash of the transactions this log was created from. -- `address`: `String`, 32 Bytes - address from which this log originated. -- `blockHash`: `String`, 32 Bytes - hash of the block where this log was in. `null` when its pending. -- `blockNumber`: `Number` - the block number where this log was in. `null` when its pending. - - -##### Example - -```js -var MyContract = web3.eth.contract(abi); -var myContractInstance = MyContract.at('0x78e97bcc5b5dd9ed228fed7a4887c0d7287344a9'); - -// watch for an event with {some: 'args'} -var myEvent = myContractInstance.MyEvent({some: 'args'}, {fromBlock: 0, toBlock: 'latest'}); -myEvent.watch(function(error, result){ - ... -}); - -// would get all past logs again. -var myResults = myEvent.get(function(error, logs){ ... }); - -... - -// would stop and uninstall the filter -myEvent.stopWatching(); -``` - -*** - -#### Contract allEvents - -```js -var events = myContractInstance.allEvents([additionalFilterObject]); - -// watch for changes -events.watch(function(error, event){ - if (!error) - console.log(event); -}); - -// Or pass a callback to start watching immediately -var events = myContractInstance.allEvents([additionalFilterObject,] function(error, log){ - if (!error) - console.log(log); -}); - -``` - -Will call the callback for all events which are created by this contract. - -##### Parameters - -1. `Object` - Additional filter options, see [filters](#web3ethfilter) parameter 1 for more. By default filterObject has field 'address' set to address of the contract. Also first topic is the signature of event. -2. `Function` - (optional) If you pass a callback as the last parameter it will immediately start watching and you don't need to call `myEvent.watch(function(){})`. See [this note](#using-callbacks) for details. - -##### Callback return - - -`Object` - See [Contract Events](#contract-events) for more. - -##### Example - -```js -var MyContract = web3.eth.contract(abi); -var myContractInstance = MyContract.at('0x78e97bcc5b5dd9ed228fed7a4887c0d7287344a9'); - -// watch for an event with {some: 'args'} -var events = myContractInstance.allEvents({fromBlock: 0, toBlock: 'latest'}); -events.watch(function(error, result){ - ... -}); - -// would get all past logs again. -events.get(function(error, logs){ ... }); - -... - -// would stop and uninstall the filter -myEvent.stopWatching(); -``` - -**** - -#### web3.eth.getCompilers - - web3.eth.getCompilers([callback]) - -Gets a list of available compilers. - -##### Parameters - -1. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Array` - An array of strings of available compilers. - -##### Example - -```js -var number = web3.eth.getCompilers(); -console.log(number); // ["lll", "solidity", "serpent"] -``` - -*** - -#### web3.eth.compile.solidity - - web3.eth.compile.solidity(sourceString [, callback]) - -Compiles solidity source code. - -##### Parameters - -1. `String` - The solidity source code. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Object` - Contract and compiler info. - - -##### Example - -```js -var source = "" + - "contract test {\n" + - " function multiply(uint a) returns(uint d) {\n" + - " return a * 7;\n" + - " }\n" + - "}\n"; -var compiled = web3.eth.compile.solidity(source); -console.log(compiled); -// { - "test": { - "code": "0x605280600c6000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa114602e57005b60376004356041565b8060005260206000f35b6000600782029050604d565b91905056", - "info": { - "source": "contract test {\n\tfunction multiply(uint a) returns(uint d) {\n\t\treturn a * 7;\n\t}\n}\n", - "language": "Solidity", - "languageVersion": "0", - "compilerVersion": "0.8.2", - "abiDefinition": [ - { - "constant": false, - "inputs": [ - { - "name": "a", - "type": "uint256" - } - ], - "name": "multiply", - "outputs": [ - { - "name": "d", - "type": "uint256" - } - ], - "type": "function" - } - ], - "userDoc": { - "methods": {} - }, - "developerDoc": { - "methods": {} - } - } - } -} -``` - -*** - -#### web3.eth.compile.lll - - web3. eth.compile.lll(sourceString [, callback]) - -Compiles LLL source code. - -##### Parameters - -1. `String` - The LLL source code. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - The compiled LLL code as HEX string. - - -##### Example - -```js -var source = "..."; - -var code = web3.eth.compile.lll(source); -console.log(code); // "0x603880600c6000396000f3006001600060e060020a600035048063c6888fa114601857005b6021600435602b565b8060005260206000f35b600081600702905091905056" -``` - -*** - -#### web3.eth.compile.serpent - - web3.eth.compile.serpent(sourceString [, callback]) - -Compiles serpent source code. - -##### Parameters - -1. `String` - The serpent source code. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - The compiled serpent code as HEX string. - - -```js -var source = "..."; - -var code = web3.eth.compile.serpent(source); -console.log(code); // "0x603880600c6000396000f3006001600060e060020a600035048063c6888fa114601857005b6021600435602b565b8060005260206000f35b600081600702905091905056" -``` - -*** - -#### web3.eth.namereg - - web3.eth.namereg - -Returns GlobalRegistrar object. - -##### Usage - -see [namereg](https://github.com/ethereum/web3.js/blob/master/example/namereg.html) example - -*** - -### web3.db - -#### web3.db.putString - - web3.db.putString(db, key, value) - -This method should be called, when we want to store a string in the local leveldb database. - -##### Parameters - -1. `String` - The database to store to. -2. `String` - The name of the store. -3. `String` - The string value to store. - -##### Returns - -`Boolean` - `true` if successfull, otherwise `false`. - -##### Example - - param is db name, second is the key, and third is the string value. -```js -web3.db.putString('testDB', 'key', 'myString') // true -``` - -*** - -#### web3.db.getString - - web3.db.getString(db, key) - -This method should be called, when we want to get string from the local leveldb database. - -##### Parameters - -1. `String` - The database string name to retrieve from. -2. `String` - The name of the store. - -##### Returns - -`String` - The stored value. - -##### Example - param is db name and second is the key of string value. -```js -var value = web3.db.getString('testDB', 'key'); -console.log(value); // "myString" -``` - -*** - -#### web3.db.putHex - - web3.db.putHex(db, key, value) - -This method should be called, when we want to store binary data in HEX form in the local leveldb database. - -##### Parameters - -1. `String` - The database to store to. -2. `String` - The name of the store. -3. `String` - The HEX string to store. - -##### Returns - -`Boolean` - `true` if successfull, otherwise `false`. - -##### Example -```js -web3.db.putHex('testDB', 'key', '0x4f554b443'); // true - -``` - -*** - -#### web3.db.getHex - - web3.db.getHex(db, key) - -This method should be called, when we want to get a binary data in HEX form from the local leveldb database. - -##### Parameters - -1. `String` - The database to store to. -2. `String` - The name of the store. - -##### Returns - -`String` - The stored HEX value. - - -##### Example - param is db name and second is the key of value. -```js -var value = web3.db.getHex('testDB', 'key'); -console.log(value); // "0x4f554b443" -``` - -*** - -### web3.shh - -[Whisper Overview](https://github.com/ethereum/wiki/wiki/Whisper-Overview) - -##### Example - -```js -var shh = web3.shh; -``` - -*** - -#### web3.shh.post - - web3.shh.post(object [, callback]) - -This method should be called, when we want to post whisper message to the network. - -##### Parameters - -1. `Object` - The post object: - - `from`: `String`, 60 Bytes HEX - (optional) The identity of the sender. - - `to`: `String`, 60 Bytes HEX - (optional) The identity of the receiver. When present whisper will encrypt the message so that only the receiver can decrypt it. - - `topics`: `Array of Strings` - Array of topics `Strings`, for the receiver to identify messages. - - `payload`: `String|Number|Object` - The payload of the message. Will be autoconverted to a HEX string before. - - `priority`: `Number` - The integer of the priority in a rang from ... (?). - - `ttl`: `Number` - integer of the time to live in seconds. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Boolean` - returns `true` if the message was send, otherwise `false`. - - -##### Example - -```js -var identity = web3.shh.newIdentity(); -var topic = 'example'; -var payload = 'hello whisper world!'; - -var message = { - from: identity, - topics: [topic], - payload: payload, - ttl: 100, - workToProve: 100 // or priority TODO -}; - -web3.shh.post(message); -``` - -*** - -#### web3.shh.newIdentity - - web3.shh.newIdentity([callback]) - -Should be called to create new identity. - -##### Parameters - -1. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -`String` - A new identity HEX string. - - -##### Example - -```js -var identity = web3.shh.newIdentity(); -console.log(identity); // "0xc931d93e97ab07fe42d923478ba2465f283f440fd6cabea4dd7a2c807108f651b7135d1d6ca9007d5b68aa497e4619ac10aa3b27726e1863c1fd9b570d99bbaf" -``` - -*** - -#### web3.shh.hasIdentity - - web3.shh.hasIdentity(identity, [callback]) - -Should be called, if we want to check if user has given identity. - -##### Parameters - -1. `String` - The identity to check. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Boolean` - returns `true` if the identity exists, otherwise `false`. - - -##### Example - -```js -var identity = web3.shh.newIdentity(); -var result = web3.shh.hasIdentity(identity); -console.log(result); // true - -var result2 = web3.shh.hasIdentity(identity + "0"); -console.log(result2); // false -``` - -*** - -#### web3.shh.newGroup - -##### Example -```js -// TODO: not implemented yet -``` - -*** - -#### web3.shh.addToGroup - -##### Example -```js -// TODO: not implemented yet -``` - -*** - -#### web3.shh.filter - -```js -var filter = web3.shh.filter(options) - -// watch for changes -filter.watch(function(error, result){ - if (!error) - console.log(result); -}); -``` - -Watch for incoming whisper messages. - -##### Parameters - -1. `Object` - The filter options: - * `topics`: `Array of Strings` - Filters messages by this topic(s). You can use the following combinations: - - `['topic1', 'topic2'] == 'topic1' && 'topic2'` - - `['topic1', ['topic2', 'topic3']] == 'topic1' && ('topic2' || 'topic3')` - - `[null, 'topic1', 'topic2'] == ANYTHING && 'topic1' && 'topic2'` -> `null` works as a wildcard - * `to`: Filter by identity of receiver of the message. If provided and the node has this identity, it will decrypt incoming encrypted messages. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Callback return - -`Object` - The incoming message: - - - `from`: `String`, 60 Bytes - The sender of the message, if a sender was specified. - - `to`: `String`, 60 Bytes - The receiver of the message, if a receiver was specified. - - `expiry`: `Number` - Integer of the time in seconds when this message should expire (?). - - `ttl`: `Number` - Integer of the time the message should float in the system in seconds (?). - - `sent`: `Number` - Integer of the unix timestamp when the message was sent. - - `topics`: `Array of String` - Array of `String` topics the message contained. - - `payload`: `String` - The payload of the message. - - `workProved`: `Number` - Integer of the work this message required before it was send (?). - -*** - -#### web3.eth.sendIBANTransaction - -```js -var txHash = web3.eth.sendIBANTransaction('0x00c5496aee77c1ba1f0854206a26dda82a81d6d8', 'XE81ETHXREGGAVOFYORK', 0x100); -``` - -Sends IBAN transaction from user account to destination IBAN address. - -##### Parameters - -- `string` - address from which we want to send transaction -- `string` - IBAN address to which we want to send transaction -- `value` - value that we want to send in IBAN transaction - -*** - -#### web3.eth.iban - -```js -var i = new web3.eth.iban("XE81ETHXREGGAVOFYORK"); -``` - -*** - -#### web3.eth.iban.fromAddress - -```js -var i = web3.eth.iban.fromAddress('0x00c5496aee77c1ba1f0854206a26dda82a81d6d8'); -console.log(i.toString()); // 'XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS -``` - -*** - -#### web3.eth.iban.fromBban - -```js -var i = web3.eth.iban.fromBban('ETHXREGGAVOFYORK'); -console.log(i.toString()); // "XE81ETHXREGGAVOFYORK" -``` - -*** - -#### web3.eth.iban.createIndirect - -```js -var i = web3.eth.iban.createIndirect({ - institution: "XREG", - identifier: "GAVOFYORK" -}); -console.log(i.toString()); // "XE81ETHXREGGAVOFYORK" -``` - -*** - -#### web3.eth.iban.isValid - -```js -var valid = web3.eth.iban.isValid("XE81ETHXREGGAVOFYORK"); -console.log(valid); // true - -var valid2 = web3.eth.iban.isValid("XE82ETHXREGGAVOFYORK"); -console.log(valid2); // false, cause checksum is incorrect - -var i = new web3.eth.iban("XE81ETHXREGGAVOFYORK"); -var valid3 = i.isValid(); -console.log(valid3); // true - -``` - -*** - -#### web3.eth.iban.isDirect - -```js -var i = new web3.eth.iban("XE81ETHXREGGAVOFYORK"); -var direct = i.isDirect(); -console.log(direct); // false -``` - -*** - -#### web3.eth.iban.isIndirect - -```js -var i = new web3.eth.iban("XE81ETHXREGGAVOFYORK"); -var indirect = i.isIndirect(); -console.log(indirect); // true -``` - -*** - -#### web3.eth.iban.checksum - -```js -var i = new web3.eth.iban("XE81ETHXREGGAVOFYORK"); -var checksum = i.checksum(); -console.log(checksum); // "81" -``` - -*** - -#### web3.eth.iban.institution - -```js -var i = new web3.eth.iban("XE81ETHXREGGAVOFYORK"); -var institution = i.institution(); -console.log(institution); // 'XREG' -``` - -*** - -#### web3.eth.iban.client - -```js -var i = new web3.eth.iban("XE81ETHXREGGAVOFYORK"); -var client = i.client(); -console.log(client); // 'GAVOFYORK' -``` - -*** - -#### web3.eth.iban.address - -```js -var i = new web3.eth.iban('XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS'); -var address = i.address(); -console.log(address); // '00c5496aee77c1ba1f0854206a26dda82a81d6d8' -``` - -*** - -#### web3.eth.iban.toString - -```js -var i = new web3.eth.iban('XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS'); -console.log(i.toString()); // 'XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS' -``` diff --git a/Javascript-Development-Deficiencies.md b/Javascript-Development-Deficiencies.md deleted file mode 100644 index 0bc7d934c..000000000 --- a/Javascript-Development-Deficiencies.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Javascript Development Deficiencies -category: ---- - -The medium-term vision for the Ethereum javascript development tools is simple: to make developing a dapp as easy as developing a web page. However, we are not quite there yet; this page provides a partial list of the problems that dapp developers have to deal with that web developers do not. - -### Transaction Asynchrony and Uncertainty - -When sending an ajax request to a server, that request (i) processes immediately, (ii) is either answered by the server or fails immediately, and (iii) has an effect that we know is final. When sending a transaction, we lose many of these benefits: - -1. When you send a transaction, it takes ~0-30 seconds for the transaction to get included in a block. -2. When a transaction does get included in a block, it could get un-included later due to blockchain reorgs, and could then get double-spent. -3. The transaction gas a gas limit and a gas price, and either of these could lead to failures: in the first case an OOG exception, and in the second case a failure to get the transaction to get included for even longer (possibly forever). It is not possible to tell for sure when this has happened. - -We also lack good ways of dealing with the output of non-constant transactions; for example, a common workflow is creating a transaction that registers a new record in a contract and then getting back the ID of that record or a success or failure confirmation, and there currently is no convenient coding pattern for getting that output back. - -### Failure and retrying - -If a transaction fails for some reason (eg. gas price too low, out of gas), it may be prudent to automatically retry with a higher gas price or gas limit. \ No newline at end of file diff --git a/Kademlia-Peer-Selection.md b/Kademlia-Peer-Selection.md deleted file mode 100644 index ee4187f20..000000000 --- a/Kademlia-Peer-Selection.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -name: Cademlia Peer Selection -category: ---- - -# Peer addresses - -Nodes in the P2P network are identified by 256-bit cryptographic hashes of the nodes' public keys. - -The distance between two addresses is the MSB first numerical value of their XOR. - -# Peer table format - -The peer table consists of rows, initially only one, at most 255 (typically much less). Each row contains at most _k_ peers (data structures containing information about said peer such as their peer address, network address, a timestamp, signature by the peer and possibly various other meta-data), where _k_ is a parameter (not necessarily global) with typical values betwen 5 and 20. - -This parameter, _k_, determines the redundancy of the network: the peer selection algorithm described in this page aims to maintain exactly _k_ peers in each row. If several different protocols requiring routing are used on the network, each protocol _p_ can specify its own redundancy requirement _k__p_, in which case the corresponding _k__p_ number of peers supporting that protocol are maintained. Participants must specify what protocols they support. - -Row numbering starts with 0. Each row number _i_ contains peers whose address matches the first _i_ bits of this node's address. The _i_+1st bit of the address must differ from this nodes address in all rows except the last one. - -As a matter of implementation, it might be worth internally representing all 255 rows from the outset (requiring that the _i_+1st bit be different from our node in all rows); but then considering all of the rows at the end as if they were one row. That is, we look at non empty rows at the end and treat the elements in them as if they belonged to row _i_ where _i_ is the lowest index such that the total number of all elements in row _i_ and in all higher rows, together is at most _k_. - -Note: there is a difference here to the original Kedemlia paper http://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf The rows with a high _i_ for us here are the rows with a low _i_ in the paper. For us, high _i_ means high number of bits agreeing, for them high _i_ mean high xor distance. - -# Adding a new peer - -A peer is added to the row to which it belongs according to the length of address prefix in common with this node. If that would increase the length of the row in question beyond _k_, the **worst** peer (according to some, not necessarily global, peer quality metric) is dropped from the row, except if it is the last row, in which case a new row _i_ + 1 is added and the elements in the old last row are split between the two rows according to the bit at the corresponding position. Note: If we followed the implementation suggestion in the previous section, then we do not need to make an exception for the last row, nor do we have to worry about splitting the last row on the implementation level. - -One sufficient condition for adding a peer is a signed "_add_me_" message containing the sender's peer address and network address, the addressee's peer address and a recent timestamp. - -# Lookup - -A lookup request contains a peer address (which might or might not be valid, it does not matter). The response is the peer list from the full row corresponding to the requested address (information about at most _k_ peers, or _k__p_ peers for the protocol _p_ in use). - -For brevity, it might be worth treating _add_me_ requests for nodes that are not already in the peer table as self-lookups and respond accordingly. - -The new peers are added to the peer table after which the ones in the row corresponding to the address being searched are sent the lookup request recursively, until no peers are returned that are closer to the searched address. - -# Joining the network - -Requires only one bootstrap peer, to which the new node sends an _add_me_ message and subsequently adds every node from the response to its own peer table. - -Thereafter, it performs a lookup of a synthetic random address from the address range corresponding to rows with indices that are smaller than the row in which the bootstrap node ended up. - -# Backwards compatibility mode and DoS safety - -Nodes can still safely dump their full peer table and accept connections from naive nodes. Overwriting the entire peer table of a node requires significant computational effort even with relatively low _k_. DoS attacks against non-naive nodes (as described in this page) require generating addresses with corresponding key pairs for each row, requiring quite a bit of hashing power. \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 40d9af62e..000000000 --- a/LICENSE +++ /dev/null @@ -1,5 +0,0 @@ -The license for this repository is CC BY-SA 4.0. - -A human-readable summary (and not a substitute) of the license is [here](https://creativecommons.org/licenses/by-sa/4.0/). - -The license is [here](https://creativecommons.org/licenses/by-sa/4.0/legalcode). diff --git a/Layers.md b/Layers.md deleted file mode 100644 index 227a0cc7a..000000000 --- a/Layers.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -name: Layers -category: ---- - -## Networking daemon - -Purpose: the networking daemon must be able to connect to other Ethereum nodes, and accept and share data, so as to serve as the backbone for the Ethereum network. The daemon itself should be as neutral as possible; ideally, it should be useful as part of any currency or cryptographic protocol without modification. It should include anti-DDoS features; perhaps maintain a running score preventing any single IP from making more than one request per second. - -Interface: - -1. every time the daemon receives a new message (ie. H(M) is not equal to H(Mprev) for any Mprev received previously), it should send a POST request to http://localhost: containing the data, where outputport can be set in the ~/.ethereum/ethereum.conf file (default 1242 if not set) -2. the daemon should listen on port , where inputport can be set in the ~/.ethereum/ethereum.conf file (default 1243 if not set), and if it receives a message in a post request it should push the data out to all connected nodes in the network. -Dependencies: internet, bootstrapping nodes - -## Ethereum Core - -### Communication layer - -1. Process_network_message(string) -> msg or transaction or block -2. Create_network_message - -### IO Layer (ie. usually database) - -1. Insert object(value) (key = sha256(value)) -2. Get object (key) -> value - -### Data layer - -1. get_transaction -2. get_block -3. get_address_balance / nonce -4. get_contract_memory_at_index -5. get_contract_root -6. get_object (Merkle trie nodes, etc) -7. block class -8. transaction class - -### Manager - -1. get_latest_block -2. add_block (including validation and total difficulty calculation) -3. apply_transactions_to_block (for miners) - -### Application Layer - -1. Wallet -2. Full -3. SPV -4. Graphical block explorer -5. Miner - -## Classes - -### Block class - -Purpose: the block class should be able to parse blocks, serialize blocks and handle certain updating operations to blocks. - -Interface: - -1. deserialize: string -> void (constructor) -2. get_balance: number address -> number -3. get_contract_state: number address, number index -> number -4. update_balance: number address, number newbalance -> void -5. update_contract_state: number address, number index, number newvalue -> void -6. get_contract_size: number address -> number -7. serialize: void -> string - -### Transaction class - -Purpose: the transaction class should be able to parse transactions, sign transactions and serialize transactions. Note that the serialize method should fail for transactions without a signature; transactions that are created inside a block and not deserialized should never actually be stored or serialized in any form. - -Interface: - -1. deserialize: string -> void (constructor) -2. sign: privkey -> void -3. serialize: void -> string -4. create: number address, number value, number fee, array[number] data -> void (constructor) -5. hash: void -> number -6. to, from, value, fee, data (accessible and settable member variables) diff --git a/Licensing.md b/Licensing.md deleted file mode 100644 index b97489ab8..000000000 --- a/Licensing.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -name: Licensing -category: ---- - -Overview - -The Ethereum Foundation ensures three principles concerning the funds it uses to develop Ethereum: - -- it is both open source software and Free software after the definition of the Free Software Foundation (so-called FOSS); -- no special treatment is given to any single entity concerning the copyright of the software, the Foundation included; -- source-code will not be distributed ahead of binaries. - -However, this is not where the story ends; there are many different licenses available that conform to these rules. After considerable discussion, both internal and external together with The Ethereum software collection is distributed under several licenses, partly to reflect the different thinking of the minds behind different pieces of software and partly to reflect the need to adapt to real-world issues and opportunities and lay out a strategy to provide the best possible future for the Ethereum community. - -### The Core - -The core of Ethereum includes the consensus engine, the networking code and any supporting libraries. For C++, this includes libethereum, libp2p, libdevcore, libdevcrypto, libethcore, libevm and libevmface. - -The core of Ethereum will be released under the most liberal of licenses. This reflects our desire to have Ethereum used in as many diverse environments as possible, even those which, for various reasons can require modifications or augmentations to the software which cannot be released to the public. - -In this way, while we have not arrived at a final license, we expect to select one of the MIT license, the MPL license or the LGPL license. If the latter is chosen, it will come with an amendment allowing it to be linked to be statically linked to software for which source code is not available. - -In this way, the core of Ethereum, be it C++ or Go, will be available for use in any commercial environment, closed or open source. - -### The Applications - -The applications of Ethereum, including the Solidity compiler (libsolidity, solc), AlethZero and Mix will be distributed under the GNU General Public License. This is to reflect the fact that these pieces of software tend to not, by nature, need to be amalgamated or augmented into a larger, closed-source, whole. There is however, much to be gained through many different members of the Ethereum-community being incentivised to develop on and build out such software. - -In this way we hope our initial version of Solidity and Mix lay down the foundation for others to build upon and improve in the true Free/open-source software manner. - -### The Middleware - -The middleware of Ethereum, including the Javascript-based ethereum.js, the webthree libraries and eth (the command line client) will be distributed under an Affero license, likely the LGPL variant of it. We wish to allow free development of technologies by allowing linking to arbitrary software, but again would like to incentivise feeding of back-end integration work back into the community, especially regarding the interoperability with legacy systems. \ No newline at end of file diff --git a/Light-client-protocol.md b/Light-client-protocol.md deleted file mode 100644 index f6fc9c06e..000000000 --- a/Light-client-protocol.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -name: Light Client Protocol -category: ---- - -The purpose of the light client protocol is to allow users in low-capacity environments (embedded smart property environments, smartphones, browser extensions, some desktops, etc) to maintain a high-security assurance about the current state of some particular part of the Ethereum state or verify the execution of a transaction. Although full security is only possible for a full node, the light client protocol allows light nodes processing about 1KB of data per 2 minutes to receive data from the network about the parts of the state that are of concern to them, and be sure that the data is correct provided that the majority of miners are correctly following the protocol, and perhaps even only provided that at least one honest verifying full node exists. - -### Background: Patricia Merkle Trees - -All substantial quantities of data in Ethereum are stored in a data structure known as the [Patricia Merkle tree](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree), a tree structure where each node in the tree is the hash of its children. Each set of key/value pairs maps to a unique root hash, and only a small subset of nodes is needed to prove that a particular key/value combination is in the tree corresponding to a particular root hash. - -![](http://vitalik.ca/files/spv.png) - -The size complexity of a Merkle proof scales linearly with the height of a tree; because each child in a tree has a particular number of children (in our case, up to 17), this means that the size complexity of a Merkle proof is logarithmic in the quantity of data stored. This means that, even if the entire state tree is a few gigabytes in size, if a node receives a state root from a trusted source that node has the ability to know with full certainty the validity of any information with the tree by only downloading a few kilobytes of data in a proof. - -An SPV proof of a node in a Patricia tree simply consists of the complete subset of tree nodes that were processed in order to access it (or, more specifically, the tree nodes that needed to be looked up in a reverse-hash-lookup database). In a simple implementation of a Patricia tree, retrieving the value associated with a particular key requires descending the hash tree, constantly looking up nodes in the database by their hashes, until you eventually reach the final leaf node; a simple algorithm for producing an SPV proof is to simply run this naive algorithm, and record all of the database lookups that were made. SPV verification consists of running the naive lookup algorithm but pointing it to a custom database populated only with the nodes in the SPV proof; if there is a "node not found" error, then the proof is invalid. - -## Principles - -In Ethereum, a light client can be viewed as a client that downloads block headers by default, and verifies only a small portion of what needs to be verified, using a distributed hash table as a database for trie nodes in place of its local hard drive. For a "partially light client", which processes everything but is constrained by hard drive space and so stores almost nothing, swapping out a database read with a DHT get request is by itself sufficient to meet the requirements. Indeed, all "full clients" except for archive nodes (intended to be run by businesses, block explorers, etc) will eventually be set up as "partially light clients" with respect to all history older than a few thousand blocks. However, what we are also interested in supporting is _fully_ light clients, which never even process most transactions. Formally, we can say that _all_ measures of a full light client are bounded by a sublinear function of the number of transactions in a block - in most cases, the protocols below work for a bound of O(log(n)), though one particular mechanism works only for ~O(sqrt(n)). - -Some use cases for a fully light client, and how the light client meets those use cases, include: - -* A light client wants to know the state of an account (nonce, balance, code or storage index) at a particular time. The light client can simply recursively download trie nodes from the state root until it gets to the desired value. -* A light client wants to check that a transaction was confirmed. The light client can simply ask the network for the index and block number of that transaction, and recursively download transaction trie nodes to check for availability. -* Light clients want to collectively validate a block. Each light client `C[i]` chooses one transaction index `i` with transaction `T[i]` (with corresponding receipt `R[i]`) and does the following: - * Initiate the state with state root `R[i-1].medstate` and `R[i-1].gas_used` (if `i = 0` use the parent endstate and 0 `gas_used`) - * Process transaction `T[i]` - * Check that the resulting state root is `R[i].medstate` and the gas_used is `R[i].gas_used` - * Check that the set of logs and bloom produced matches `R[i].logs` and `R[i].logbloom` - * Checks that the bloom is a subset of the block header-level bloom (this detects block header-level blooms with false negatives); then pick a few random indices of the block header-level bloom where that bloom contains a 1 and ask other nodes for a transaction-level bloom that contains a 1 at that index, rejecting the block if no response is given (this detects block header-level blooms with false positives) -* Light clients want to "watch" for events that are logged. The protocol here is the following: - * A light client gets all block headers, checks for block headers that contain bloom filters that match one of a desired list of addresses or topics that the light client is interested in - * Upon finding a potentially matching block header, the light client downloads all transaction receipts, checks them for transactions whose bloom filters match - * Upon finding a potentially matching transaction, the light client checks its actual log RLP, and sees if it actually matches - -The first three light client protocols require a logarithmic amount of data access and computation; the fourth requires ~O(sqrt(N)) since bloom filters are only a two-level structure, although this can be improved to O(log(N)) if the light client is willing to rely on multiple providers to point to "interesting" transaction indices and decommission providers if they are revealed to have missed a transaction. The first protocol is useful to simply check up on state, and the second in consumer-merchant scenarios to check that a transaction was validated. The third protocol allows Ethereum light clients to collectively validate blocks with a very low degree of trust. In Bitcoin, for example, a miner can create a block that gives the miner an excessive amount of transaction fees, and there would be no way for light nodes to detect this themselves, or upon seeing an honest full node detect it verify a proof of invalidity. In Ethereum, if a block is invalid, it must contain an invalid state transition at some index, and so a light client that happens to be verifying that index can see that something is wrong, either because the proof step does not check out, or because data is unavailable, and that client can then raise the alarm. - -The fourth protocol is useful in cases where a dapp wants to keep track of some kind of events that need to be efficiently verifiable, but which do not need to be part of the permanent state; an example is a decentralized exchange logging trades or a wallet logging transactions (note that the light client protocol will need to be augmented with header-level coinbase and uncle checks for this to work fully with mining accounts). In Bitcoin terminology, `LOG` can be viewed as a pure "proof of publication" opcode. \ No newline at end of file diff --git a/Middleware-and-Dapp-Project-Ideas.md b/Middleware-and-Dapp-Project-Ideas.md deleted file mode 100644 index 8cfe57f21..000000000 --- a/Middleware-and-Dapp-Project-Ideas.md +++ /dev/null @@ -1,112 +0,0 @@ -This page describes some ideas that I (Vitalik) have that I would like to see implemented, but do not have time for myself. If anyone wants advice on how to implement them feel free to ping me at any time, or just start yourself. - -### Data Feed - -The core idea behind a data feed is simple: a data feed is a contract with an administrator that maintains a key-value store, where the keys represent what data is stored (eg. "BTC/USD") and the values represent the value that the administrator believes the variable currently is in the real world (eg. 235). A simple data feed contract can be found [in the standardized contract APIs repository](https://github.com/ethereum/dapp-bin/tree/master/standardized_contract_apis/fee_charging_datafeed.sol); it has a `set` function which allows its administrator to set the value for a particular key, and a `get` function which allows anyone to get the value for a particular key; that particular contract also allows the administrator to set a fee in ether. - -Regarding fee setting, note that you should not set the fee too high as otherwise it's possible at medium cost to create a "caching passthrough contract": essentially, the smart contract equivalent of piracy, and there's no way to prevent that without compromising the flexibility that makes Ethereum Ethereum; a fee of around 1-10 finney should be fair and work well if you do wish to charge. - -The way that you would implement the server side code is simple. In pseudocode, you can implement it as a separate daemon that accesses an api: - - keys = [("BTC/USD", "http://my_exchange.com/api/BTCUSD?password=12345"), - ("CHF/USD", "http://my_exchange.com/api/CHFUSD?password=12345"), - ("temperature:Seattle", "http://my_weather_network.com/api/temperature/Seattle?password=12346"), - ... ] - for key, url in keys: - try: - value = json.loads(open(url))["value"] - ethereum.send_transaction(ethereum.get_nonce(ethereum.my_address), ethereum.get_gasprice(), - 200000, MY_DATAFEED_CONTRACT, 0, MY_DATAFEED_ABI.encode('set', [key, value]) - except: - pass - -(Note: the above is pseudocode; not all of the above methods are available in pyethereum quite yet). - -If you control: - -* An exchange or other website that has access to price feed or index data -* A weather network -* A site that lists results of real-life events -* A service that KYCs people and assigns them unique identity tokens -* Any other data repository - -Then the Ethereum ecosystem will benefit from you publishing a data feed contract on the ethereum blockchain. - -A closely related idea is an **HTTP getter passthrough contract**. Essentially, the contract would have one method, `get(string)`, that would take a URL as an argument, and simply log the URL alongside the address that asked for the get. A server daemon would make a curl request to the URL, and call the `passthroughCallback(string)` method of the sender address with the output. Note that multiple daemons running in this form could be called in multisig fashion if desired. - -### Web of trust - -Reputation and credit scores are potentially a very powerful economic lubricant in modern society, allowing us to easily tell reliable from unreliable parties, and are even more important in a decentralized world where centralized curation is unavailable and many classes of regulation become more difficult to enforce. The question of "can this user be trusted?" is approximated with a simple and easy-to-understand number. - -Currently, such systems are actively being looked into and adopted by private companies particularly in the "sharing economy": - -
-![](http://www.kellydessaint.com/wp-content/uploads/2014/08/lyft_ratings3.jpg) -
- -And even governments: - -
-[![](https://www.privateinternetaccess.com/blog/wp-content/uploads/2015/10/SesameCredit.jpg)](https://www.privateinternetaccess.com/blog/2015/10/in-china-your-credit-score-is-now-affected-by-your-political-opinions-and-your-friends-political-opinions/) -
- -However, if we want to create a globally accessible system, centralized credit scores are arguably insufficient: not everyone in the world will be willing to trust a particular entity to provide accurate and fair credit scores, particularly in international cases where there are large political differences. Hence, while centralized credit scores may work in particular closed environments, in an international trade context it would be more ideal to have a global framework that allows specialized scoring agencies to exist, but which allows recipients to choose which ones they "listen" to, and even combine their scores. - -A highly effective solution to this problem, which has existed in academia and the public for over a decade, uses the "web of trust" route: essentially, instead of trying to achieve a single universal score for everyone, provide a way for each person to score anyone else from their own point of view. This is accomplished through the trust transitivity heuristic: if A trusts B, and B trusts C, then to some degree that's cause for A to trust C. In some ways, centralized credit scores are a special case of this: everyone trusts the central agency (in theory), the central agency assigns people trust ratings, and so that's how much everyone is induced to trust everyone else. However, the decentralized approach is more general, and ideally allows us to take into account _all_ "chains of trust" between two people, and not just the ones that flow through a particular centralized gateway. - -![](http://vitalik.ca/files/wot_centralized_and_decentralized.png?1) - -One example of an algorithm that does this well is the [Advogato trust metric](http://www.advogato.org/trust-metric.html), a trust score scheme based on [max-flow](https://en.wikipedia.org/wiki/Maximum_flow_problem). - -A useful project would be to create an implementation of such a system on Ethereum, and create a dapp by which anyone can register an identity, and register trust scores for other identities. Then, create a decentralized cloud computing service by which anyone can query "provide a proof, consisting of a list of trust paths, showing the Advogato trust score from A to B" and anyone can reply in exchange for a micropayment (or perhaps create a server that does it for free, and convince a charity to subsidize it); if user A wants to know "what is B's trust score", they can make this query, receive the result, verify the proof, and then display it. - -This system could then be used by many other dapps on ethereum, including financial contract using price feeds and arbitration. - -### Financial Derivatives Market - -Essentially, a polished, working dapp that allows users to make options on any ethereum asset, and derivatives (eg. CFDs) on any ethereum price feed. This should support "multisig price feeds": choosing multiple data feed contract addresses that support a particular ticker symbol, and taking the median of them, so as to remove reliance on any single party. - -Supported actions should ideally include: - -* Entering into CFDs with other parties on any price index, settling in any standards-compatible currency or asset (though perhaps start with ETH) -* Options between any two assets (though perhaps start with asset<->ETH) -* Plain old regular asset exchange -* An order book for all of the above - -### RANDAO - -Essentially, [this](https://forum.ethereum.org/discussion/2031/randao-a-dao-working-as-rng). Set it up as a decentralized service which any lottery or other randomness-based game can use; also, build a "full node software" package/plugin which facilitates participating in the RANDAO by providing random numbers. - -### Interface with national ID - -Create a system, relying on trusting no one other than the original issuer, by which users with electronic identities (eg. Estonian digital ID, other electronic passports, crypto KYC schemes, etc) can prove to the ethereum blockchain that they have that particular ID. Note that this can be plugged into the WoT by, eg, creating a contract which trusts everyone who has an Estonian digital ID with score 1. - -### Zero knowledge proofs - -Create multiple compatible implementations of a ZK-SNARK protocol. - -### Ultrahard KDFs for brainwallets - -A decentralized paid cloud computing service for brainwallet computations, combined with a client-side solution, in order to implement my proposal for ultra-secure brainwallets using blind-outsourceable ultrahard KDFs: https://blog.ethereum.org/2014/10/23/information-theoretic-account-secure-brainwallets/ - -### Estonia ID integration - -Create a system which integrates the Estonian digital ID system into Ethereum; essentially, create a registry where someone can link their address to a particular Estonian digital ID by signing a transaction with their ID. The registry should cryptographically verify that the signature is valid and that it matches a particular ID, and should then store a mapping, eg. `address -> (first name, last name, number)` - -Some developer resources that can help with this include: - -* http://eid.eesti.ee/index.php/Authenticating_in_web_applications -* https://e-estonia.com/e-residents/for-developers/ -* https://sk.ee/en/services/testcard/ -* http://id.ee/index.php?id=30469 - -### Security Deposit-backed Conditional Hashcash - -The key piece of technology that later spawned the advent of blockchains starting with Bitcoin, proof of work, was originally devised for quite a different application: email spam prevention. In order to send an email that would be viewed by recipients' email interfaces, users would need to complete a certain amount of computational work on their computers that could quickly be verified. This would impose a small cost in electricity and CPU power to sending an email (say, $0.01) that would in theory be no problem for ordinary messages, but would be so expensive as to make spam no longer worth it. In practice, this idea never succeeded, in large part because people did not want to pay for their email and because it would only lead to spammers paying more in order to send more well-crafted emails to fewer parties, which would be more likely to receive attention because users think that they already passed the proof of work filter. - -Here, I propose a proof of stake twist on the algorithm that would solve this problem. The key insight is that instead of making the sender _always_ pay the cost, we make the cost a security deposit, and the recipient has the right, only if they wish, to destroy the security deposit at no benefit to themselves (in an actual implementation, "destroy" will hopefully mean something like "donate to protocol developers"). Ordinary "useful" messages would get through unscathed, and spam would be punished in proportion to the percentage of people that find it scammy. The conditional nature of the protocol can theoretically allow the deposits to be increased much higher than the cost of proof of work; deposits of $1 or even higher are quite reasonable. - -There are two possible extensions to this idea: - -1. Use techniques similar to [anti-pre-revelation games](https://blog.ethereum.org/2015/08/28/on-anti-pre-revelation-games/#comment-2230211912) (or possibly other techniques) to allow users to destroy other users' security deposits (either probabilistically or fully) without the victim knowing who did it. This allows the mechanism to be used more effectively in intra-organizational and social situations, so that you can punish people for being annoying without extra-protocol repercussions. Aside from information-theoretic strategies, there may be routes to doing this using Chaumian blinding schemes, cryptographic accumulators and/or zk-SNARK proofs; the goal to target would be in a scenario with one sender and N recipients, with the sender having a deposit of $NX, giving each recipient the right to destroy $X exactly once without revealing which one of the N they are; the main challenge is the sender gleaning this information by simulating the process of each single recipient destroying their deposit and seeing which one(s) fail, and so private information on the recipients' part and perhaps even an interactive protocol is required. -2. Have different levels of deposits, where higher levels of deposits can be used to signal more importance/urgency in the interface; at the highest levels, one could imagine a deposit of $500 leading to one's phone ringing maximally loudly whereas a deposit of $0.1 would only lead to an email appearing next time one opens one's mailbox. \ No newline at end of file diff --git a/Mining.md b/Mining.md deleted file mode 100644 index 2fce6bcb0..000000000 --- a/Mining.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -name: Mining -category: ---- - -# Introduction - -The word mining originates in the context of the gold analogy for crypto currencies. Gold or precious metals are scarce, so are digital tokens, and the only way to increase the total volume is through mining it. This is appropriate to the extent that in Ethereum too, the only mode of issuance post launch is via the mining. Unlike these examples however, mining is also the way to secure the network by creating, verifying, publishing and propagating blocks in the blockchain. - -* Mining Ether = Securing the network = verify computation - -## So what is mining anyway? - -Ethereum Frontier like all blockchain technologies uses an incentive-driven model of security. Consensus is based on choosing the block with the highest total difficulty. -Miners produce blocks which the others check for validity. Among other well-formedness criteria, a block is only valid if it contains **proof of work** (PoW) of a given **difficulty**. -Note that in Ethereum 1.1, this is likely gonna be replaced by a **proof of stake** model. - -The proof of work algorithm used is called [Ethash](https://github.com/ethereum/wiki/wiki/Ethash) (a modified version of [Dagger-Hashimoto](https://github.com/ethereum/wiki/wiki/Dagger-Hashimoto) involves finding a nonce input to the algorithm so that the result is below a certain threshold depending on the difficulty. The point in PoW algorithms is that there is no better strategy to find such a nonce than enumerating the possibilities while verification of a solution is trivial and cheap. If outputs have a uniform distribution, then we can guarantee that on average the time needed to find a nonce depends on the difficulty threshold, making it possible to control the time of finding a new block just by manipulating difficulty. - -The difficulty dynamically adjusts so that on average one block is produced by the entire network every 12 seconds (ie., 12 s block time). This heartbeat basically punctuates the synchronisation of system state and guarantees that maintaining a fork (to allow double spend) or rewriting history is impossible unless the attacker possesses more than half of the network mining power (so called 51% attack). - -Any node participating in the network can be a miner and their expected revenue from mining will be directly proportional to their (relative) mining power or **hashrate**, ie., number of nonces tried per second normalised by the total hashrate of the network. - -Ethash PoW is memory hard, making it ASIC resistant. This means that calculating the PoW requires choosing subsets of a fixed resource dependent on the nonce and block header. This resource (a few gigabyte size data) is called a **DAG**. The [DAG](https://github.com/ethereum/wiki/wiki/Ethash-DAG) is totally different every 30000 blocks (a 100 hour window, called an **epoch**) and takes a while to generate. Since the DAG only depends on block height, it can be pregenerated but if its not, the client needs to wait till the end of this process to produce a block. Until clients actually precache dags ahead of time the network may experience a massive block delay on each epoch transition. Note that the DAG does not need to be generated for verifying the PoW essentially allowing for verification with both low CPU and small memory. - -As a special case, when you start up your node from scratch, mining will only start once the DAG is built for the current epoch. - - -## Mining Rewards - -Note that mining 'real' Ether will start with the Frontier release. On the Olympics testnet, the [Frontier pre-release](http://ethereum.gitbooks.io/frontier-guide/), the ether mined have no value (but see [Olympic rewards](https://blog.ethereum.org/2015/05/09/olympic-frontier-pre-release/)). - -The successful PoW miner of the winning block receives: -* A **static block reward** for the 'winning' block, consisting of exactly 5.0 Ether -* All of the gas expended within the block, that is, all the gas consumed by the execution of all the transactions in the block submitted by the winning miner is compensated for by the senders. The gascost incurred is credited to the miner's account as part of the consensus protocoll. Over time, it's expected these will dwarf the static block reward. -- An extra reward for including Uncles as part of the block, in the form of an extra 1/32 per Uncle included - -Uncles are stale blocks, ie with parent that are ancestors (max 6 blocks back) of the including block. -Valid uncles are rewarded in order to neutralise the effect of network lag on the dispersion of mining rewards, thereby increasing security. -Uncles included in a block formed by the successful PoW miner receive 7/8 of the static block reward = 4.375 ether -A maximum of 2 uncles allowed per block. - -## Ethash DAG - -Ethash uses a **DAG** (directed acyclic graph) for the proof of work algorithm, this is generated for each **epoch**, i.e every 30000 blocks (100 hours). The DAG takes a long time to generate. If clients only generate it on demand, you may see a long wait at each epoch transition before the first block of the new epoch is found. However, the DAG only depends on block number, so it CAN and SHOULD be calculated in advance to avoid long wait at each epoch transition. `geth` implements automatic DAG generation and maintains two DAGS at a time for smooth epoch transitions. Automatic DAG generation is turned on and off when mining is controlled from the console. It is also turned on by default if `geth` is launched with the `--mine` option. Note that clients share a DAG resource, so if you are running multiple instances of any client, make sure automatic dag generation is switched on in at most one client. - -To generate the DAG for an arbitrary epoch: - -``` -geth makedag -``` - -For instance `geth makedag 360000 ~/.ethash`. Note that ethash uses `~/.ethash` (Mac/Linux) or `~/AppData/Ethash` (Windows) for the DAG so that it can shared between clients. - - -# The Algorithm - -Our algorithm, [Ethash](https://github.com/ethereum/wiki/wiki/Ethash) (previously known as Dagger-Hashimoto), is based around the provision of a large, transient, randomly generated dataset which forms a DAG (the Dagger-part), and attempting to solve a particular constraint on it, partly determined through a block's header-hash. - -It is designed to hash a fast verifiability time within a slow CPU-only environment, yet provide vast speed-ups for mining when provided with a large amount of memory with high-bandwidth. The large memory requirements mean that large-scale miners get comparatively little super-linear benefit. The high bandwidth requirement means that a speed-up from piling on many super-fast processing units sharing the same memory gives little benefit over a single unit. - -## Formal Requirements - -TODO: Content from formal requirements doc. - -## Design Decisions Taken - -TODO: Content from design decisions doc. - -## Infrastructure Overview - -Mining will be accomplished in one of two ways: either on CPU (and possibly the GPU, to be confirmed) with the Mist client or on the GPU though a combination of the Ethereum daemon and [sgminer](https://github.com/sgminer-dev/sgminer). - -An sgminer module for Ethash is expected to be released at some point during, but not necessarily before the Frontier Genesis. - -## JSON-RPC - -Communication between the external mining application and the Ethereum daemon for work provision and submission happens through the JSON-RPC API. Two RPC functions are provided; `eth_getWork` and `eth_submitWork`. - -These are formally documented on the [JSON-RPC API](https://github.com/ethereum/wiki/wiki/JSON-RPC) wiki article. - diff --git a/Mix-Features.md b/Mix-Features.md deleted file mode 100644 index 66d6b62e4..000000000 --- a/Mix-Features.md +++ /dev/null @@ -1,183 +0,0 @@ ---- -name: Mix Features -category: ---- - -# Block Mining - -Hit `File`->`New Project`. - -Type contract: - -```javascript -contract Test { -} -``` - -Hit `File`->`Save`. - -Hit `Deploy`->`Deploy 'Default'` to deploy contract. - -Then for index.html: - -```html - - - - - - number: - - - -``` - -Hit `File`->`Save`. - -In the HTML view, you'll see: - -``` -number: 1 -``` - -Hit `Deploy`->`Mine`. - -The HTML view will update to: - -``` -number: 2 -``` - -# Parameters in Contract Constructor - -Write a Contract containing parameters in the constructor: - -```javascript -contract Test { - uint mem; - Test(uint _a, uint _b) { mem = _a; } - get() returns (uint) - { - return mem; - } -} -``` - -Press `F7` => `Edit State` -The transaction named 'Constructor' should appear in the transaction lists. - -Press `Edit` (on `Constructor`) -This modal dialog should allow users to fill in input parameters (_a and _b). - -Press `+` to add a new transaction. Select the function `get` and save. - -Press `F5` (or run the current editing state if this is not the default state). - -Verify that the return value of `get` is displayed and is this is the good one => in the transaction log (column `returned`). - -# Deploy to Network - -This feature allows users to deploy the current project as a Dapp in the main blockchain. -This will deploy contracts and register front end resources. - -The deployment process includes two steps: - - **The Deployment of contracts**: -This step will deploy contracts in the main blockchain and package front end resources of the current project. After this operation the package (package.dapp) will be available inside the deployment directory. - - - **The Registration of front end resources**: -To render the Dapp, the Ethereum browser (Mist or AlethZero) needs to access this package. This step will register the URL where the resources are stored. - -To Deploy your Dapp, Please follow these instructions: - -Click on `Deploy`, `Deploy to Network`. -This modal dialog displays two parts, We will focus on the first part (Deployment) for now: - - **The Deployment of contracts** - - 4 Buttons: `Help` to access to the WikiPage, `Open Package Folder` to open the deployment directory (this button is only enable is the package is built), `Copy Base64 conversion to ClipBoard` to copy the Base64 value of the built package (this button is only enable is the package is built), `Exit` to close this modal dialog. - - `Root Registrar address` is the address of the root registrar contract (used to link the Dapp with resources. - - `Account used to deploy` allows users to select the Ethereum account to use to deploy. - - `Amount of gas to use..` is the amount of gas that the deployment process will use to deploy contracts. - - `Ethereum Application URL` is the address that users should use in Mist (or AlethZero) to access to the Dapp. in italic, you can check the formatted Dapp URL (which will be used by the Ethereum browser) -(ex: eth/user1/app1). - - `Web Application Resources URL` is the URL where the front resources (html/js/...) will be stored. - - 1 button to start the deployment process (The checkbox `Deploy Contract(s)` is disabled and checked if this is the first time the contract is deployed. If not you can choose to repackage the resources without redeploying the contract by unchecking this option). - -Click on `Deploy contract(s) and Package resources files` (last button) and the deployment is executed. -Then many options/actions will be enabled: - - `Open Package Folder`, `Copy Base64 conversion to ClipBoard`, `Deploy Contract(s)` - - All inputs associated with the second step. - -**Host your web application** - -There are many places where to host front end resources, you just need to find a web server. One other way (and very easy way) could be to use the pastebin.com service: - - Follow the first deployment step to deploy contract(s). - - The `Copy Base64 conversion to ClipBoard` icon will be enable (on top of the modal dialog), click on this icon to copy the Base64 content into the clipboard. - - Go to pastebin.com and paste the content into the `New Paste` input. Then click on `Submit'. - - Go through the Captcha. - - Copy the address targeted by the link `Raw` (on the top of the page). - - Use this address in the `Web Application Resources URL` field. - -**Registration of front end resources** - - `URL Hint contract address` is the address of the contract which is used to store the URL where the resources are. - - `Web Application Resources URL` is the URL from where the Ethereum browser will retrieve resources. - -Click on `Register hosted Web Application` and Mix will register the front end resources on the Ethereum network. - -Users can now use Mist or AlethZero to access to the Dapp, using the Ethereum URL (ex: eth/user1/app1). - -# Account Management - -When a new state is created, it is possible to add new accounts which can be used to send transaction. -It is not possible to delete an account if this one is used by a transaction. - -By default, one account is created, this account will be used to deploy standards contract like `Config` and `NameReg` but can also be used in other transactions. - -For each created account users have to specify a balance. When users start to debugging, the state will -be initialized with all the configured accounts/balances. - -When a transaction is edited, users can select which account to set as the sender. - -# Logs Window - -Clicking on the header status pane will open a pane which displays all logs generated by Mix. -There are 3 log levels: info, warning, error. -Those logs comes from different part of Mix: - - `JavaScript` displays logs coming from the Web preview, it shows error messages generated by the JavaScript engine and messages generated by the command `console.log('...')`. - - `Run` displays logs coming from the execution of transactions. - - `State` displays logs coming from directly from the state (State alteration, New block added). - - `Compilation` displays logs generated by an error when Mix is trying to compile contracts. - -On the header are several actions: - - Clear the content of this window. - - Copy the content to the Clipboard. - - Select which log type to display (4 buttons). - - Use the text input to filter displayed logs. - -# Auto-completion for solidity source - -Auto-completion in Mix is based on the code mirror plugins show-hint.js and anyword-hint.js (Not semantic) -It displays: - - Solidity token (currency, keywords, stdContract, Time, Types). - - Contract Name. - - Functions Name. - - Words that are in the nearby code. - -# Error messages - -When running a bunch of transactions, several error might happen. -One of the common error is that the current account does not have enough ether to execute a transaction. -Users should be aware of that and the status panel should display the amount of gas needed, and the current amount of ether that the user has given for this transaction. -Other important error messages will be displayed here. - -# Highlight secondary error locations - -If the current compilation error has secondary errors locations Mix shows those secondary errors. -In each secondary errors Mix shows where (document) the primary error is. \ No newline at end of file diff --git a/Mix-improvement-proposal.md b/Mix-improvement-proposal.md deleted file mode 100644 index 2eb055a4b..000000000 --- a/Mix-improvement-proposal.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -name: Mix Improvement Proposal -category: ---- - -how it currently looks, its working well for very simple scripts, but its hard to impossible to use for any advanced javascript application, using require.js, common.js, bower, npm, angualr.js, ember, canjs, meteor or any more advanced js framework. As the current deploy method forces you to do things in a simplistic way (linking ethereum.js, contracts files and add the contract variable) - -This also makes it hard to test your application as the deploy process is the one, which uploads the contracts as well and nobody want to deploy its app and contracts without being able to thoroughly test them on the main/test net beforehand. - -Additionally not all dapps use one or more contracts, but might want to deploy contracts on the fly (like the wallet dapp) and need a simple way to get the compiled contract code. - -So here a re my suggestions: - -- Deploy should only deploy the app files (with the possibility to choose a to-deploy-folder), and can include the automated name reg stuff as well - -- contracts should be deployed by right clicking them -> deploy contract, which then asks where to deploy (testnet, mainnet) and gives back the ABI and address (maybe in a `myContract-deployed.js`) - -- contracts should also be compiled with right click -> compile contract, giving the compiled HEX string and ABI in an `myContract-compiled.js` (or just use one `myContract-mix.js`) - -- the files in the sidebar should show the folder structure and not sort by type, as any advanced js application needs more than just an index.html and js file. (folders are good ;) - -- the deployable file should be zip, not rlp so people can unpack it easily and discover the content which will be deployed. This also allows to understand it and write separate bundle scripts for them. **(But, might anyway become obsolete with swarm)** - -I think this improvements, will allow for greater flexibility without compromising the use of mix. \ No newline at end of file diff --git a/Mix:-The-DApp-IDE.md b/Mix:-The-DApp-IDE.md deleted file mode 100644 index 26afb6857..000000000 --- a/Mix:-The-DApp-IDE.md +++ /dev/null @@ -1,181 +0,0 @@ ---- -name: Mix The DAPP IDE -category: ---- - -# Welcome to Mix IDE! - -This guide provides a very simple and quick introduction to the Mix IDE workflow by walking you through the creation of a simple ÐApp. Once you are done with this tutorial, you will have a general knowledge of how to create and run applications in the IDE. - -Note that the software is in still in proof-of-concept state. Things are changing rapidly and this tutorial might not be up to date. If that is the case [please open an issue](https://github.com/ethereum/cpp-ethereum/issues) or [edit the wiki](https://github.com/ethereum/wiki/wiki/Mix%3A-The-DApp-IDE/_edit). - -## Getting started. - -This tutorial assumes you have [C++ Ethereum installed](https://github.com/ethereum/cpp-ethereum/wiki). - -## Creating a new project - -Let's create a simple ÐApp that will allow user to store and query personal movie ratings. - -In the IDE, choose `File > New Project`. Enter the project name "MovieRatings" and a path for the project file. To the left there is a project items list with two items added by default: Contract and index.html. Contract contains [Solidity](https://github.com/ethereum/wiki/wiki/Solidity-Tutorial) contract code, and index.html is for the front-end. You can add new contract files to the project using file menu. All files will be copied to the project directory. - -Select Contract and enter the text for the rating contract: - -```js - contract Rating { - function setRating(bytes32 _key, uint256 _value) { - ratings[_key] = _value; - } - mapping (bytes32 => uint256) public ratings; - } -``` - -Check [Solidity tutorial](https://github.com/ethereum/wiki/wiki/Solidity-Tutorial) for solidity reference. - -Now select `index.html` and enter the following html code: -```html - - - - - - -

Ratings

-
- Store: - - - -
-
- Query: - -
-
- - -``` -Note that Mix exposes the following objects into the global window context: -* [`web3`](https://github.com/ethereum/wiki/wiki/JavaScript-API#web3) - Ethereum JavaScript API - -* `contracts` - A collection of contract objects. A key to the collection is the contract name. A value is an object with the following properties: - * `contract` - Contract object instance (created as in `web3.eth.contract`) - * `address` - Contract address from the last deployed state (see below) - * `interface` - Contract ABI - -Check the [JavaScript API Reference](https://github.com/ethereum/wiki/wiki/JavaScript-API) for further information. - -Select `File > Save` to save project files. You should see the web preview in the web preview pane. - -## Setting up state - -Now we need to configure a state for debugging. Mix has its own blockchain that is reset on each debugging session. States are used to get the blockchain to a point where it is possible to make transactions and calls to a contract. A state is defined by a sequence of transactions that create DApp and all dependencies on the blockchain and set up DApp initial storage. - -If the debugger pane on the right side is not open, open it by pressing `F7` or selecting `Windows > Show right view` from the menu. At the top of the right pane you can see a state selector and a transaction log. The Default state is already created. Add a transaction by clicking the `Add Tx` button. Make sure the function called `Rating` is selected from the Contract dropdown. This is the contract constructor, running this transaction will effectively deploy the contract on a blockchain. Close the windows by pressing `OK`. - -Add another transaction with `Add Tx` button. This time select a `Transact with Contract` transaction and enter parameter values, e.g. `Titanic` for _key and `4` for _value. This will add a single rating key-value pair to the state. Close the state editor with `OK`. Now once you press `Add Block...` the blockchain will be cleared and a state will be re-deployed. You can see the Pending transactions move to Block 1 in the transaction log. - -## Transaction log - -Now let's test out contract. Type "Titanic" in the web preview query input and you should see the result returned. Enter a name and a rating in store fields and click `Save` to add a new rating. Note that all transactions and calls made to the contract during state deployment and debugging session are recorded into Transaction log to the right. Double click on any entry to load the execution into the debugger. There is also a mine button `Add Block...` to instantly mine a new block on the chain and put all pending transactions there. - -## Debugging - -Mix currently supports assembly level contract code debugging. Source level debugging is a work in progress. - -### Assembly level debugging - -Double-click a `setRating` transaction in the transaction log to debug it. The VM assembly code is loaded into the assembly view and the execution slider is reset to a first position. You can navigate the execution using the slider and/or step buttons. At any execution point the following information is available: - -* VM stack. -* Call stack - Grows when contract is calling into another contract. Double click a stack frame to view the machine state in that frame -* Storage - Storage data associated with the contract -* Memory - Machine memory allocated up to this execution point -* Call data - Transaction or call parameters - -See the [Ethereum Yellow Paper](http://gavwood.com/Paper.pdf) for VM instruction description. - -## Deployment to network - -This feature allows users to deploy the current project as a Dapp in the main blockchain. -This will deploy contracts and register frontend resources. - -The deployment process includes three steps: - - - **Deploy contract**: -This step will deploy contracts in the main blockchain. - - - **Package dapp**: -This step is used to package and upload frontend resources. - - - **Register**: -To render the Dapp, the Ethereum browser (Mist or AlethZero) needs to access this package. This step will register the URL where the resources are stored. - -To Deploy your Dapp, Please follow these instructions: - -Click on `Deploy`, `Deploy to Network`. -This modal dialog displays three parts (see above): - - - **Deploy contract** - - - *Select Scenario* - -"Ethereum node URL" is the location where a node is running, there must be a node running in order to initiate deployment. - -"Pick Scenario to deploy" is a mandatory step. Mix will execute transactions that are in the selected scenario (all transactions except transactions that are not related to contract creation or contract call). Mix will display all the transactions in the panel below with all associated input parameters. - -"Gas Used": depending on the selected scenario, Mix will display the total gas used. - - - *Deploy Scenario* - -"Deployment account" allow selecting the account that Mix will use to execute transactions. - -"Gas Price" shows the default gas price of the network. You can also specify a different value. - -"Deployment cost": depending on the value of the gas price that you want to use and the selected scenario. this will display the amount ether that the deployment need. - -"Deployed Contract": before any deployment this part is empty. This will be filled once the deployment is finished by all contract addresses that have been created. - -"Verifications". This will shows the number of verifications (number of blocks generated on top of the last block which contains the last deployed transactions). Mix keep track of all the transactions. If one is missing (unvalidated) it will be displayed in this panel. - -- **Package dapp** - -- *Generate local package* - -The action "Generate Package" will create the package.dapp in the specified folder - -"Local package Url" the content of this field can be pasted directly in AlethZero in order to use the dapp before uploading it. - -- *Upload and share package* - -This step has to be done outside of Mix. package.dapp file has to be hosted by a server in order to be available by all users. - -"Copy Base64" will copy the base64 value of the package to the clipboard. - -"Host in pastebin.com" will open pastebin.com in a browser (you can then host your package as base64). - -- **Package dapp** - -"Root Registrar address" is the account address of the root registrar contract - -"Http URL" is the url where resources are hosted (pastebin.com or similar) - -"Ethereum URL" is the url that users will use in AlethZero or Mist to access your dapp. - -"Formatted Ethereum URL" is the url that users will use in AlethZero or Mist to access your dapp. - -"Gas Price" shows the default gas price of the network. You can also specify a different value. - -"Registration Cost" will display the amount of ether you need to register your dapp url. diff --git a/Morden.md b/Morden.md deleted file mode 100644 index f3e912ea6..000000000 --- a/Morden.md +++ /dev/null @@ -1,61 +0,0 @@ -Morden is the first Ethereum alternative testnet. It is expected to continue throughout the Frontier and Homestead era. - -### Usage - -#### TurboEthereum (C++) - -This is supported natively on 0.9.93 and above. Pass the `--morden` argument in when starting any of the clients. e.g.: - -``` -> eth --morden -``` - -Or, for AlethZero - -``` -> alethzero --morden -``` - -#### PyEthApp (Python client) - -PyEthApp supports the morden network from v1.0.5 onwards: - -``` -> pyethapp --profile morden run -``` - -### Details - -- Network Identity: **2** -- All parameters same as Frontier except: - - genesis.json (given below); - - Initial Account Nonce (`IAN`) is 2^20 (instead of 0 in all previous networks). - - All accounts in the state trie have nonce >= `IAN`. - - Whenever an account is inserted into the state trie it is initialised with nonce = `IAN`. -- Genesis block hash: `0cd786a2425d16f152c658316c423e6ce1181e15c3295826d7c9904cba9ce303` -- Genesis state root: `f3f4696bbf3b3b07775128eb7a3763279a394e382130f27c21e70233e04946a9` - -### Seed Nodes -- `enode://e58d5e26b3b630496ec640f2530f3e7fa8a8c7dfe79d9e9c4aac80e3730132b869c852d3125204ab35bb1b1951f6f2d40996c1034fd8c5a69b383ee337f02ddc@92.51.165.126:30303` - -### genesis.json - -```json -{ - "nonce": "0x00006d6f7264656e", - "difficulty": "0x20000", - "mixhash": "0x00000000000000000000000000000000000000647572616c65787365646c6578", - "coinbase": "0x0000000000000000000000000000000000000000", - "timestamp": "0x00", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData": "0x", - "gasLimit": "0x2FEFD8", - "alloc": { - "0000000000000000000000000000000000000001": { "balance": "1" }, - "0000000000000000000000000000000000000002": { "balance": "1" }, - "0000000000000000000000000000000000000003": { "balance": "1" }, - "0000000000000000000000000000000000000004": { "balance": "1" }, - "102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c": { "balance": "1606938044258990275541962092341162602522202993782792835301376" } - } -} -``` \ No newline at end of file diff --git a/NatSpec-Determination.md b/NatSpec-Determination.md deleted file mode 100644 index 41deff0aa..000000000 --- a/NatSpec-Determination.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -name: NatSpec Determination -category: ---- - -Publishing and finding the [NatSpec] (https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format) documentation for a contract is an important part of the Ethereum system. There are two pieces to this puzzle: the first is for a given client to be able to determine, given a call to a contract, what a **trustworthy** NatSpec documentation hash for the contract is; the second is to find the actual NatSpec documentation body given its content hash. - -### Trusted Content Determination - -The former, trusted content determination, will ultimately be accomplished through a sophisticated reputation system. In the meantime, we (the Ethereum foundation) will maintain our own curated repository of trusted NatSpec documentation hashes in a contract. The contract is trivial, just providing a mapping from contract code hash to NatSpec JSON file hash. It can be found [here](https://github.com/ethereum/dapp-bin/blob/master/NatSpecReg/contract.sol). We, alone, will retain the key updating and adding entries to this contract. - -This contract will have a specific address on the PoC-9 & Frontier testnet, probably referenced from the Ethereum services contract. - -### Content Publishing and Distribution - -The latter, content publishing and distribution, will ultimately be accomplished through the "Swarm" subsystem or IPFS. Until then, we will piggy back on the existing workaround for content-based publication and distribution; the [URL Hint](https://github.com/ethereum/wiki/wiki/URL-Hint-Protocol) system. - diff --git a/Natspec-Example.md b/Natspec-Example.md deleted file mode 100644 index bb09be753..000000000 --- a/Natspec-Example.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -name: NatSpec Example -category: ---- - -# Introduction - -This is intended as an example of proof of concept of the natspec evaluation in Alethzero, the CPP client and as a showcase of the functionality of Natspec comments. - -# Steps - -## Create the natspec documentation - -Open up alethzero client and type in the following contract that we will use as an example - -``` -contract test { - /// @notice Will multiply `a` by 7. - function multiply(uint a) returns(uint d) { - return a * 7; - } -} -``` - -![Creating natspec in AZ](images/natspec1.png) - -Then press the `Execute` button in order to generate the contract creation transaction. We can do that from the JSON Api too but we are using AlethZero in order to create the natspec documentation from the contract. Pressing the execute button will create a local database entry (LevelDB) of a mapping of the contract's hash to the natspec documentation. - -This is just a temporary solution to showcase the functionality of natspec. The idea is for people to be able to retrieve natspec documentations of contracts from a trusted authority which most users can trust. - -## Open up the example contract - -![Opening up example contract](images/natspec2.png) -We will be using the JSON Api to try and perform the only transaction that our example contract has defined in its interface. Open up Alethzero's internal browser and type in the following path to get to our example `/path/to/cpp-ethereum/libjsqrc/ethereumjs/example/natspec_contract.html`. - -You should see a page similar to below. Press the button to start the example. -![Starting natspec example](images/natspec3.png) -## Performing the transaction - -This is the interface our _application_ has for the contract. Using the textbox we can provide the input to the transaction and then execute it. - -## Authentication - -At this final stage is where natspec actually comes into place. Each and every transaction has an authentication stage. The natspec documentation is what is provided to the user in order to notify him of the transaction and query whether or not to go ahead with it. -![Authenticating natspec](images/natspec4.png) - -As you can see from the picture below even if a contract's transaction does not have any specific documentation we will still get a generic popup message asking us whether or not we want to authenticate the transaction. -![Authenticating unknown transaction](images/natspec5.png) \ No newline at end of file diff --git a/Network-Status.md b/Network-Status.md deleted file mode 100644 index 30fb35cea..000000000 --- a/Network-Status.md +++ /dev/null @@ -1,101 +0,0 @@ ---- -name: NatSpec Status -category: ---- - -# Network Status Monitoring - -The [Ethereum (centralised) network status monitor](https://stats.ethdev.com) (known sometimes as "eth-netstats") is a web-based application to monitor the health of the testnet/mainnet through a group of nodes. - -## Listing - -To list your node, you must install the client-side information relay, a node module. Instructions given here work on Ubuntu (Mac OS X follow same instructions, but sudo may be unnecessary). Other platforms vary (please make sure that nodejs-legacy is also installed, otherwise some modules might fail). - -Clone the git repo, then install pm2: - -``` -git clone https://github.com/cubedro/eth-net-intelligence-api -cd eth-net-intelligence-api -npm install -sudo npm install -g pm2 -``` - -Then edit the `app.json` file in it to configure for your node: - -- alter the value to the right of `LISTENING_PORT` to the ethereum listening port (default: 30303) -- alter the value to the right of `INSTANCE_NAME` to whatever you wish to name your node; -- alter the value to the right of `CONTACT_DETAILS` if you wish to share your contact details -- alter the value to the right of `RPC_PORT` to the rpc port for your node (by default 8545 for both cpp and go); -- and alter the value to the right of `WS_SECRET` to the secret (you'll have to get this off [the official skype channel](http://tinyurl.com/ofndjbo)). - -Finally run the process with: - -``` -pm2 start app.json -``` - -Several commands are available: - -- `pm2 list` to display the process status; -- `pm2 logs` to display logs; -- `pm2 gracefulReload node-app` for a soft reload; -- `pm2 stop node-app` to stop the app; -- `pm2 kill` to kill the daemon. - -### Updating -In order to update you have to do the following: -- `git pull` to pull the latest version -- `sudo npm update` to update the dependencies -- `pm2 gracefulReload node-app` to reload the client - - -*** - -## Auto-installation on a fresh Ubuntu install -Fetch and run the build shell. This will install everything you need: latest ethereum - CLI from develop branch (you can choose between eth or geth), node.js, npm & pm2. - -```bash -bash <(curl https://raw.githubusercontent.com/cubedro/eth-net-intelligence-api/master/bin/build.sh) -``` - -### Configuration -Configure the app modifying [processes.json](/eth-net-intelligence-api/blob/master/processes.json). Note that you have to modify the backup processes.json file located in `./bin/processes.json` (to allow you to set your env vars without being rewritten when updating). - -```js -"env": - { - "NODE_ENV" : "production", // tell the client we're in production environment - "RPC_HOST" : "localhost", // eth JSON-RPC host the default is 8545 - "RPC_PORT" : "8545", // eth JSON-RPC port - "LISTENING_PORT" : "30303", // eth listening port (only used for display) - "INSTANCE_NAME" : "", // whatever you wish to name your node - "CONTACT_DETAILS" : "", // add your contact details here if you wish (email/skype) - "WS_SERVER" : "wss://stats.ethdev.com", // path to eth-netstats WebSockets api server - "WS_SECRET" : "", // WebSockets api server secret used for login - } -``` - -### Run - -Run it using pm2: - -```bash -cd ~/bin -pm2 start processes.json -``` - -ethereum (eth or geth) must be running with rpc enabled. - -``` -geth --rpc -``` -the default port (if one is not specified) for rpc under geth is 8545 - -### Updating -To update the API client use the following command: - -```bash -~/bin/www/bin/update.sh -``` - -It will stop the current netstats client processes, automatically detect your ethereum implementation and version, update it to the latest develop build, update netstats client and reload the processes. \ No newline at end of file diff --git a/NewBlock-Message.md b/NewBlock-Message.md deleted file mode 100644 index 91699561d..000000000 --- a/NewBlock-Message.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -name: NewBlock Message -category: ---- - -### Goals - -At present `Blocks` messages may be sent either as a response to a `GetBlocks` message receipt or due to a new block being mined or discovered. This causes some issues for the state transition mechanisms, which are to be avoided. - -### Basic Design - -Provide a second response type explicitly used for distributing a new block. - -### Needed Changes - -New packet for the Ethereum sub-protocol, `NewBlock`: - -**Blocks** -[`+0x06`, [`blockHeader`, `transactionList`, `uncleList`], `...`] Specify (a) block(s) as an answer to `GetBlocks`. The items in the list (following the message ID) are blocks in the format described in the main Ethereum specification. This may validly contain no blocks if no blocks were able to be returned for the `GetBlocks` query. - -**NewBlock** -[`+0x07`, [`blockHeader`, `transactionList`, `uncleList`], `totalDifficulty`] Specify a single block that the peer should know about. The composite item in the list (following the message ID) is a block in the format described in the main Ethereum specification. -- `totalDifficulty` is the total difficulty of the block (aka score). diff --git a/Node-discovery-protocol.md b/Node-discovery-protocol.md deleted file mode 100644 index f0b9f6f34..000000000 --- a/Node-discovery-protocol.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -name: Node Discovery Protocol -category: ---- - -In a nutshell: -* Aimed at discovering _RLPx nodes_ to connect to -* UDP-based RPC protocol ([kademlia](https://en.wikipedia.org/wiki/Kademlia)-like) -* Defines 4 packet types: _ping_, _pong_, _findnode_ and _neighbors_ - -See details at either: -* [devp2p](https://github.com/ethereum/devp2p) repository's [node discovery protocol](https://github.com/ethereum/devp2p/blob/master/rlpx.md) page -* [go-ethereum](https://github.com/ethereum/go-ethereum) repository's [node discovery protocol](https://github.com/ethereum/go-ethereum/wiki/RLPx-----Node-Discovery-Protocol) page \ No newline at end of file diff --git a/Open-positions-&-Schemes.md b/Open-positions-&-Schemes.md deleted file mode 100644 index fbbdadc61..000000000 --- a/Open-positions-&-Schemes.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -name: Open Positions and Schemes -category: ---- - -### Full-time Roles - -Ethereum has a number of full-time employee roles open. For the Berlin team (concentrating mostly around the C++-based implementation and development tools) you'll be based in Kreuzberg, Berlin in our central office/hub/café location, for the Amsterdam team (concentrating mostly around the Go-based implementation and the consumer software) you'll work remotely for now. Roles include security, optimisation, networking and helping make reality our advanced integrated blockchain development environment. We are presently particularly interested in expanding our team for the latter; if you have good knowledge of the Qt5 platform including QtQuick & QML, then please get in touch with `jobs@ethdev.com`. - -For more information on full time positions, see `TODO: Aeron`. - -### Hub-Invitation Scheme - -If you have been working on an Ethereum/ÐΞV-related project, we would love to hear from you. In addition to helping wherever we can with fixes and advice, for promising non-profit, open-source projects where considerable effort has clearly been invested we would like to invite you to collaborate more closely at one of our holons/hubs. At present there are two operational hubs: - -- **ÐΞV Berlin** in Kreuzberg (Berlin), Germany; -- **ÐΞV Amsterdam** near Museum Plein, Netherlands; -- **Ethereum Suisse** in Zug (near Zurich), Switzerland. - -Such an invitation will include travel costs, a small stipend for food costs during the time and shared accommodation. You will have full access to the hub resources during your stay and be free to work and relax around other members of the local ÐΞV & Ethereum communities. - -Projects that are especially interesting to us are: -- alternative implementations of the protocol in esoteric languages; -- legacy-system (web back-end, but perhaps other frameworks/environments, too) integrations; -- education and adoption tools; -- Ðapps & contracts that do something novel; -- Ðapps & contracts that do something well. - -If you believe you have such a project and would like to come visit us for a while, let us know at `visitus@ethdev.com`! - -### Sponsoring Scheme - -Additionally, for interesting projects, we would like to extend financial support in the form of a small bursary. We consider all such projects, as with the Hub Invitation Scheme. Bursary amounts vary from the $1000s to the $10,000s, depending on the size, scope and outlook of the project. - -If you believe you have such a project let us know at `bursary@ethdev.com`, with a proposal for where you would like to take the project and estimates of any expenses that might be involved in taking it forward. - -### FAQ - -Q. I want to make a client in language XYZ. I haven't started yet but was hoping you'd pay me a full developer's salary to do it. Can I have a job? - -A. No. Our resources do not extend so far. We wish you luck with your endeavour and if you get far would certainly invite you to our collaborative environment in the above scheme. - -Q. I have an idea for a contract/Ðapp/integration/... Could I get some money to fund its development? - -A. Ethereum/ÐΞV is not an accelerator, incubator or investment operation. We only wish to lend a hand (financial and otherwise) to those already engrossed in their project. As such our assistance schemes are open only to those whose already have an established project that is Ethereum-centric. \ No newline at end of file diff --git a/Parallel-Block-Downloads.md b/Parallel-Block-Downloads.md deleted file mode 100644 index 130d71ae9..000000000 --- a/Parallel-Block-Downloads.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -name: Parallel Block Downloads -category: ---- - -New network protocol & strategy. - -### Goals -- Achieve parallel downloads of chain -- Introduce framework that can form basis of Swarm -- Minimise unnecessary block transfers - -### Basic Overview - -- Two peers connect & say Hello. Hello includes the TD & hash of their best block. -- The client with the worst TD asks peer for full chain of just block hashes. -- Chain of hashes is stored in space shared by all peer connections, and used as a "work pool". -- While there are hashes in the chain of hashes that we don't have in our chain: - - Ask for N blocks from our peer using the hashes. Mark them as on their way so we don't get them from another peer. - -### Required Changes - -Network protocol: 33 - -Additional parameters to Hello: -- `TD`: Total Difficulty of the best chain. Integer. -- `BestHash`: The hash of the best (i.e. highest TD) known block. -- `GenesisHash`: The hash of the Genesis block. - -Additional Message types: -- `0x17`: `GetBlockHashes` [ `hash` : `B_32`, `maxBlocks`: `P` ]: Requests a `BlockHashes` message of at most `maxBlocks` entries, of block hashes from the blockchain, starting at the parent of block `hash`. Does not _require_ the peer to give `maxBlocks` hashes - they could give somewhat fewer. -- `0x18`:`BlockHashes` [ `hash_0`: `B_32`, `hash_1`: `B_32`, .... ]: Gives a series of hashes of blocks (each the child of the next). This implies that the blocks are ordered from youngest to oldest. -- `0x19`:`GetBlocks` [ `hash_0`: `B_32`, `hash_1`: `B_32`, .... ]: Requests a `Blocks` message detailing a number of blocks to be sent, each referred to by a hash. Note: Don't expect that the peer necessarily give you all these blocks in a single message - you might have to re-request them. - -Remove Message types: -- `GetChain` -- `NotInChain` \ No newline at end of file diff --git a/Problems.md b/Problems.md deleted file mode 100644 index 7a013aad6..000000000 --- a/Problems.md +++ /dev/null @@ -1,388 +0,0 @@ ---- -name: Problems -category: ---- - -The science of cryptography, which has existed to some degree for millennia but in a formal and systematized form for less than fifty years, can be most simply defined as the study of communication in an adversarial environment. In a similar vein, we can define cryptoeconomics as a field that goes one step further: the study of economic interaction in an adversarial environment. To distinguish itself from traditional economics, which certainly studies both economic interaction and adversaries, cryptoeconomics generally focuses on interactions that take place over network protocols. Particular domains of cryptoeconomics include: - -* Online trust and reputation systems -* Cryptographic tokens / cryptocurrencies, and more generally digital assets -* Self-executing "smart" contracts -* Consensus algorithms -* Anti-spam and anti-sybil attack algorithms -* Incentivized marketplaces for computational resources -* Decentralized systems for social welfare / mutual aid / basic income -* Decentralized governance (for both for-profit and non-profit entities) - -The increasing prominence of cryptoeconomics in the last five years is to a large extent the result of the growth of cryptocurrencies and digital tokens, and brings a new, and interesting, dimension to cryptography. While before cryptography was, by and large, a purely computational and information-theoretic science, with strong guarantees built on security assumptions that are close to absolute, once money enters the picture the perfect world of mathematics must interact with a much more messy reality of human social structures, economic incentives, partial guarantees and known vulnerabilities that can only be mitigated, and not outright removed. While a cryptographer is used to assumptions of the form "this algorithm is guaranteed to be unbreakable provided that these underlying math problems remain hard", the world of cryptoeconomics must contend with fuzzy empirical factors such as the difficulty of collusion attacks, the relative quantity of altruistic, profit-seeking and anti-altruistic parties, the level of concentration of different kinds of resources, and in some cases even sociocultural circumstances. - -In traditional applied cryptography, security assumptions tend to look something like this: - -1. No one can do more than 279 computational steps -2. Factoring is hard (ie. superpolynomial) -3. Taking nth roots modulo composites is hard -4. The elliptic curve discrete logarithm problem cannot be solved faster than in 2n/2 time - -In cryptoeconomics, on the other hand, the basic security assumptions that we depend on are, alongside the cryptographic assumptions, roughly the following: - -1. No set of individuals that control more than 25% of all computational resources is capable of colluding -2. No set of individuals that control more than 25% of all money is capable of colluding -3. The amount of computation of a certain proof of work function that can be accomplished with a given amount of money is not superlinear beyond a point which is reasonably low -4. There exist a non-negligible number of altruists and a non-negligible number of crazies or political opponents of the system, and the majority of users can be reasonably modeled as being close to economically rational -5. The number of users of a system is large, and users can appear or disappear at any time, although at least some users are persistent -6. Censorship is impossible, and any two nodes can send messages to each other relatively quickly. -7. It is trivial to generate a very large number of IP addresses, and one can purchase an unlimited amount of network bandwidth -8. Many users are anonymous, so negative reputations and debts are close to unenforceable - -There will also be additional security assumptions specific to certain problems. Thus, quite often it will not even be possible to definitively say that a certain protocol is secure or insecure or that a certain problem has been solved. Rather, it will be necessary to create solutions that are optimized for particular empirical and social realities, and continue further and further optimizing them over time. - -## Technology - -The decentralized consensus technology used in Bitcoin is impressive to a very large extent because of its simplicity. A 30-year-old problem in computer science was solved via a mechanism which is simple to implement, and so simple to understand that even some semi-technical teenagers can describe the entirety of how it works. However, at the same time the technology in its current form is very limited. The scalability in Bitcoin is very crude; the fact that every full node needs to process every transaction is a large roadblock to the future success of the platform, and a factor preventing its effective use in micropayments (arguably the one place where it is the most useful). Timestamping is flawed, and proof-of-computation algorithms are very limited in the types of computation that they can support. The fact that the original solution was so "easy", however, suggests that there is still a large opportunity to improve, and there are a number of directions in which improvement could be directed. - -### 1. Blockchain Scalability - -One of the largest problems facing the cryptocurrency space today is the issue of scalability. It is an often repeated claim that, while mainstream payment networks process something like 2000 transactions per second, in its current form the Bitcoin network can only process seven. On a fundamental level, this is not strictly true; simply by changing the block size limit parameter, Bitcoin can easily be made to support 70 or even 7000 transactions per second. However, if Bitcoin does get to that scale, we run into a problem: it becomes impossible for the average user to run a full node, and full nodes become relegated only to that small collection of businesses that can afford the resources. Because mining only requires the block header, even miners can (and in practice most do) mine without downloading the blockchain. - -The main concern with this is trust: if there are only a few entities capable of running full nodes, then those entities can conspire and agree to give themselves a large number of additional bitcoins, and there would be no way for other users to see for themselves that a block is invalid without processing an entire block themselves. Although such a fraud may potentially be discovered after the fact, power dynamics may create a situation where the default action is to simply go along with the fraudulent chain (and authorities can create a climate of fear to support such an action) and there is a coordination problem in switching back. Thus, at the extreme, Bitcoin with 7000 transactions per second has security properties that are essentially similar to a centralized system like Paypal, whereas what we want is a system that handles 7000 TPS with the same levels of decentralization that cryptocurrency originally promised to offer. - -Ideally, a blockchain design should exist that works, and has similar security properties to Bitcoin with regard to 51% attacks, that functions even if no single node processes more than `1/n` of all transactions where `n` can be scaled up to be as high as necessary, although perhaps at the cost of linearly or quadratically growing secondary inefficiencies and convergence concerns. This would allow the blockchain architecture to process an arbitrarily high number of TPS but at the same time retain the same level of decentralization that Satoshi envisioned. - -**Problem**: create a blockchain design that maintains Bitcoin-like security guarantees, but where the maximum size of the most powerful node that needs to exist for the network to keep functioning is substantially sublinear in the number of transactions. - -**Additional Assumptions and Requirements**: - -* There exist a large number of miners in the network -* Miners may be using specialized hardware or unspecialized hardware. Specialized hardware should be assumed to be more powerful than unspecialized hardware by a large (eg. 10000) constant factor at specific tasks. -* Ordinary users will be using unspecialized hardware -* Ideally, after some number of blocks (perhaps logarithmic in the total size of the network) every transaction should require 51% of network hashpower to reverse. However, solutions where transactions can pay very small fees for a lower "level" of security are acceptable, though one should take care to avoid situations where an attacker can profit by performing one attack to reverse very many small transactions at the same time -* Ideally, the solution should work for and maintain as many properties as possible of a generalized account-based blockchain (eg. Ethereum), though solutions specific to currency, domain registrations or other specialized use caes are acceptable - -### 2. Timestamping - -An important property that Bitcoin needs to keep is that there should be roughly one block generated every ten minutes; if a block is generated every day, the payment system becomes too slow, and if a block is generated every second there are serious centralization and network efficiency concerns that would make the consensus system essentially nonviable even assuming the absence of any attackers. To ensure this, the Bitcoin network adjusts difficulty so that if blocks are produced too quickly it becomes harder to mine a new block, and if blocks are produced too slowly it becomes easier. - -However, this solution requires an important ingredient: the blockchain must be aware of time. In order to solve this problem, Bitcoin requires miners to submit a timestamp in each block, and nodes reject a block if the block's timestamp is either (i) behind the median timestamp of the previous eleven blocks, or (ii) more than 2 hours into the future, from the point of view of the node's own internal clock. This algorithm is good enough for Bitcoin, because time serves only the very limited function of regulating the block creation rate over the long term, but there are potential vulnerabilities in this approach, issues which may compound in blockchains where time plays a more important role. - -**Problem**: create a distributed incentive-compatible system, whether it is an overlay on top of a blockchain or its own blockchain, which maintains the current time to high accuracy. - -**Additional Assumptions and Requirements** - -* All legitimate users have clocks in a normal distribution around some "real" time with standard deviation 20 seconds. -* No two nodes are more than 20 seconds apart in terms of the amount of time it takes for a message originating from one node to reach any other node. -* The solution is allowed to rely on an existing concept of "N nodes"; this would in practice be enforced with proof-of-stake or non-sybil tokens (see #9). -* The system should continuously provide a time which is within 120s (or less if possible) of the internal clock of >99% of honestly participating nodes. Note that this also implies that the system should be self-consistent to within about 190s. -* The system should exist without relying on any kind of proof-of-work. -* External systems may end up relying on this system; hence, it should remain secure against attackers controlling < 25% of nodes regardless of incentives. - -### 3. Arbitrary Proof of Computation - -Perhaps the holy grail of the study zero-knowledge proofs is the concept of an arbitrary proof of computation: given a program P with input I, the challenge is to create a zero-knowledge proof that you ran P with input I and received output O, such that the proof can be verified quickly (ie. in polylogarithmic or ideally constant time) even if the original computation took a very large number of steps to complete. In an ideal setup, the proof would even hide the value of I, just proving that you ran P with some output with result O, and if I needs to be made public it can be embedded into the program. Such a primitive, if possible, would have massive implications for cryptocurrency: - -1. The blockchain scalability problem would be much easier to solve. Instead of miners publishing blocks containing a list of transactions, they would be publishing a proof that they ran the blockchain state updater with some list of transactions and produced a certain output; thus, instead of transactions needing to be verified by every node in the network, they could be processed by one miner and then every other miner and user could quickly verify the proof of computation and if the proof turns out correct they would accept the new state. This is not a complete solution, because there would still be a need to transmit data, but the problem would be much easier with this powerful building block. -2. The blockchain privacy problem would be much easier to solve. The blockchain scalability solution above would hide the details behind individual transactions; it would only reveal the fact that all of them are legitimate, so transactions would be hidden from everyone but the sender and the receiver. -3. It would become computationally viable to use a Turing-complete consensus network as a generic distributed cloud computing system; if you have any computation you wanted done, you would be able to publish the program for miners and miners would be able to run the program for you and deliver the result alongside a proof of its validity. - -There is a large amount of existing research on this topic, including a protocol known as "SCIP" (Succinct Computational Integrity and Privacy) that is already working in test environments, although with the limitation that a trusted third party is required to initially set up the keys; use of this prior work by both its original developers and others is encouraged. - -**Problem**: create programs `POC_PROVE(P,I) -> (O,Q)` and `POC_VERIFY(P,O,Q) -> { 0, 1 }` such that `POC_PROVE` runs program `P` on input `I` and returns the program output `O` and a proof-of-computation `Q` and `POC_VERIFY` takes `P`, `O` and `Q` and outputs whether or not `Q` and `O` were legitimately produced by the `POC_PROVE` algorithm using `P`. - -**Requirements And Additional Assumptions** - -* The runtime of `POC_PROVE` should be in `O(n*polylog(n))` where `n` is the number of steps required to run the program. -* The runtime of `POC_VERIFY` should be either constant or logarithmic in the number of steps, and at most linear in the maximum memory usage of the program. -* The protocol should require no trusted third parties. If TTPs are required, the protocol should include a mechanism for simulating one efficiently using secure multiparty computation. - -### 4. Code Obfuscation - -For many years now we have known how to encrypt data. Simple, robust and well-tested algorithms exist for both symmetric key encryption, where the same key is needed to encrypt and decrypt, and public key encryption, where the encryption key and decryption key are different and one cannot be derived from the other. However, there is another kind of encryption that can potentially be very useful, but for which we currently have no viable algorithm: the encryption of programs. The holy grail is to create an obfuscator `O`, such that given any program P the obfuscator can produce a second program `O(P) = Q` such that `P` and `Q` return the same output if given the same input and, importantly, `Q` reveals no information whatsoever about the internals of `P`. One can hide inside of `Q` a password, a secret encryption key, or one can simply use `Q` to hide the proprietary workings of the algorithm itself. - -In 2007, it was proven that perfect "black box" encryption is impossible; essentially, the argument is that there is a difference between having black-box access to a program and having the code to that program, no matter how obfuscated, and one can construct certain classes of programs that resist obfuscation. However, there is also a weaker notion of obfuscation, known as indistinguishability obfuscation, that appears to be quite possible. The definition of an indistinguishability obfuscator `O` is that if you take two equivalent (ie. same inputs -> same outputs) programs `A` and `B` and calculate `O(A) = P` and `O(B) = Q`, then there is no computationally feasible way for an outsider without access to `A` or `B` to tell whether `P` came from `A` or `B`. - -This type of obfuscation may seem more limited, but it is nevertheless sufficient for many applications. For a heuristic argument why, consider two programs `F` and `G` where `F` internally contains and simply prints out that 32-byte string which is the hash of "12345", whereas G actually computes the hash of "12345" and prints it out. By the indistinguishability obfuscation definition, there is no computationally feasible way to tell `O(F)` from `O(G)` apart. Hence, if one can feasibly recover "12345" from `O(G)`, then for `O(G)` and `O(F)` to be indistinguishable one would also need to be able to feasibly recover "12345" from `O(F)` - a feat which essentially entails breaking the preimage resistance of a cryptographic hash function. - -Recently, a discovery was made by Craig Gentry, Amit Sahai et al on an algorithm which uses a construction known as "multilinear jugsaw puzzles" in order to accomplish this. Their algorithm, described here, claims to satisfy the indistinguishability obfuscation property, although at a high cost: the algorithm requires the use of fully homomorphic encryption, a highly inefficient construction that incurs roughly a one-billion-fold computational overhead. - -If this construction can be made better, the potential benefits are massive. The most interesting possibility in the world of cryptocurrency is the idea of an on-blockchain contract containing private information. This basically allows for the scripting properties of Turing-complete blockchain technologies, such as Ethereum, to be exported into any other financial or non-financial system on the internet; for example, one can imagine an Ethereum contract which contains a user's online banking password, and if certain conditions of the contract are satisfied the contract would initiate an HTTPS session with the bank, using some node as an intermediary, and log into the bank account with the user's password and make a specified withdrawal. Because the contract would be obfuscated, there would be no way for the intermediary node, or any other player in the blockchain, to modify the request in-transit or determine the user's password. The same trick can be done with any other website, or much more easily with a "dumb" blockchain such as Bitcoin. - -**Problem**: create a reasonably efficient indistinguishability obfuscation algorithm. - -**Additional Assumptions and Requirements** - -* Successful attacks must have an expected runtime above 2^80 -* The algorithm should be sufficiently fast that a standard ECDSA signature or an AES encryption should be feasible within 108 computational steps (more specifically, 108 gas in the Ethereum VM) - -### 5. Hash-Based Cryptography - -One of the looming threats on the horizon to cryptocurrency, and cryptography in general, is the issue of quantum computers. Currently, the problem does not seem too severe; all quantum computers are either "adiabatic quantum computers", effective at only an extremely limited set of problems and perhaps not even better than classical computers at all, or machines with a very small number of qubits not capable of factoring numbers higher than 35. In the future, however, quantum computers may become much more powerful, and the recent revelations around the activities of government agencies such as the NSA have sparked fears, however unlikely, that the US military may control a quantum computer already. With this in mind, the movement toward quantum-proof cryptography has become a somewhat higher priority. - -To date, all quantum-proof schemes fall into one of two categories. First, there are algorithms involving lattice-based constructions, relying on the hardness of the problem of finding a linear combination of vectors whose sum is much shorter than the length of any individual member. These algorithms appear to be powerful, and relatively efficient, but many distrust them because they rely on complicated mathematical objects and relatively unproven assumptions. However, there is also another class of algorithms that are quantum-proof: hash-based algorithms. One example of this is the classic Lamport signature: create a Merkle tree of 164 nodes (a figure chosen specifically to match 160 bits of security), publish the root, and then have the signature of a document be the combined Merkle tree proof of a subset of 82 nodes pseudorandomly chosen based on the hash of the document. This signature is one-time, and bulky (~3000 bytes), but fulfils the purpose. - -The question is, can we do better? There is an approach known as hash ladders, allowing the size of a signature to be brought down to 420 bytes, and one can use Merkle trees on another level to increase the number of signatures possible, although at the cost of adding 100-300 bytes to the signature. However, even still these approaches are imperfect, and if hash-based cryptography is to be competitive the properties of the algorithms will need to be substantially improved in order to have nicer properties. - -**Problem**: create a signature algorithm relying on no security assumption but the random oracle property of hashes that maintains 160 bits of security against classical computers (ie. 80 vs. quantum due to Grover's algorithm) with optimal size and other properties. - -**Requirements And Additional Assumptions** - -* The computational effort of producing a signature should be less than 224 computational steps, assuming a hash takes 28 steps (a reasonable assumption due to hardware optimizations and in the future hashing ASICs built into chips) -* The size of a signature should be as small as possible -* The size of a public key should be as small as possible -* The signature algorithm should be scalable to add any number of uses, although likely at the cost of adding a constant number of bytes per signature for every 2x increase in the maximum number of uses, and if possible the setup time should be sublinear in the number of uses. - -## Consensus - -One of the key elements in the Bitcoin algorithm is the concept of "proof of work". In any Byzantine-fault-tolerant system, the security level is often defined as the minimum percentage of hostile nodes - for example, in the context of secret sharing, the Berlekamp-Welch algorithm with 2x redundancy is guaranteed to provide the correct output assuming that the total number of hostile nodes does not exceed 25% of the network, and in the context of Bitcoin mining the requirement is that the size of the set of honest nodes exceeds the size of any individual hostile coalition. However, all of these security guarantees have one important qualification: there must be some way to define what an individual node is. Before Bitcoin, most fault-tolerant algorithms had high computational complexity and assumed that the size of the network would be small, and so each node would be run by a known individual or organization and so it is possible to count each node individually. - -With Bitcoin, however, nodes are numerous, mostly anonymous, and can enter or leave the system at any time. Unless one puts in careful thought, such a system would quickly run into what is known as a Sybil attack, where a hostile attacks simply creates five times as many nodes as the rest of the network combined, whether by running them all on the same machine or rented virtual private server or on a botnet, and uses this supermajority to subvert the network. In order to prevent this kind of attack, the only known solution is to use a resource-based counting mechanism. For this purpose, Bitcoin uses a scheme known as proof-of-work, which consists of solving problems that are difficult to solve, but easy to verify. The weight of a node in the consensus is based on the number of problem solutions that the node presents, and the Bitcoin system rewards nodes that present such solutions ("miners") with new bitcoins and transaction fees. - -Bitcoin's proof of work algorithm is a simple design known as Hashcash, invented by Adam Back in 1995. The hashcash function works as follows: - - def hashcash_produce(data, difficulty): - nonce = random.randrange(2**256) - while sha256(data + str(nonce)) > 2**256 / difficulty: - nonce += 1 - return nonce - - def hashcash_verify(data, nonce, difficulty): - return sha256(data + str(nonce)) <= 2**256 / difficulty - -Note that in the actual Bitcoin protocol nonces are limited to 32 bits; at higher difficulty levels, one is required to also manipulate transaction data in the block as a sort of "extranonce". - -Originally, the intent behind the Bitcoin design was very egalitarian in nature. Every individual would mine on their own desktop computer, producing a highly decentralized network without any point of control and a distribution mechanism that spread the initial supply a BTC across a wide number of users. And for the first 18 months of Bitcoin's existence, the system worked. In the summer of 2010, however, developers released a Bitcoin miner that took advantage of the massive parallelization offered by the graphics processing unit (GPU) of powerful computers, mining about 10-50 times more efficiently than CPUs. In 2013, specialization took a further turn, with the introduction of devices called "application-specific integrated circuits" - chips designed in silicon with the sole purpose of Bitcoin mining in mind, providing another 10-50x rise in efficiency. CPU and GPU mining are now completely unprofitable, and the only way to mine is to either start a multimillion-dollar ASIC manufacturing company or purchase an ASIC from one that already exists. - -Another related issue is mining pool centralization. Theoretically, the legitimate function of a mining pool is simple: instead of mining on their own and receiving a small chance of earning the block reward of 25 BTC, miners mine for a pool, and the pool sends them a proportionate constant payout (eg. 0.002 BTC per block). There are centralized mining pools, but there are also P2P pools which serve the same function. However, P2P pools require miners to validate the entire blockchain, something which general-purpose computers can easily do but ASICs are not capable of; as a result, ASIC miners nearly all opt for centralized mining pools. The result of these trends is grim. Right now, nearly 25% of all new ASIC hashpower is produced in a single factory in Shenzhen, and nearly 50% of the network is controlled by a single mining pool. - -The second problem is easy to alleviate; one simply creates a mining algorithm that forces every mining node to store the entire blockchain. The first problem, that of mining centralization, is much harder. There is the possibility that the problem will solve itself over time, and as the Bitcoin mining industry grows it will naturally become more decentralized as room emerges for more firms to participate. However, that is an empirical claim that may or may not come to pass, and we need to be prepared for the eventuality that it does not. Furthermore, the wasted energy and computation costs of proof of work as they stand today may prove to be entirely avoidable, and it is worth looking to see if that aspect of consensus algorithms can be alleviated. - -### 6. ASIC-Resistant Proof of Work - -One approach at solving the problem is creating a proof-of-work algorithm based on a type of computation that is very difficult to specialize. One specific ideas involves creating a hash function that is "memory-hard", making it much more difficult to create an ASIC that achieves massive gains through parallelization. This idea is simple, but fundamentally limited - if a function is memory-hard to compute, it is also generally memory-hard to verify. Additionally, there may be ways to specialize hardware for an algorithm that have nothing to do with hyperparallelizing it. Another approach involves randomly generating new mining functions per block, trying to make specialization gains impossible because the ASIC ideally suited for performing arbitrary computations is by definition simply a CPU. There may also be other strategies aside from these two. - -Ultimately, perfect ASIC resistance is impossible; there are always portions of circuits that are going to be unused by any specific algorithm and that can be trimmed to cut costs in a specialized device. However, what we are looking for is not perfect ASIC resistance but rather economic ASIC resistance. Economic ASIC resistance can be defined as follows. First of all, we note that in a non-specialized environment mining returns are sublinear - everyone owns one computer, say with N units of unused computational power, so up to N units of mining cost only the additional electricity cost, whereas mining beyond N units costs both electricity and hardware. If the cost of mining with specialized hardware, including the cost of research and development, is higher per unit hashpower than the cost of those first N units of mining per user then one can call an algorithm economically ASIC resistant. - -For a more in-depth discussion on ASIC-resistant hardware, see [https://blog.ethereum.org/2014/06/19/mining/](https://blog.ethereum.org/2014/06/19/mining/) - -**Problem**: Create two functions, `PoWProduce(data,diff) -> nonce` and `PoWVerify(data,nonce,diff) -> { 0, 1 }`, to serve as alternatives to Hashcash such that it is economically unattractive to produce an ASIC for `PoWProduce` - -**Additional Assumptions And Requirements**: - -* `PoWProduce` must have expected runtime linear in `diff` -* `PoWVerify` must have runtime at most polylogarithmic in `diff` -* Running `PoWProduce` should be the most efficient, or very close to the most efficient, way to produce values that return `1` when checked with `PoWVerify` (ie. no software optimization) -* `PoWProduce` must not be superlinear in computational power or time; that is to say, the expected number of successful `PoWProduce` computations for a node with `N` dollars worth of hardware after `t` seconds should be bounded by `kNt` for some `k`. Furthermore, the linearity should kick in quickly; ie. $1000 worth of mining hardware should function with over 90% efficiency. -* It should be shown with reasonably rigorous technological and economic analysis that the algorithm is economically ASIC resistant. - -### 7. Useful Proof of Work - -Another related economic issue, often pointed out by detractors of Bitcoin, is that the proof of work done in the Bitcoin network is essentially wasted effort. Miners spend 24 hours a day cranking out SHA256 (or in more advanced implementations Scrypt) computations with the hopes of producing a block that has a very low hash value, and ultimately all of this work has no value to society. Traditional centralized networks, like Paypal and the credit card network, manage to get by without performing any proof of work computations at all, whereas in the Bitcoin ecosystem about a million US dollars of electricity and manufacturing effort is essentially wasted every day to prop up the network. - -One way of solving the problem that many have proposed is making the proof of work function something which is simultaneously useful; a common candidate is something like Folding@home, an existing program where users can download software onto their computers to simulate protein folding and provide researchers with a large supply of data to help them cure diseases. The problem is, however, that Folding@home is not "easy to verify"; verifying the someone did a Folding@home computation correctly, and did not cut corners to maximize their rounds-per-second at the cost of making the result useless in actual research, takes as long as doing the computation oneself. If either an efficiently verifiable proof-of-computation for Folding@home can be produced, or if we can find some other useful computation which is easy to verify, then cryptocurrency mining could actually become a huge boon to society, not only removing the objection that Bitcoin wastes "energy", but even being socially beneficial by providing a public good. - -Note that there is one major concern with this approach that has been identified: if the useful PoW is implemented incorrectly, it can potentially reduce the cost of an attack on the network. If the useful PoW is useful in such a way that it is sometimes economically viable for certain very large entities to perform the computation even without the currency incentive, then those entities have an incentive to launch attacks against the network at no cost, since they would be performing the computations anyway. One simple, though crude and imperfect, way of addressing this problem is to make the PoW a half-and-half mix between useful and useless, making the cost of an attack at least 50% of what it would be in a useless-PoW environemnt. In practice, the overhead of making PoW verifiable may well introduce over 2x inefficiency unintentionally. Another economic solution is to make the computation a "pure" public good such that no individual entity derives a significant benefit from it. Proposed solutions to this problem should include a rigorous analysis of this issue. - -**Problem**: Create two functions, `PoWProduce(data,diff) -> nonce` and `PoWVerify(data,nonce,diff) -> { 0, 1 }`, to serve as alternatives to Hashcash such that the outputs of `PoWProduce` are independently useful. - -**Requirements** - -* `PoWProduce` must have expected runtime linear in `diff` -* `PoWVerify` must have expected runtime at most polylogarithmic in `diff` -* Running `PoWProduce` should be the most efficient way to produce values that return `1` when checked with `PoWVerify` -* `PoWProduce` must not be superlinear in computational power or time; that is to say, the expected number of successful `PoWProduce` computations for a node with `N` dollars worth of hardware after `t` seconds should be bounded by `kNt` for some `k`. Furthermore, the linearity should kick in quickly; ie. $1000 worth of mining hardware should function with over 90% efficiency. -* `PoWProduce` must produce a public good, such that the total value to everyone of the public good produced is greater than the cost of all resources invested into the mining process. -* The system must be able to exist without a trusted third party, but it is reasonable to allow a trusted third party to serve as a data source for useful computations. If the trusted third party acts maliciously in any way, the public good may be negated but the blockchain mining should not be compromised. - -### 8. Proof of Stake - -Another approach to solving the mining centralization problem is to abolish mining entirely, and move to some other mechanism for counting the weight of each node in the consensus. The most popular alternative under discussion to date is "proof of stake" - that is to say, instead of treating the consensus model as "one unit of CPU power, one vote" it becomes "one currency unit, one vote". - -A very simple proof of stake algorithm requires the miner mining the block to sign it with the private key to the address holding their coins, where the block is valid if `sha256(PREVHASH + ADDRESS + TIMESTAMP) <= 2^256 * BALANCE / DIFFICULTY` where `PREVHASH` is the hash of the previous block, `ADDRESS` is the signer's address with balance `BALANCE`, `TIMESTAMP` is the current Unix time in seconds and `DIFFICULTY` is an adjustable parameter to regulate the frequency of successful signatures. At first glance, this algorithm has the basic required properties: every miner has some random chance per second of succeeding, and if your address has twice as much money in it then you have double the chance of success. - -However, this algorithm has one important flaw: there is "nothing at stake". In the event of a fork, whether the fork is accidental or a malicious attempt to rewrite history and reverse a transaction, the optimal strategy for any miner is to mine on every chain, so that the miner gets their reward no matter which fork wins. Thus, assuming a large number of economically interested miners, an attacker may be able to send a transaction in exchange for some digital good (usually another cryptocurrency), receive the good, then start a fork of the blockchain from one block behind the transaction and send the money to themselves instead, and even with 1% of the total stake the attacker's fork would win because everyone else is mining on both. - -Another problem to keep in mind is the issue of so-called "long-range attacks" - attacks where the miner attempts to start a fork not five or ten blocks behind the head of the main chain, as happens normally, but hundreds of thousands of blocks back. If an algorithm is designed incorrectly, it may be possible for an attacker to start from that far back, and then mine billions of blocks into the future (since no proof of work is required), and new users would not be able to tell that the blockchain with billions of blocks more is illegitimate. This can generally be solved with timestamping, but special corner cases do tend to appear in overcomplicated designs. - -The Slasher algorithm, described [here](http://blog.ethereum.org/2014/01/15/slasher-a-punitive-proof-of-stake-algorithm/) and implemented by Zack Hess as a proof-of-concept [here](https://github.com/zack-bitcoin/slasher), represents my own attempt at fixing the nothing-at-stake problem. The core idea is that (1) the miners for each block are determined ahead of time, so in the event of a fork a miner will either have an opportunity to mine a given block on all chains or no chains, and (2) if a miner is caught signing two distinct blocks with the same block number they can be deprived of their reward. The algorithm is viable and effective, but it suffers from two flaws of unknown significance. First, if all of the miners for a given block learn each other's identities beforehand, they can meet up and collude to shut down the network. Second, the nothing-at-stake problem remaing for attacks going back more than 3000 blocks, although this is a smaller issue because such attacks would be very obvious and can automatically trigger warnings. - -For a more in-depth discussion on proof of stake, see [https://blog.ethereum.org/2014/07/05/stake/](https://blog.ethereum.org/2014/07/05/stake/) - -**Problem**: create a proof-of-stake algorithm that solves the nothing-at-stake problem and long-range attack problems, without introducing new collusion risks that require less than 25% of stakeholders to succeed. - -**Additional Requirements And Assumptions** - -* The expected return from mining should be bounded by `k` times the miner's stake for some `k`, and assuming $1 billion total participating stake a stake of $1000 should be able to reach 90% of this maximum efficiency. -* The algorithm should be fully incentive-compatible, addressing the double-voting issue defined above and the collusion issue defined above at both short and long range. - -### 9. Proof of Storage - -A third approach to the problem is to use a scarce computational resource other than computational power or currency. In this regard, the two main alternatives that have been proposed are storage and bandwidth. There is no way in principle to provide an after-the-fact cryptographic proof that bandwidth was given or used, so proof of bandwidth should most accurately be considered a subset of social proof, discussed in later problems, but proof of storage is something that certainly can be done computationally. An advantage of proof-of-storage is that it is completely ASIC-resistant; the kind of storage that we have in hard drives is already close to optimal. - -The most simple algorithm for proving that you own a file with `N` blocks is to build a Merkle tree out of it, publish the root, and every `k` blocks publish a Merkle tree proof of the `i`th block where `i` is the previous block hash mod `N`. However, this algorithm is limited because it is only a simple building block, not a complete solution. In order to turn this into a currency, one would need to determine which files are being stored, who stores whose files, to what extent and how the system should enforce redundancy, and if the files come from the users themselves how to prevent compression optimizations and long-range attacks. - -Currently, the latest work in this area are two projects called Permacoin and Torcoin, which solve some of the problems in proof of storage with two insights. First, users should not be able to choose which files they store. Instead, files should be randomly selected based on their public key and users should be required to store ALL of the work assigned or else face a zero reward. This idea, provided in the context of proof of bandwidth in the case of Torcoin, prevents attacks involving users only storing their own data. Second, a Lamport-like signature algorithm can be used that requires users to have their private key and store their file locally; as a result; uploading all of one's files to the cloud is no longer a viable strategy. This, to some degree, forces redundancy. - -However, the problem with Permacoin is that it leaves unclear what files should be stored; cryptocurrency issuance can theoretically pay for billions of dollars of work per year, but there is no single static archive whose storage is worth billions. Ideally, the system would allow for new files to be added, and perhaps even allow users to upload their own files, but without introducing new vulnerabilities. - -**Problem**: create a currency that uses proof-of-storage as its consensus and distribution algorithm. - -**Additional Assumptions And Requirements** - -* The currency must be future-proof, being able to expand the amount of data stored over time; the system should not eventually fall into some failure state if hard disk space continues to get cheaper and more efficient. -* The currency should ideally be maximally useful. At the least, the currency should allow people to upload their own files and have them stored, providing an uploading network with minimal cryptographic overhead, although ideally the currency should select for files that are public goods, providing net total value to society in excess of the number of currency units issued. -* The expected return from mining should be at most slightly superlinear, ie. it must be bounded by `ks/(1-s)` for some `k`, where `s` is the miner's share of the total network, although perfect linearity is ideal. -* The system should be maximally resistant against mining pool centralization as a result of any small degree of superlinearity. -* The system should be secure against nothing-at-stake and long-range attacks. -* The system should be secure against attacker involving users uploading specially formatted files or storing their own data. - -## Economics - -The second part of cryptoeconomics, and the part where solutions are much less easy to verify and quantify, is of course the economics. Cryptocurrencies are not just cryptographic systems, they are also economic systems, and both kinds of security need to be taken into account. Sometimes, cryptographic security may even be slightly compromised in favor of an economic approach - if a signature algorithm takes more effort to crack than one could gain from cracking it, that is often a reasonable substitute for true security. At the same time, economic problems are also much more difficult to define. One cannot usually definitively know whether or not a problem has been solved without extensive experimentation, and the result will often depend on cultural factors or the other organizational and social structures used by the individuals involved. However, if the economic problems can be solved, the solutions may often have reach far beyond just cryptocurrency. - -### 10. Stable-value cryptoassets - -One of the main problems with Bitcoin is the issue of price volatility. The value of a bitcoin often experiences very large fluctuations, rising or falling by as much as 25% in a single day and 3x in a month. The main economic reason behind this is that the supply of bitcoins is fixed, so its price is directly proportional to demand (and therefore, by efficient market hypothesis, the expected discounted future demand), and demand is very unpredictable. It is not known if Bitcoin will be simply a niche payment method for transcations requiring a high degree of privacy, a replacement for Western Union, a mainstream consumer payment system or the reserve currency of the world, and the expected value of a bitcoin differs over a thousandfold between these various levels of adoption. Furthermore, the utility of the Bitcoin protocol is heavily dependent on the movements of the Bitcoin price (ie. people are interested in Bitcoin more if the price is going up), creating a positive feedback loop, which has arguably been responsible for both Bitcoin's great meteoric rises and its many-month-long periods of rapid decline. - -To solve this problem, there are generally two paths that can be taken. The first is to have the network somehow detect its current level of economic usage, and have a supply function that automatically increases supply when usage increases. This reduces uncertainty; even though the expected future level of adoption of the protocol may have a variance of 10-100x, the circumstance where adoption increases 100x will also have 100x more supply and so the value of the currency will remain the same. There is a problem that if usage decreases there is no way to remove units from circulation, but even still the lack of upward uncertainty should reduce upward volatility, and downward volatility would also naturally reduce because it is no longer bad news for the value of the currency when an opportunity for increased usage is suddenly removed. Furthermore, in the long term the economy can be expected to grow, so the zero-supply-growth floor may not even ever be reached in practice. - -The problem is that measuring an economy in a secure way is a difficult problem. The most obvious metric that the system has access to is mining difficulty, but mining difficulty also goes up with Moore's law and in the short term with ASIC development, and there is no known way to estimate the impact of Moore's law alone and so the currency cannot know if its difficulty increased by 10x due to better hardware, a larger user volume or a combination of both. Other metrics, such as transaction count, are potentially gameable by entities that want the supply to change in a particular direction (generally, holders want a lower supply, miners want a higher supply). - -Another approach is to attempt to create a currency which tracks a specific asset, using some kind of incentive-compatible scheme likely based on the game-theoretic concept of Schelling points, to feed price information about the asset into the system in a decentralized way. This could then be combined with a supply function mechanism as above, or it can be incorporated into a zero-total-supply currency system which uses debts collateralized with other cryptographic assets to offset its positive supply and thus gain the ability to grow and shrink with changes to usage in either direction. The problem here is constructing the scheme in such a way that there is no incentive for entities to feed in false price information in order to increase or decrease the supply of the asset in their favor. - -**Problem**: construct a cryptographic asset with a stable price. - -**Requirements** - -* The expected root-mean-square daily change in the logarithm of the price of the asset should be less than 25% of that of Bitcoin under similar conditions. Ideally, the asset should be guaranteed to almost always maintain a value within 10% of an arbitrary cryptographic or real-world asset for which price information is easily accessible -* The expectation analysis should take into account black swan risks (ie. systems where the variance is 0% 99% of the time but 10x in a day the other 1% of the time are unacceptable) -* The solution must come with a model, including parameters such as short-term-consumption purchases, medium-term purchases, speculative purchases, positive and negative media, adoption and regulatory events, irrational actors and actors with political motives, show that their model well fits the history of Bitcoin and potentially major altcoins without overfitting, and show that under the model the other two requirements hold -* Zero-total-supply assets, ie. assets where each unit is balanced by a collateralized debt of a unit, are allowed, although such systems must include a robust margin-calling mechanism because it is assumed that most users are anonymous and can therefore trivially run away from debts - -### 11. Decentralized Public Goods Incentivization - -One of the challenges in economic systems in general is the problem of "public goods". For example, suppose that there is a scientific research project which will cost $1 million to complete, and it is known that if it is completed the resulting research will save one million people $5 each. In total, the social benefit is clear: if everyone contributes $1, then each individual person will see a benefit of $5 - $1 = $4 for $4 million total. However, the problem is that from the point of view of each individual person contributing does not make sense - whether or not you contribute has close to zero bearing on whether enough money will be collected, so everyone has the incentive to sit out and let everyone else throw their money in, with the result that no one does. - -So far, most problems to public goods have involved centralization; some large organization, whether a big company or a government, agrees to offer some of its private services only to those individuals who participate in paying for the public good. Often this is done implicitly: for example, some of the money from each purchase of an iPad goes toward research and development (some of which is a public good, and some of which is an excludable "club good"). At other times, it's more explicit, as in the case of taxation. In order for decentralized economic systems (we'll refer to decentralized economic systems that somehow rely on cryptography and/or cryptocurrency as "cryptoeconomic systems") to be effective, ways of incentivizing production of public goods relevant to that system are required. A few possible approaches include: - -* **Assurance contracts** - the idea behind an assurance contract is that `N` people may or may not put their funds into a pool, where that pool pays to produce a public good if and only if at least $X in total is contributed. Otherwise, the pool pays everyone back. If the pool creator acts optimally, the tipping point will be right at the top of the bell curve that is the probability distribution for how much other people might contribute, meaning that the chance that one user with their contribution of `X/N` will be pivotal should, by central limit theorem, approach `~1/sqrt(N)`, creating a `sqrt(N)`-sized amplifying effect on their donation. -* **Dominant assurance contracts** - a special type of assurance contract, called a dominant assurance contract, involves an entrepreneur that pays all contributors back slightly more than 100% of what they put in if the fund fails to reach its target (and takes profits if the fund succeeds); this provides an incentive for someone to create optimally targeted assurance contracts. -* **Currency issuance** - a cryptoeconomic system can contain its own currency or token system which is somehow necessary or useful in some part of the system. These currency units can then either be generated by the system and then sold or directly assigned to reward contribution. This approach gets around the free-rider problem because no one needs to pay the $1 explicitly; the value arises out of the emergent value of the network which is does not cost people to support. -* **Status goods issuance** - a status good can be defined as a good that confers only relative benefit to its holder and not absolute benefit to society; for example, you may stand out in the public if you wear an expensive diamond necklace, but if everyone could trivially obtain such a necklace the situation would be very similar to a world with no diamond necklaces at all. A cryptoeconomic system can release its own status goods, and then sell or award them. One example of a status good is a "badge"; some online forums, for example, show a special badge beside users that have contributed funds to support the forum's development and maintenance. Another important example of a status good is a namespace; for example, a decentralized messaging protocol may be able to fund itself by selling off all of the 1-4 letter usernames. -* **Recursive rewarding** - this is in some ways a mirror image of the concept of "recursive punishment" that arguably underlies a large number of social protocols. For example, consider the case of tax-funded police forces. In natural circumstances, there often arise opportunities to take actions which are beneficial to the perpetrator, but ultimately harmful to society as a whole (eg. theft). The most common solution to this problem is punishment - an act which is harmful in itself, but which shifts the incentives so that attacking is no longer beneficial to the perpetrator. However, there is a problem: there is no incentive to participate in the punishment process. This is solved by making punishment obligatory, with non-participation (in modern society by paying taxes) itself punishable by the same mechanism. Recursive rewarding is a mirror image of this strategy: here, we reward a desirable action, and people who partivipate in the rewarding mechanism (eg. by giving reward recipients a discount in shops) are themselves to be rewarded. - -Many of these approached can arguably be done in concert, or even simultaneously within one mechanism. - -**Problem**: come up with and implement methods for incentivizing public goods production in a decentralized environment. - -**Additional Assumptions And Requirements** - -* A fully trustworthy oracle exists for determining whether or not a certain public good task has been completed (in reality this is false, but this is the domain of another problem) -* The agents involved can be a combination of individual humans, teams of humans, AIs, simple software programs and decentralized cryptographic entities -* A certain degree of cultural filtering or conditioning may be required for the mechanism to work, but this should be as small as possible -* No reliance on trusted parties or centralized parties should be required. Where some kind of "supernode" role does exist, the protocol should provide a way for anyone to participate in that function with a mechanism for rewarding those who do it well -* The mechanism should ideally be able to handle both public goods which everyone values and public goods which are only valued by a small portion of the population (eg. the production of a freely available book or video on a specific topic) - -### 12. Reputation systems - -A concept which can arguably be considered to be a mirror image of currency is a reputation system. A reputation system serves three functions. First of all, it provides a mechanism for filtering honest people from dishonest people. Different people have different moral preference profiles, and so individuals who cheat less in one context are less likely to cheat in another context. Second, it provides an incentive not to cheat. If an individual can be said to possess a reputation of value `R`, and he enters a business deal where he is receiving payment `V` in exchange for a product with cost-of-production `C`, then as long as `R > C` the reputation system removes the incentive to run away with the money because doing so would sacrifice the reputation. Finally, reputation can be thought of as a kind of point system that people value intrinsically, both in a private context and as a status good in comparison with others. - -Money serves functions that are very similar. People who are willing to spend more money on something tend to want it more, creating a filtering function ensuring efficient resource consumption on the demand side. It provides an incentive not to cheat by consuming and not producing, because if you do so your remaining currency units and thus ability to consume in the future will go down. And finally, it is also very much an intrinsically valued point system; in fact, some argue that among very wealthy individuals this function of money is dominant. - -However, there are also differences. First, money is an absolute score - I have X units of currency C from the point of view of everyone in the world - but reputation is a relative measure, depending on both the owner of the reputation and the observer. I may have a high reputation in North America, a near-zero reputation in Africa, and a negative reputation among certain kinds of antitechnologist and ultranationalist groups. Second, reputation is free to give; it does not cost me anything to praise you, except potentially moral liability that I may incur if you turn out to act immorally in some way. This is in contrast with money, where adding X units to A means subtracting X units from B. - -However, up until very recently, reputation has been a very informal concept, having no concept of score and instead relying entirely on individual opinion. Because opinion is relatively easy to manipulate, this means that reputation as a concept has been highly suboptimal in its implementation, and has been quite vulnerable to informational and psychological attacks. Some specific problems are: - -1. How do we know how what the value of someone's reputation with someone else is after a particular number of interactions? A common attack on informal reputation systems is the "long con" - act honestly but passively and cheaply for a very long time, accumulate trust, and then suddenly go all out and destructively capitalize on one's reputation as much as possible. The initial dormant phase is cheap for the attacker, but ends up resulting in the attacker accumulating a disproportionately large amount of trust for the community and thereby ultimately causing much more damange than good. Overcompensate for this too much, however, and there ends up being no opportunity to gain trust. -2. How do we incorporate secondary trust? In general, when `A` is deciding whether or not to trust `B`, `A` has not had any prior dealings with `B`, and therefore has no way of knowing whether or not `B` is trustworthy. One approach is to just look at all ratings for `B`, but then we run into the issue of Sybil attacks: what if `B` creates 50000 fake users, all of whom rate each other highly, to give good ratings to him? To solve this problem, reputation systems rely on a fallback known as a web of trust: find some chain of people `P[1] ... P[k]` such that `A` trusts `P[1]`, `P[i]` trusts `P[i+1]` for all `i`, and `P[k]` trusts `B`. Under the "six degrees of separation hypothesis", any two people in the world except those completely disconnected from society have such a chain of maximum length `k = 5` (so at most six hops total). However, the question arises, if `A` has a certain rating for `P[1]` and `P[1]` has a certain rating for `B`, what should the reputation system recommend to `B`? -3. If a reputation system becomes more formalized, are there market attacks that reduce its effectiveness to simply being just another form of money? Specifically, how would a reputation system where giving reputation is free handle users multiplying their reputation with millions of "I praise you if you praise me" trades? Will such trades need to be explicitly banned, punishable by loss of reputation, or is there a better solution? -4. How do we deal with double use attacks? Specifically, suppose that `A` has a reputation with value `R = $1000`. Using this reputation, `A` has a business dealing where `P[1]` trusts her for $600. Then, she simultaneously engages in such a dealing with `P[2], P[3] ... P[10]`, each of whom individually believe that `A` will not betray them since $600 < $1000, and then runs away with $6000 taking the $1000 hit from the value of her reputation. How do we prevent such fractional reserve-like scenarios? - -**Problem**: design a formalized reputation system, including a score `rep(A,B) -> V` where `V` is the reputation of `B` from the point of view of `A`, a mechanism for determining the probability that one party can be trusted by another, and a mechanism for updating the reputation given a record of a particular open or finalized interaction. - -Note that for the purpose of this use case we are targeting specifically the "can I trust you" use case of reputation, and not the social-incentivizing "[whuffie](https://en.wikipedia.org/wiki/Whuffie)"-esque currency-like aspect. - -**Additional Assumptions and Requirements** - -* The system has access to a record of all finalized transactions inside the system and all transactions in progress, although entities are of course able to choose to make deals outside the system -* It is allowed to introduce mechanisms like charity donations, public goods provision and sacrifices as a way of increasing one's reputation. However, if non-monetary contributions are allowed, there needs to be some mechanism for measuring their value -* For simplicity, we can assume that interactions between two people are of the form "A pays, then B sends the product and A receives", with no possibility for loss beyond the principal (eg. food poisoning) or ambiguous quality. Ideally, however, the system should account for such possibilities. -* The system should continue to be reasonably accurate whether the parties involved are simple programs (eg. micropayment software protocols), more complicated AIs, DAOs, individual humans or human centralized or decentralized organizations -* If a mechanism is provided for determining the probability of a successful interaction, a success metric for the system can be defined as the sum over all transactions of `V * (S * log(p) - (1-S) * log(1-p))`, where `S = 1` if the transaction succeeded and `S = 0` if there was a registered complaint, `p` is the assigned probability and `V` is the value of the transaction. The objective is to maximize this metric. - -## Metrics - -In the world of cryptoeconomics, in order for something to be rewarded it must be measured. Some things are easy to measure; for example, just by looking at the string "dog5356356" and its SHA256 hash, `0000390f327fefc900...`, one can clearly see that around 216 SHA256 computations were done to produce it. Other computational results that cannot be verified so quickly can be easily measured competitively using challenge-response protocols, where different parties are incentivized to find errors in each other's proofs. Results to mathematical problems are also usually easy to computationally verify. Other things, however, cannot be verified just by looking them; in that case, in both the real world and the cryptographic world, there is only one solution: social proof. - -To some extent, proof of work consensus is itself a form of social proof. Transaction A happened before transaction B because the majority of users say it did, and there is an economic incentive to go with the majority opinion (specifically, if you generate a block on the incorrect chain, that block will get discarded and the miner will receive no reward). Assuming that most participants act truthfully, the incentive is to go along with the projected majority and tell the truth as well. This insight can be extended into [SchellingCoin](http://blog.ethereum.org/2014/03/28/schellingcoin-a-minimal-trust-universal-data-feed/), a generalized data feed protocol, protocols for proof of bandwidth, and anything else that can be quickly verified. The challenge is, however, what if verification has a cost? What if it takes some effort to determine whether or not a certain thing has happened, or what if the information is in principle only available to a few people? If there is too much gathering cost or secrecy, then centralization becomes necessary; the question is, how high can we go? How much can we measure without any social proof at all, and how much can we measure without a centralized verifier? - -### 13. Proof of excellence - -One interesting, and largely unexplored, solution to the problem of distribution specifically (there are reasons why it cannot be so easily used for mining) is using tasks that are socially useful but require original human-driven creative effort and talent. For example, one can come up with a "proof of proof" currency that rewards players for coming up with mathematical proofs of certain theorems. There is no generic algorithm, aside from brute force, for proving theorems, and yet proofs of theorems are theoretically computationally easy to verify: one simply needs to write every step of the proof in a formal language, allowing the use of only one inference rule (eg. `a + b = b + a` or `a * (b + c) = a * b + a * c` but not `a * (b + c) = a * c + b * a`) between each step, and having a program verify the correctness of the inferences at each step. - -For example, a proof of a common algebraic factorization problem appears as follows: - - a^2 - b^2 - = a^2 - a*b + a*b - b^2 - = a*a - a*b + a*b - b^2 - = a*(a - b) + a*b - b^2 - = a*(a - b) + a*b - b*b - = a*(a - b) + b*a - b*b - = a*(a - b) + b*(a - b) - = (a + b)*(a - b) - -Each step of the proof can be verified using pattern matching algorithms, but it is much harder for a computer to figure out that the trick is to add and subtract `a*b` into the expression (technically, in this case specialized algorithms can do it, but in more general cases especially involving second-order logic it becomes intractable). Note that for computers the proof must be written down in excruciating detail; blockchain-based algorithms specifically heavily benefit from simplicity. To alleviate this problem, compilers can likely be made that can make small two and three-step inferences and expand shorter proofs into more complete ones. - -Alternatives to proof-of-proof include proof-of-optimization, finding optimal inputs to some function to maximize a particular output (eg. the ability of a radio antenna to receive signals), algorithms involving playing strategy games or multiplayer AI challenges (one can even require users to submit programs to the blockchain that play against each other), and solving a specific math problem at greater and greater difficulty (eg. factoring). Note that because success in these problems is very sporadic, and highly inegalitarian, one cannot use most of these algorithms for consensus; rather, it makes sense to focus on distribution. - -**Problem**: create a proof-of-excellence distribution mechanism that rewards solving problems that are both dominated by human effort and whose solutions provide some benefit to humanity. - -**Additional Assumptions and Requirements** - -* Given a well-justified extrapolation of the global levels of human and computer competence at the underlying problem, over 75% of the rewards from the system should be provided by human labor, although software aids are allowed. -* The algorithm must ideally be future-proof; that is to say, it must continue rewarding value production in the long term and should not be an area that will eventually be "solved" completely. -* The distribution should be maximally egalitarian, though this is a secondary concern. -* The system should be secure against front-running attacks, ie. if an individual submits a solution, then it should not be practical for even a moderately powerful attacker to look at the solution and then resubmit his own transaction containing the same solution and thereby steal the reward. - -### 14. Anti-Sybil systems - -A problem that is somewhat related to the issue of a reputation system is the challenge of creating a "unique identity system" - a system for generating tokens that prove that an identity is not part of a Sybil attack. The naive form of anti-Sybil token is simple: a sacrifice or proof of deposit. In a sacrifice setup, such identities simply cost $X, and in a PoD system identities require a deposit of $Y in order to be active, where perhaps the deposit can be taken away or destroyed under certain circumstances. However, we would like to have a system that has nicer and more egalitarian features than "one-dollar-one-vote"; arguably, one-person-one-vote would be ideal. - -To date, we have seen two major strategies for trying to solve this problem. One potential solution is to come up with a proof-of-work algorithm which is dominated by human labor, and not computers. This is not as difficult as it may seem; although computers get more and more powerful every year, there are a number of problems that have remained out of computers' reach for decades, and it may even be possible to identify a class of problems that are the artificial-intelligence-theoretic equivalent of "NP-complete" - problems such that, if they can be solved, it with high probability implies that AI can essentially replicate human activity in its entirety, in which case we are essentially in a post-scarcity utopia and money and incentivization may not even be necessary. These problems may be non-interactive challenges like CAPTCHAs, although all existing CAPTCHAs are far from adequate for the task, or they may be interactive strategy games like Go. - -The second strategy is to use social proof, turning the muscle of decentralized information gathering toward a simple problem: are these two identities the same person? If they are not, then they receive two anti-Sybil tokens, and if they are they receive one token. In general, we can separately define two concepts of identity: voluntary identity and involuntary identity. A voluntary identity can be seen as a cluster of interactions which are in some fashion correlated with each other; for example, a cryptographic identity consists of the set of interactions signed by a particular public key. An involuntary identity is a cluster of interactions which are correlated with each other, but where the entity producing the interactions does not want the correlations to be visible. A simple unique identity system would rely on voluntary identities embedded in social networks, with the understanding that creating separate identities with reputations is an expensive task and so most people would not want to do it, but a more advanced system may try to detect involuntary slipups like writing style patterns or IP addresses. - -The question is, can we use these mechanisms, either separately or together, and perhaps in combination with cryptoeconomic protocols and sacrifices as a fallback in order to create an anti-Sybil system which is highly egalitarian? We will accept that any scheme can be cracked at some cost; however, what we want is for it to be much more efficient for individuals to obtain _one_ anti-Sybil token "the proper way" rather than purchasing one off the grey/black market. The challenge is to push the grey/black market cost as high as possible, as much as possible without making the first token difficult. - -**Problem** - create a mechanism for distributing anti-Sybil tokens - -**Additional Assumptions and Requirements**: - -* Everyone is part of a social network with similar characteristics to social networks now found in the real world, and social data can be provably provided to cryptoeconomic systems (eg. blockchains, Ethereum contracts) -* The cost of obtaining one anti-Sybil token for a human should be as low as possible -* The cost of obtaining multiple anti-Sybil tokens for a human should be as high as possible -* The cost of obtaining anti-Sybil tokens for an automated system should be as high as possible (this is a more important criterion than high cost for multi-obtainment for humans) -* The system should not create dependency on centralized parties (eg. government passport offices) that have the power to cheat the system - -### 15. Decentralized contribution metrics - -Incentivizing the production of public goods is, unfortunately, not the only problem that centralization solves. The other problem is determining, first, which public goods are worth producing in the first place and, second, determining to what extent a particular effort actually accomplished the production of the public good. This challenge deals with the latter issue. Although in the case of computational tasks it's easy to come up with a proof of solution, for non-computational tasks the situation is much more difficult. If a cryptoeconomic system wants to incentivize users to build better graphical user interfaces to its own system, how would it rate people's contributions? [Even more problematically](http://en.wikipedia.org/wiki/Underhanded_C_Contest), what about potentially quasi-adversarial tasks like incentivizing updates to its own code? What about a DAO that funds healthcare, or tries to incentivize adopting renewable energy? - -This is a subclass of the general "social proof" problem; here, the particular challenge is that each individual datum in question is something that very few people are interested in, and data gathering costs are often high. Sometimes, there is not even a concept of a single "correct" value with respect to the particular metric; in the case of quality measurement for an interface, a solution like A/B testing may be required. In adversarial cases, there may need to be an opportunity for incentivized opponents to look at a solution and attempt to pick it apart. - -**Problem**: come up with and implement a decentralized method for determining whether or not a particular task was performed by a specific person, and for estimating the quality of the work - -**Additional Assumptions and Requirements** - -* The agents involved can be a combination of individual humans, teams of humans, AIs, simple software programs and other DAOs -* There is no cryptographically verifiable information about the completion of any task; the system must rely entirely on some form of social proof - -### 16. Decentralized success metrics - -Another, related, problem to the problem of decentralized contribution metrics is the problem of decentralized success metrics. On the macroscopic scale, how do we know if, and to what extent, an organization has succeeded in accomplishing its objectives? In the case of something like Bitcoin, there is a simple, but imperfect, answer: success can be measured by the hashpower of the network. This setup is reasonably effective, but is flawed in two ways: first, hashpower is an imperfect proxy for price, because the development or nondevelopment of ASICs may skew the results, and second, price is an imperfect proxy for success, because the currency may have greater success as something with a lower market capitalization if it is more used in other ways. In the case of a DAO funding healthcare or anti-climate-change efforts, however, no such heuristic exists at all. Once again, some concept of social proof is the only option. - -Here, information gathering costs are low, and information is accessible to everyone in the public, so a higher level of accuracy is possible, hopefully even enough for financial contracts based off of the metric to be possible. However, in order to maintain that higher level of accuracy, and in the presence of such financial derivatives, new problems arise. Can one moderately powerful entity manipulate the metric for their own benefit? If information gathering costs do exist, is the system vulnerable to falling into a centralized equilibrium, where everyone is incentivized to simply follow along with the actions of some specific party? - -**Problem**: come up with and implement a decentralized method for measuring numerical real-world variables - -**Additional Assumptions and Requirements** - -* The agents involved can be a combination of individual humans, teams of humans, AIs, simple software programs and other DAOs -* The system should be able to measure anything that humans can currently reach a rough consensus on (eg. price of an asset, temperature, global CO2 concentration \ No newline at end of file diff --git a/Proposal:-BlockHashesFromNumbers.md b/Proposal:-BlockHashesFromNumbers.md deleted file mode 100644 index f67fbc158..000000000 --- a/Proposal:-BlockHashesFromNumbers.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: BlockHashesFromNumbers Proposal -category: ---- - -# Problem - -During initial synchronization to a large blockchain downloading block hashes can take significant time. Current protocol does not allow parallel hashes downloading. Hashes can be requested sequentially up the chain, making it impossible to start blocks downloading until all of the hashes up to the known hash or genesis are received. A malicious peer can feed an infinite hash chain. Currently it is not straightforward to protect against such an attack as there is no additional information on the number of hashes. The only strategy is to estimate a reasonable number of hashes using current date, genesis date and average block time, and then reject the peer after downloading that many hashes. - -# Solution - -There should be a way to request a list of hashes by the block number. This will allow parallel downloading, starting block downloading and validation immediately after receiving first hashes, rejecting malicious peers right away. - -# Specification - -1. Introduce a new packet: `BlockHashesFromNumber`, into the slot `+0x08` (new). - -**BlockHashesFromNumber** -[`+0x08`: `P`, `number`: `P`, `maxBlocks`: `P`] -Requests a BlockHashes message detailing a number of the first block hash and a total of hashes to be sent. Returned hash list must be ordered by block number in ascending order. diff --git a/Proposal:-Extend-GetBlockHashes-with-target-hash.md b/Proposal:-Extend-GetBlockHashes-with-target-hash.md deleted file mode 100644 index c5758e84b..000000000 --- a/Proposal:-Extend-GetBlockHashes-with-target-hash.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -name: Extend GetBlockHashes With Target Hash Proposal -category: ---- - -# Problem - -The current protocol specification does not provide the means to mitigate an infinite chain feeding attack. A malicious peer can make up arbitrary blocks on the fly, and feed their hashes indefinitely to a target, without ever linking to the existing chain. This will result in an eventual memory exhaustion and crash. The root cause is that the protocol provides no means to validate any blocks, without first pulling the entire hash chain. - -# Solution - -Peers should be able to request hashes not only backwards towards the genesis block, but forward too to some specific target hash. This would allow the downloader to start pulling actual blocks and verify them concurrently with fetching the hashes. If no peers (including the hash provider) has the blocks to back up the hashes, the chain is rejected. - -This forward synchronization strategy requires the capacity to locate a common ancestor block to our blockchain and that of a remote peer in order to know the joining point from which to request the hashes. This can be facilitated with the same mechanism by doing a binary search on our blockchain, requesting 1xhashes from the remote (towards its advertised head) side to see if it knows about it or not, honing in on the common ancestor. - -# Specification - -1. Extend `GetBlockHashes` packet with an additional field: - - **GetBlockHashes** [`+0x03`: `P`, `srcHash`: `B_32`, `targetHash`: `B_32`, `maxBlocks`: `P`] - * `targetHash`: The endpoint in a remote blockchain towards which to retrieve hashes - -2. Modify `BlockHashes`'s returned hash order: - - * Adhere to that requested by `GetBlockHashes`, opposed to the current "hard coded" young -> old ordering - -The benefit of this proposal is that beside providing the means to do forward syncing, it retains the capacity to implement the currently specified reverse fetch behavior by passing the genesis block's hash to `targetHash`. This way Ethereum implementations don't have to immediately devise a new downloader strategy to cope with the update, but can function as they are until ready to evolve. - -# Supersedes - -[[Proposal: BlockHashesFromNumbers]] - -The main issue the `BlockHashesFromNumbers` set out to resolve was the slow download of hashes (which was stalling the synchronization), by introducing parallel fetches based on height/block-number based hash retrievals. It also inherently provided a mechanism to limit the number of potentially invalid hashes downloaded to that of the current chain's height. - -The current proposal however approaches the challenge from the opposite direction. By downloading hashes towards the end of a chain - after the first hash delivery - blocks can be immediately retrieved in parallel (compared to which hash downloads are insignificant in size and hence latency), so there is no need for the added complexity and potential issues with parallelizing hash downloads. Additionally, by limiting the number of pending hashes, we can also prevent any infinite chain attacks. - -Given that the current proposal addresses all of the issues `BlockHashesFromNumbers` aimed to fix, while being much less invasive (requires the addition of single packet field); is gracefully compatible with previous protocol implementations (they can continue to function without an algorithm update); and implementation wise is straightforward and easy to reason about; we believe it is a superior proposal. - -### Critique - -- Closer to the present protocol than `BlockHashesFromNumbers`. -- Less general and expansive than `BlockHashesFromNumbers`: it is designed for a very particular strategy and is less likely to be adaptable to future, unknown strategies. -- Does not support parallel hash-chain downloading alongside forward hash-chain downloading (`BlockHashesFromNumbers` supports both). -- Somewhat more complex in terms of semantics: - - The notion of a series of hash going from a source hash to a destination hash is found nowhere else in the protocol or codebase. Exchanging number to/from hash is already found in the API. - - Not immediately clear with edge cases (e.g. if from is genesis and to is leaf, or if from doesn't exist in the chain but leaf does, or vice-versa). `BlockHashesFromNumbers` is well-defined under all circumstances. -- Somewhat more complex in terms of implementation; how to efficiently determine the fork point or common ancestor? `BlockHashesFromNumbers` would make it trivial with a binary chop. diff --git a/Proposal:-NewBlockHashes.md b/Proposal:-NewBlockHashes.md deleted file mode 100644 index 83ebdf613..000000000 --- a/Proposal:-NewBlockHashes.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -name: NewBlockHashes Proposal -category: ---- - -# Problem - -Block propagation is slow. This is partly due to the problematic strategy decision of either sending out a new block to all peers (costly in terms of bandwidth, especially when considered at the network level where most nodes will receive a block from most of their peers) or send a new block to a randomly selected subset of peers (making worst-case propagation times substantial). - -# Solution - -Much better would be a low-bandwidth full propagation of the hash. All nodes would receive a hash for each new block from most of their peers (peers who have demonstrated knowledge of the hash would not be notified). However, the block itself would need only be transferred once per node. - -# Specification - -Introduce a new packet: `NewBlockHashes`, into the slot `+0x01` (original taken by `GetTransactions`, which is not defunct). - -**NewBlockHashes** -[`+0x01`: `P`, `hash1`: `B_32`, `hash2`: `B_32`, `...`] Specify one or more new blocks which have appeared on the network. Including hashes that the sending peer could reasonable be considered to know that the receiving node is aware of is considered Bad Form, and may reduce the reputation of the sending node. Including hashes that the sending node later refuses to honour with a proceeding `GetBlocks` message is considered Bad Form, and may reduce the reputation of the sending node. - - diff --git a/Proposal:-Reversion-Notification.md b/Proposal:-Reversion-Notification.md deleted file mode 100644 index ecff74482..000000000 --- a/Proposal:-Reversion-Notification.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -name: Reversion Notification Proposal -category: ---- - -## **JSONRPC** changes: - -`eth_getFilterChanges`, `eth_getFilterLogs` both return additional fields: "type" and "polarity" - -- `type`: `STRING` - `pending` when the log is pending. `mined` if log is already mined. -- `polarity`:`BOOL` - either `true` (the transaction pertaining to this log was mined or arrived as pending compared to the previous notification/notified block) or `false` (the transaction pertaining to this log was reverted or was deleted compared to the previous notification/notified block). - -```diff -// Result -{ - "id":1, - "jsonrpc":"2.0", - "result": [{ - "logIndex": "0x1", // 1 - "blockNumber":"0x1b4" // 436 - "blockHash": "0x8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcfdf829c5a142f1fccd7d", - "transactionHash": "0xdf829c5a142f1fccd7d8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcf", - "transactionIndex": "0x0", // 0 - "address": "0x16c5785ac562ff41e2dcfdf829c5a142f1fccd7d", - "data":"0x0000000000000000000000000000000000000000000000000000000000000000", -+ "type":"mined", -+ "polarity": true, - "topics": ["0x59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a5"] - },{ - ... - }] -} -``` - -- logs order - -logs should be returned in order, from earliest to latest. - -In case of fork, the order should be following: - -``` -// -// ......1 - 2 - 3a - 4a -// ...............\- 3b - 4b - 5b -// -// getLogs({fromBlock: 4a, toBlock: 5b}) should return -// 4a, 3a, 3b, 4b, 5b -// -``` - - - -## **JSONRPC** new methods: - -- `eth_newFilterEx` (new version of `eth_newFilter`) -- `eth_getLogsEx` (new version of `eth_getLogs`) - -They expect 'fromBlock', 'toBlock' to be block hash instead of block number. - -```diff -params: [{ -- "fromBlock": "0x1", -+ "fromBlock": "0x599438826541d3e8c29c167fa15b491d91b65e422f8b8a3da69eaa9a43c832e1", -- "toBlock": "0x2", -+ "toBlock": "0x599438826541d3e8c29c167fa15b491d91b65e422f8b8a3da69eaa9a43c832e1", - "address": "0x8888f1f195afa192cfee860698584c030f4c9db1", - "topics": ["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b"] -}] -``` - -- `eth_getFilterChangesEx` (new version of `eth_getFilterChanges`) -- `eth_getFilterLogsEx` (new version of `eth_getFilterLogs`) - -`eth_getFilterChangesEx` && `eth_getFilterLogsEx` have the same input params as `eth_getFilterChanges` && `eth_getFilterLogs`, but different format of returned objects. - -``` -// Result -{ - "id":1, - "jsonrpc":"2.0", - "result": [{ - "blockNumber":"0x1b4" // 436 - "blockHash": "0x8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcfdf829c5a142f1fccd7d", - "type": "pending", - "polarity": true, - "logs": [{ - "logIndex": "0x1", // 1 - "transactionHash": "0xdf829c5a142f1fccd7d8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcf", - "transactionIndex": "0x0", // 0 - "address": "0x16c5785ac562ff41e2dcfdf829c5a142f1fccd7d", - "data":"0x0000000000000000000000000000000000000000000000000000000000000000", - "topics": ["0x59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a5"] - },{ - ... - }], - },{ - ... - }] -} -``` - - -## Comments: - -**Fabian**: I like it but i would change three things: - -1. `polarity: true` -> `invalidated: true` or `invalid: true` -2. get rid of the old filter and add `eth_newFilterEx` as `eth_newLogFilter`, to make it fit the other filter type names (`eth_newBlockFilter`, `etH_newPendingTransactionFilter`) -3. Don't return logs grouped by blocks, as i don't see an advantage besides that it is harder to parse. (Logs don't really care in which block they came, though we need to add the `blockX` properties for reference) \ No newline at end of file diff --git a/Proposal:-Transaction-Proxy-Hooks.md b/Proposal:-Transaction-Proxy-Hooks.md deleted file mode 100644 index 09e59b2eb..000000000 --- a/Proposal:-Transaction-Proxy-Hooks.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -name: Transaction Proxy Hooks Proposal -category: ---- - -## Requirements - -Need an abstraction mechanism to allow ÐApps like the Wallet provide their services in an integrated manner without compromising the neutrality of the browser or placing undue burden on third-party ÐApp developers to support them. - -## Basic Design - -The ethereum.js interface may be utilised to allow the ÐApp client to register itself as the transaction handler for each of a number of accounts; in doing so it will provide an additional callback. - -This is done through one addition to the ethereum.js `web3.eth` object, `registerProxyTransactor`: - -``` -var addresses = []; -// TODO: populate addresses - -function f(tx) { - // tx includes tx.from, tx.to, tx.data, tx.value, tx.gasPrice, tx.gas - // and is *exactly* the same as what was passed to eth.transact, but probably not in this - // JS environment. - // tx.from is guaranteed to be an element of addresses. - // TODO: do something -} - -web3.eth.registerProxyTransactor(addresses, f); -``` - -That's the entire JS API. - -In terms of JSON-RPC, there must be an alteration to `eth_accounts`: rather than just including the accounts that we have the secret key for (and that the user has accepted are valid for this dapp to use and know about), all accounts passed as the first argument to `registerProxyTransactor` should also be contained (with the same safeguards as per user acceptance). - -There are also two additional calls in the JSON-RPC; one for polling the status of whether any transactions are waiting to be signed by our callback that we registered as the second argument of `registerProxyTransactor`, and one for letting the core know that our ethereum.js object is capable of proxying transactions sent from the addresses passed as the first argument of `registerProxyTransactor`. - -The first is `eth_registerAddressHandler`; it takes one argument which is an array of addresses and returns an integer identifier. Any otherwise unsignable transactions whose from address is included in this array should be, at some time later, returned to this session as a result of polling the RPC function `eth_checkProxyTransactions`. - -`eth_checkProxyTransactions` takes one argument - the previous integer identifier and returns an array of transactions, each of the form that are passed to `web3.eth.transact`. - -### Core - -Cores must maintain queues of proxy transactions together with sets of addresses, one each per ethereum.js `web3.eth` object (identified through the integer returned to `eth_registerAddressHandler` and provided by `eth_checkProxyTransactions`). These transactions are to be returned to the session via `eth_checkProxyTransactions`. They are to be filled whenever an `eth_transact` is called (from any session) with a `from` address that is contained in the corresponding set of proxyable addresses. - - -### Notes - -If it's called twice, all previous state associated with it is replaced. If two ethereum.js `web3.eth` objects both try to handle the same address, the first one wins and the second silently fails. - -NatSpec messages should be shown for all transactions, ideally only a single ultimate user action required for any given high-level transaction. E.g.: - -- Send 56 ether to `Dave - 0x56789123` from account `Gav's Bank Account - 0x12345678`. -- Wallet ÐApp handling account `Gav's Bank Account - 0x12345678` requests authorisation to conduct the above through: Message from `Gav - 0x34343455` to `Gav's Bank Account - 0x12345678` to: Send 56 ether to `Dave - 0x56789123`. - -The first NatSpec line just corresponds to the first bare and impossible-to-sign transaction from a contract. The second is the actual transaction that will be signed, stating that Gav (the account for which we have a secret key), would sign a transaction instructing the wallet to send the funds. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 000000000..88a20a570 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +Please use [wiki/wiki](https://github.com/ethereum/wiki/wiki) since that is freely editable by anyone, rather than needing to maintain this repo. \ No newline at end of file diff --git a/RPC-Testing.md b/RPC-Testing.md deleted file mode 100644 index 7032858d8..000000000 --- a/RPC-Testing.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -name: RPC Testing -category: ---- - -``` -{ - blockchain: [ - { - difficulty: 1024, - transactions: [ - ... - ] - }, - ] -} -``` \ No newline at end of file diff --git a/Raspberry-Pi-instructions.md b/Raspberry-Pi-instructions.md deleted file mode 100644 index 6d86d36c5..000000000 --- a/Raspberry-Pi-instructions.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -name: Raspberry Pi Instructions -category: ---- - -## Get the "everything-is-ready" image for your Raspberry Pi 2 -Download from: http://gav.ethdev.com/ArchLinuxEthereum12082015.img.zip -(it's 2.4 GB in size, if you want to save bandwidth, go and build it yourself, see instructions below) - -Unzip it and follow those guidelines to copy the image to your sd card: https://www.raspberrypi.org/documentation/installation/installing-images/ - -Plugin the sd card, LAN connection and the power supply and lets start! - -In order to connect to your pi follow those instructions: https://www.raspberrypi.org/documentation/remote-access/ssh - -Currently there are two users, `root` and `pi`. -The passwords are `root` and `raspberry`, respectivly. The first thing you should do is change that. Otherwise everyone can see your IP in netstats and just log into your Raspberry Pi. -Log in and type `passwd ` to update the password for each user. - - - -Currently the go client (geth) and the cpp client (eth) are preinstalled. You can find instruction on how to use them here: https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options and here: https://github.com/ethereum/cpp-ethereum/wiki/Using-Ethereum-CLI-Client. But executing eth/geth with `--help` will give you more up-to-date information on how to use them. -Also eth-netstats is installed. You can find instructions in how to use it here: https://github.com/ethereum/wiki/wiki/Network-Status. -It is used to display your client on the centralized network server (http://stats.ethdev.com/). -In order to give your client a different name, choose your favorite command line text editor and change the `INSTANCE_NAME` parameter in `~/eth-net-intelligence-api/app.json` to whatever you like. - -For convenience there is `startClientWithNetstat.sh` script (execute it with bash) which starts the client and registers it on eth-netstats. -(Note: Downloading the chain takes several hours up to a day, during that time the Raspberry Pi is so busy that netstats doesn't work properly, it may even crash. You may not see your client on netstats until the download is complete. If you don't see you client after one complete day, try a reboot and execute the script again.) - -For updating the clients you can just do `bash updateClient.sh` (this may take a while and may not work, since it is pulling current develop. Dependencies have changed). - -## Resize your system to use large sd cards - -The image is for a 8GB sd card. It allocates 2 GB as swap (needed for compiling and mining :-) ). If your sd card is larger than 8GB, then follow those instructions: - -As root execute -``` -fdisk /dev/mmcblk0 -``` - -Delete the third partition: -``` -d -3 -``` - -Create a new primary partition and use default sizes prompted. This will then create a partition that fills the disk. -``` -n -p -3 -enter -enter -``` -Save and exit fdisk: -``` -w -``` - -Now reboot (`reboot`). Once rebooted: -``` -resize2fs /dev/mmcblk0p3 -``` - -That's it, now you are using all the disk space available. -This has been tested on the Raspberry Pi 2 only. - -## Just get the binaries - -Alternativly, you can use the linux system of your choice and and get the arm binaries here: -* https://build.ethdev.com/builds/ARM%20Go%20develop%20branch/geth-ARM-latest.tar.bz2 (go) -* \ (cpp-ethereum) - -## Build it yourself -If you want to build all that yourself, you can do so following those instructions: - -We start with a ArchLinux system with 2 GB swap. Instructions on how to get there can be found here: -http://archlinuxarm.org/forum/viewtopic.php?f=60&t=8366 - -### go-ethereum -[Installation instructions for ARM](https://github.com/ethereum/go-ethereum/wiki/Installation-Instructions-for-ARM) - -### cpp-ethereum -First we install all necessary libaries as described here https://github.com/ethereum/cpp-ethereum/wiki/Building-on-ArchLinux (but without the qt libs): - -These are the required packages from the official repositories: -``` -sudo pacman -Sy -sudo pacman -S base-devel cmake scons clang llvm boost leveldb crypto++ jsoncpp -``` - -These are packages that you can get from the [AUR(Arch User Repositories)](https://aur.archlinux.org/). I would suggest using [yaourt](https://wiki.archlinux.org/index.php/yaourt) or any other of the [AUR helpers](https://wiki.archlinux.org/index.php/AUR_helpers). - -``` -yaourt -S argtable libjson-rpc-cpp -``` - -Yaourt can be installed by doing this: - -``` -curl -O https://aur.archlinux.org/packages/pa/package-query/package-query.tar.gz -tar -xvzf package-query.tar.gz -cd package-query -makepkg -si - -cd .. -curl -O https://aur.archlinux.org/packages/ya/yaourt/yaourt.tar.gz -tar -xvzf yaourt.tar.gz -cd yaourt -makepkg -si -``` -#### Building the client - -The instructions for building the client from here and on are identical with Ubuntu so the reader should refer to the [relevant page](https://github.com/ethereum/cpp-ethereum/wiki/Building-on-Ubuntu#choose-your-source). but use `cmake .. -DBUNDLE=minimal -DETHASHCL=0 -DEVMJIT=0` instead. - -Resources: - -http://archlinuxarm.org/forum/viewtopic.php?f=60&t=8366 -http://archlinuxarm.org/forum/viewtopic.php?f=31&t=3119 -https://github.com/ethereum/cpp-ethereum/wiki/Building-on-ArchLinux \ No newline at end of file diff --git a/Readme.md b/Readme.md deleted file mode 100644 index 6e4b622fe..000000000 --- a/Readme.md +++ /dev/null @@ -1,14 +0,0 @@ -Newcomers and those seeking an introduction to Ethereum may go to https://ethereum.org or https://github.com/ethereum/wiki/wiki. - -Note that you can proofread while you read and learn about anything. - -# Contribution guidelines -Please just **edit the pages in the wiki directly** as shown in the sidebar here: https://github.com/ethereum/wiki/wiki, rather than making **pull requests**. - -Please only create an **issue** if you can't fix it by editing yourself, and only if it is related to the wiki. If it is a technical issue e.g. with [web3 or JSON.RPC](https://github.com/ethereum/web3.js/issues), [geth](https://github.com/ethereum/go-ethereum/issues), [Mist](https://github.com/ethereum/mist) (although note that Mist isn't really user-ready yet, so using alternatives like [MyEtherWallet](https://www.myetherwallet.com/) is recommended instead), etc., please post an issue in the repo for that project as well, and reference the issue that you create in this repo (by copying and pasting the link to the issue in this repo in a comment in the issue in the relevant project repo). - -If you are **translating** an article, please **create a new page** and create the translation in that. Do not edit an existing article by translating it. Someone did this with the home wiki, changing the title, and this actually caused the home page to just direct to a list of pages in the wiki, and made it hard to find the edited home page as the title was changed to Arabic. So **do not edit the title of an article**. - -If you have experience with editing on Wikipedia, then that will help with knowing how to edit this wiki, although the contribution rules are less strict. Referencing facts is a key writing and proofreading task, as well as checking that information is up-to-date (and updating it if otherwise), correcting grammar, typos, and spelling; and making the wiki comprehensive and easy to understand. - -Other rules, such as a neutral point of view and no original research are desirable, but may be hard to maintain. Notability is less relevant. diff --git a/Registrar-ABI.md b/Registrar-ABI.md deleted file mode 100644 index 06c577036..000000000 --- a/Registrar-ABI.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -name: Registrar ABI -category: ---- - -### Registrar - -Read-only interface that all registrars must implement - -#### Javascript -``` -var Registrar = web3.eth.contract([{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"name","outputs":[{"name":"o_name","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"owner","outputs":[{"name":"o_owner","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"content","outputs":[{"name":"o_content","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"addr","outputs":[{"name":"o_address","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"subRegistrar","outputs":[{"name":"o_subRegistrar","type":"address"}],"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"}],"name":"Changed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"addr","type":"address"}],"name":"PrimaryChanged","type":"event"}]); -``` - -#### Solidity -``` -contract Registrar{function name(address _owner)constant returns(bytes32 o_name){}function owner(bytes32 _name)constant returns(address o_owner){}function content(bytes32 _name)constant returns(bytes32 o_content){}function addr(bytes32 _name)constant returns(address o_address){}function subRegistrar(bytes32 _name)constant returns(address o_subRegistrar){}} -``` - -### GlobalRegistrar - -`GlobalRegistrar` is the main name registration object. The global registrar object on the PoC-9 testnet is at address `0xc6d9d2cd449a754c494264e1809c50e34d64562b`. - -#### Javascript -``` -var GlobalRegistrar = web3.eth.contract([{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"name","outputs":[{"name":"o_name","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"content","outputs":[{"name":"","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"addr","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"reserve","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"subRegistrar","outputs":[{"name":"o_subRegistrar","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_newOwner","type":"address"}],"name":"transfer","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_registrar","type":"address"}],"name":"setSubRegistrar","outputs":[],"type":"function"},{"constant":false,"inputs":[],"name":"Registrar","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_a","type":"address"},{"name":"_primary","type":"bool"}],"name":"setAddress","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_content","type":"bytes32"}],"name":"setContent","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"disown","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"register","outputs":[{"name":"","type":"address"}],"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"}],"name":"Changed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"addr","type":"address"}],"name":"PrimaryChanged","type":"event"}]); -``` - -#### Solidity - -``` -contract GlobalRegistrar{function name(address _owner)constant returns(bytes32 o_name){}function owner(bytes32 _name)constant returns(address ){}function content(bytes32 _name)constant returns(bytes32 ){}function addr(bytes32 _name)constant returns(address ){}function reserve(bytes32 _name){}function subRegistrar(bytes32 _name)constant returns(address o_subRegistrar){}function transfer(bytes32 _name,address _newOwner){}function setSubRegistrar(bytes32 _name,address _registrar){}function Registrar(){}function setAddress(bytes32 _name,address _a,bool _primary){}function setContent(bytes32 _name,bytes32 _content){}function disown(bytes32 _name){}function register(bytes32 _name)constant returns(address ){}} -``` - -### OwnedRegistrar - -OwnedRegistrar fill the same interface as Registrar but allows a single owner complete authority over its contents. - -#### Javascript - -``` -var OwnedRegistrar = web3.eth.contract([{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"name","outputs":[{"name":"o_name","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"owner","outputs":[{"name":"o_owner","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"getAddress","outputs":[{"name":"o_owner","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"content","outputs":[{"name":"","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"addr","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"subRegistrar","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"getName","outputs":[{"name":"o_name","type":"bytes32"}],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_registrar","type":"address"}],"name":"setSubRegistrar","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"record","outputs":[{"name":"o_primary","type":"address"},{"name":"o_subRegistrar","type":"address"},{"name":"o_content","type":"bytes32"}],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_a","type":"address"},{"name":"_primary","type":"bool"}],"name":"setAddress","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_content","type":"bytes32"}],"name":"setContent","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"disown","outputs":[],"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"}],"name":"Changed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"addr","type":"address"}],"name":"PrimaryChanged","type":"event"}]); -``` - -#### Solidity -``` -contract OwnedRegistrar{function name(address _owner)constant returns(bytes32 o_name){}function owner(bytes32 _name)constant returns(address o_owner){}function getAddress(bytes32 _name)constant returns(address o_owner){}function content(bytes32 _name)constant returns(bytes32 ){}function addr(bytes32 _name)constant returns(address ){}function subRegistrar(bytes32 _name)constant returns(address ){}function getName(address _owner)constant returns(bytes32 o_name){}function setSubRegistrar(bytes32 _name,address _registrar){}function record(bytes32 _name)constant returns(address o_primary,address o_subRegistrar,bytes32 o_content){}function setAddress(bytes32 _name,address _a,bool _primary){}function setContent(bytes32 _name,bytes32 _content){}function disown(bytes32 _name){}} -``` \ No newline at end of file diff --git a/Security-Categorization.md b/Security-Categorization.md deleted file mode 100644 index 5f4f16898..000000000 --- a/Security-Categorization.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -name: Security Categorization -category: ---- - -See also: [https://github.com/ethereum/wiki/wiki/Design-Rationale](https://github.com/ethereum/wiki/wiki/Design-Rationale), for descriptions of potentially counterintuitive design decisions in Ethereum. - -The purpose of this document is to attempt to create a taxonomy of key security properties that we are targeting for the Ethereum protocol, implementation and materials to have at launch time, as well as provide supplementary information where needed for each one. - -### Yellow Paper - -* Paper is free of typos and mathematical and grammatical errors -* The definitions in the paper are clear and unambiguous - * Pay particular attention to external dependencies, eg. the definition of secp256k1 -* In places where the formal definition deviates drastically from all commonly used intuitive definitions, clear explanations are provided - -### Proof of Work - -The working spec description of Dagger Hashimoto is available at [https://github.com/ethereum/wiki/wiki/Ethash](https://github.com/ethereum/wiki/wiki/Ethash) - -The algorithm is intended to have the following key properties: - -* ASIC resistance (ie. lowest possible ASIC speedup coefficient) -* Light-client verifiability, in <1s on Python or Javascript on a desktop or C++ on a Raspberry Pi - -And should not have any of the following flaws: - -* High centralization risk (ie. unboundedly superlinear return) -* Possibility of superior "complex" software implementations (eg. as in SAT solving) -* Cheap evasion of memory hardness (due to light-client verifiability considerations, a low-memory implementation must exist, but this should not be a practical way of mining, and hybrid reduced-memory implementations should also be uneconomical) -* Outright trivial attack (eg. the underlying function is actually polytime invertible) -* Pool resistance -* If pools are going to happen, p2pools should be a viable option - -### Block algorithm - -A simulator of difficulty adjustment is available at https://github.com/ethereum/economic-modeling/blob/master/diffadjust/blkdiff.py . - -The modified GHOST algorithm is defined [here](https://github.com/ethereum/wiki/wiki/White-Paper#modified-ghost-implementation). - -The following properties are desired: - -* The difficulty adjustment should update quickly to increasing or decreasing hashpower and should not be maliciously gameable in any sense. -* The 12 second block time + GHOST should not have perverse incentives (ie. it should be optimal to mine on the head) -* The 12 second block time should not induce an excessively high orphan rate and higher confirmation times than expected. -* Ethereum should remain reasonably light-client friendly, especially for low-power IoT (patch solution if necessary: block skiplists, eg. every block with number % n^k == 0 must refer to the block n^k blocks ago, for say n = 4 and k = 0...3; this basically entails turning prevhash into an array) -* Blockchain bloat: blocksize too big to incentivize new full nodes. Will it be dynamically adjusted? If so, also rogue miners attack to bloat the blockchain -* It should be expensive to generate incentives not to mine on the best chain using baits inside of smart contracts - -### Gas economics - -* The floating gas limit should achieve the compatibility objectives described in https://github.com/ethereum/wiki/wiki/White-Paper#fees -* There should not exist a way for a transaction to get itself executed and spend large amounts of computational resources on many nodes without paying for gas - * The following is an example vulnerability: a miner can create a transaction A that spends a very large amount of gas (eg. ~gaslimit * 0.99) running useless computation. That miner then creates a transaction B with the same nonce that has no effect, and tries to mine a block containing B. If a miner produces a block containing B, it broadcasts A, forcing all other nodes on the network to waste time processing A, even though A actually getting accepted is nearly impossible since B is already published in a block. -* There should not be any kind of of perverse incentive in the way gas costs work on the high level (eg. how gas is passed from parent to child message, how gas is refunded, exception reversions, etc) -* Storage gas refund mechanism should not be exploitable -* The operation gas costs should match the cost of running the operation at least complexity-theoretically (ie. there should be no way of causing O(n^2) computational load with O(n) gas). - * An n*log(n) vulnerability against `JUMP`s in the JIT VM is known, but is deemed not sufficiently catastrophic to worry about - * An example prior vulnerability in PoC6 was that since `CALLDATACOPY` always cost 1 gas, you could incur n^2 computational load with n `CALLDATACOPY` instructions on n bytes of memory (ie. O(n) gas) - * A good implementation of `CALL` and `CREATE` should never actually copy memory to produce call data. Otherwise, it will be vulnerable to a quadratic execution attack where a contract runs CALL n times on n bytes of memory, causing n^2 computational load on O(n) gas - * The return data of a `CALL` is not a source of a quadratic execution vulnerability because the `RETURN` opcode expands memory in each inner call, thereby costing `n` memory expansion gas `n` times. -* Expanding the amount of data stored in the state should cost at least 5 gas per byte in all cases -* There should not exist some operations are much more expensive to execute per unit gas than others, leading to a high "multiplicative griefing factor". Note that this is not a primary concern for security audits; we will perform profiles of each operation ourselves later on in order to set gas costs optimally. - -### VM - -* The VM implementation and the formal specifications (so called Yellow Paper) should be equivalent. The VM implementation can be found at https://github.com/ethereum/go-ethereum/tree/master/vm -* The VM should be resistant to the following attack scenarios: - * Transactions/messages whose execution will somehow escape the VM and either reveal or modify memory or hard drive contents of the client's machine - * Transactions/messages whose execution will cause a system crash - * Transactions/messages that could be processed differently by different machines - * Transactions/messages that have a much higher execution time / gas cost ratio than most others, opening the door to a denial-of-service attack - -### Wire protocol - -The wire protocol is described here: https://github.com/ethereum/wiki/wiki/%C3%90%CE%9EVp2p-Wire-Protocol - -The wire protocol should be secure against the following issues: - -* Node isolation against the block spread algorithm -* Single account transaction paralelism ratio due to nonce validation in peers (vs DoS prevention) -* Sequences of wire messages that would lead to the recipient spending a very large amount of time responding to them -* Sequences of wire messages that would lead to the recipient storing a large amount of data -* Sequences of wire messages that would lead to the recipient storing data that is specifically crafted to make data structures blow up (eg. sending transactions with hashes in sequence in order to make trees very very deep) - * Any third party software, e.g. leveldb would also fall under this scrutiny - e.g. what kind of tree is leveldb? Is it vulnerable to such DoS attacks? -* Messages that would fingerprint the target - -### JS / RPC - -* Check that there are no exploits in the Javascript API, JSON-RPC API -* Define a security model for browser+js bindings. (-or give nathan@leastauthority.com a link to an existing doc.) - -### Libraries - -* Leveldb - * Check for hidden limits in leveldb and other libraries that might trigger inconsistent failures outside the VM, similar to http://bitcoinmagazine.com/3668/bitcoin-network-shaken-by-blockchain-fork/ -* Crytopgraphic libraries - * secp256k1 with a Go bridge (https://github.com/obscuren/secp256k1-go) - * A fork of the official golang sha3 package (https://github.com/obscuren/sha3) (Reason for using a sha3 fork is because the official sha3 has switched to FIPS-202 which Ethereum can't use because genesis addresses have been generated using an earlier version of sha3) - * Official ripemd package (code.google.com/p/go.crypto/ripemd160) - -### Non-Audit security-related product wishlist: - -* How-to write secure contracts -* How-to write secure html+js front-ends diff --git a/Security-Issue-Process.md b/Security-Issue-Process.md deleted file mode 100644 index 30695b60b..000000000 --- a/Security-Issue-Process.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -name: Security Issue Process -category: ---- - -Draft of steps that should be taken when finding a security issue in Ethereum. Security issue is defined as a problem in scope of [Security-Categorization](https://github.com/ethereum/wiki/wiki/Security-Categorization). - -Partly inspired by [OWASP Risk Rating](https://www.owasp.org/index.php/OWASP_Risk_Rating_Methodology) - -### Documentation - -* Add a entry describing the issue at (TODO: github link). -* Estimate likelihood, impact and complexity of fix. -* Affected software version(s). - -### Estimate Likelihood - -* How likely is it to be uncovered and exploited by an attacker? -* Ease of discovery? -* Ease of exploit? -* Likelihood of detection? - -### Estimate Impact - -* Blockchain consensus. Potential of blockchain fork? -* Financial damage. Loss of ether? -* Privacy. E.g. revealing who sent a tx or who owns an address. -* Availability. Can it impact availablity of node(s)? - -### Technical description - -* Protocol version. -* Client version(s). Single or multiple implementations? -* OS / external library version(s). -* Link to relevant source code. -* How to fix. -* How to test. - -### Ownership / Responsibility - -* Who is assigned to fix the issue? -* Who will test / review a fix? -* Who takes responsibility for preparing new builds of client software? - -### Disclosure - -* Who takes on to disclose the issue? -* Communication channels (mail lists, twitter, github). diff --git a/Serenity_Wishlist.md b/Serenity_Wishlist.md deleted file mode 100644 index ee3f9dd20..000000000 --- a/Serenity_Wishlist.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -name: Serenity Wishlist -category: ---- - -This document outlines known flaws and missing features in Ethereum Frontier and Homestead that are non-serious but inconvenient, and which we decided to leave in in order to be able to launch in any reasonable timeframe. We intend to thoroughly investigate solving all of these issues for Serenity (aka. Ethereum 1.1). - -### Big Issues - -1. Because every user must process every transaction (ie. the per-user required quantity of storage is linear in the number of users or level of usage), Ethereum is currently fundamentally unscalable, as are all other blockchain technologies to date. We believe this to be the single largest problem in blockchain development, and it will be our primary focus for either Serenity or a version soon after. -2. Proof of work is an extremely expensive means of maintaining consensus and produces substantial negative externalities due to environmental issues and to a lesser degree principal-agent issues, and its security guarantees are uncomfortably incomplete (eg. it is vulnerable to [P + epsilon attacks](https://blog.ethereum.org/2015/01/28/p-epsilon-attack/) or even outright bribes of fairly low size). We plan to resolve this via proof of stake, which resolves these issues via a combination of proof of stake and subjective resolution-of-last-resort. A small amount of proof of work may remain as an anti-DDoS measure. - -### Trie - -In the process of designing Ethereum 1.0 we have done a thorough job of optimizing the Ethereum virtual machine's computational power, but a much less thorough job of optimizing the database. There exists the possibility for substantial space savings, for both full nodes and light clients, by reorganizing Merkle tree structures and accounts. One example model for a more optimized state tree is the following: - -1. Assign account numbers sequentially, not via `address = sha3(pubkey) % 2**160`. This means that the set of accounts is contiguous, allowing standard binary Merkle trees to be used in place of Patricia trees, saving substantial space in state, history and LOAD/SSTORE time due to the resulting tight-packing. -2. Where Patricia trees are required, switch from hex to binary (est. 10-50% savings) -3. Where Patricia trees are required, note that currently a proof stores redundant info by storing a hash of a tree node in one node and then the other node separately. Create a special-purpose compression algorithm, either LZV style or placing nodes into each other directly when they refer to each other, to deduplicate (est. 35% savings). -4. Charge rent for accounts. This entails expanding accounts by adding a `last_accessed` parameter, and then when an account is accessed we update the parameter to the current block timestamp and simultaneously subtract `rent * (block.timestamp - acct.last_accessed)` from the account balance, where `rent` is somehow dynamically adjusted. If the new balance is below zero, then the account is destroyed and a large gas refund is provided. We theorize that large miners and account holders will want to create transactions that destroy accounts that are lagging on rent in order to reduce storage bloat; alternatively we can incentivize it with an additional security deposit. -5. Require transactions to include a timestamp, so that they can only be valid in `[timestamp, timestamp + 3600]`. This prevents replay attacks in the special case that accounts go down to zero balance, get deleted and then regain balance but with a nonce reset to zero. - -### More expressive Merkle trees - -Certain kinds of mechanisms, to be developed on Ethereum, require a richer set of data structures then just arrays, key/value maps, etc; the most commonly asked-for one is a heap (or an equivalent data structure that supports push/pop/top in logtime), highly useful in front-runner-proof markets among other applications. Currently, implementing a heap in Ethereum will lead to log^3(n) overhead, as we have a tree (the heap) on top of a tree (the account storage Patricia tree) on top of a tree (leveldb). Making a custom DB for the Patricia tree will likely need to be done at some point anyway, and will remove one level of overhead. However, the larger gain will come from the ability to have a Merklized heap-like structure, essentially making the heap operations native to the protocol. This reduces the total overhead all the way to the optimum of log(n). - -See also: Andrew Miller's [Lambda Auth](http://amiller.github.io/lambda-auth/), potentially useful as a starting point for a generalized design. - -### Events - -There should ideally be some mechanism by which one can create events that trigger automatically at certain times in the future, without any overlay protocols (as one simple application of this, consider a dice game that depends on future block data as a source of randomness). For this to work effectively, one must introduce an "event tree" into the Ethereum state alongside the state tree, and add specialized opcodes for creating events (events can be seen as one-way calls that get "frozen" and then executed in the future). A mechanism for gas costs for events, particularly recurring events, should be determined. - -### Verification - -Currently, secp256k1 ECDSA + SHA3 exists as a privileged signature verification algorithm in Ethereum. Ideally, since we are a generalized platform, it would be nice to be able to support any signature verification algorithm. A proposed design for this is: - -1. When a transaction is sent, it does not require a sender, only a "destination" address. Gas price, start gas, value, and data are still required. -2. The top-level message execution by default has a limit of 25000 gas, and within that time must either exit with an error, or run an `ACCEPT` opcode, paying for the full amount of gas from that contract's account. If the message exits with an error before ACCEPTing, the transaction is invalid. If it ACCEPTs, then it has the full amount of gas to run any other computation, send sub-messages, etc. The intent is for the first 25000 gas to be spent verifying a signature placed inside of the transaction data, and exiting with an error if the signature is invalid. - -Ideally, the initial limit would be large enough to support many kinds of signatures, but still small enough to be DDoS-proof. An alternative would be to require PoW on transactions, and scale the PoW difficulty with a verification gas limit set in the transaction; ASIC-resistant PoW can be used for this, though it would need to be carefully designed to be more CPU-friendly rather than GPU-friendly as is the case for Ethash. - -### Compression - -Currently, wire and database compression is done with a fairly crude algorithm that run-length-encodes zeroes but otherwise leaves data unchanged. Substantial gains can probably be made by applying either a pre-generated Huffman code or some separate compression algorithm such as [http://lloyd.github.io/easylzma/](http://lloyd.github.io/easylzma/). - -### Virtual machine - -The Ethereum virtual machine has a number of suboptimalities at present, and so there are plenty of features that can be added or impoved. Particular possibilities include: - -1. The addition of opcodes specialized for 64-bit arithmetic, which can be done on machines much more quickly. -2. The addition of `MCOPY` as an opcode and not a contract. -3. Replacement of DUP1...DUP16 and SWAP1...SWAP16 with `DUP ` (where `` is stored similarly to pushdata). This allows for unlimited depth in stack variables. -4. The addition of a `DEPTH` opcode to determine the current call stack depth, useful or determining whether or not there is enough stack space to make a particular sub-call with a compile-time-known depth. -5. A more radical rearchitecture where the VM deals with 64-bit values only, and long-arithmetic is done directly over memory slices. This removes the 256-bit limit and allows easy crypto calculations at arbitrary sizes. - -### Sending funds - -Currently, there is no way to send _all_ of one's funds to a contract from an externally owned account, unless one can exactly estimate the amount of gas that will be consumed. This adds some inconvenience to the process of emptying accounts. A possible solution is a "keep the change" opcode, by which a contract can (i) absorb all remaining gas in a message, (ii) claim `gas * gasprice` as ether for itself, and (iii) have that gas NOT count toward the miner's revenue or the block's gas limit. - -### Currency Neutrality - -Allow any currency to be used for purposes of security deposits, paying rent, etc. One possible framework in which this could happen is as follows: - -1. Create a base protocol-level concept of "currency". An eligible currency should give the protocol the ability to print more units of it and should support the standard send/receive/allow withdrawal interface. -2. Have (and subsidize liquidity on LMSR-style?) an on-protocol decentralized exchange to determine the price of each token relative to each other token. -3. Anyone can set a security deposit of any size in any currency. The protocol keeps track of a minimum security deposit in every currency (adjusted to target some number of validators), and you cannot add a deposit unless you provide at least this quantity. A deposit ceases to be usable if it falls below 50% of the minimum. - -Alternatives include being more liberal with regard to the assets involved, but using some kind of preference-revelation scheme to determine the value of a maximally arbitrary asset (note: this is hard when you do not have a single "favored currency" which you are assuming will have higher liquidity than everything else). - -A third option is to have a demurrage-heavy (or otherwise ephemeral) pseudo-currency, similar to gas, which is in some way assigned to validators. \ No newline at end of file diff --git a/Serpent-1.0-(old).md b/Serpent-1.0-(old).md deleted file mode 100644 index a221b99e8..000000000 --- a/Serpent-1.0-(old).md +++ /dev/null @@ -1,281 +0,0 @@ ---- -name: Serpent 1.0 -category: ---- - -Serpent is one of the high-level programming languages used to write Ethereum contracts. The language, as suggested by its name, is designed to be very similar to Python; later versions may even eventually come to target the entire [RPython spec](http://pypy.readthedocs.org/en/latest/coding-guide.html#rpython-definition). The language is designed to be maximally clean and simple, combining many of the efficiency benefits of a low-level language with ease-of-use in programming style. The latest version of the Serpent compiler, available [on github](http://github.com/ethereum/serpent), is written in C++, allowing it to be easily included in any client, and works by compiling the code first to LLL then to EVM; thus, if you like LLL, a possible intermediate option is to write Serpent, compile it to LLL, and then hand-tweak the LLL at the end. - -This tutorial assumes basic knowledge of how Ethereum works, including the concept of blocks, transactions, contracts and messages and the fact that contracts take a byte array as input and provide a byte array as output. If you do not, then go [here](https://github.com/ethereum/wiki/wiki/Ethereum-Development-Tutorial) for a basic tutorial. - -### Differences Between Serpent and Python - -The important differences between Serpent and Python are: - -* Python numbers have potentially unlimited size, Serpent numbers wrap around 2256. For example, in Serpent the expression `3^(2^254)` suprisingly evaluates to 1, even though in reality the actual integer is too large to be recorded in its entirety within the universe. -* Serpent has no decimals. -* There is no way to take a Serpent array and access its length; this sometimes leads to inconveniences like needing to type `return([a,b,c], 3)` instead of Python's `return [a,b,c]`. Future versions may change this specifically in the case of array literals. -* Serpent has no concept of strings (at this point); if you make an expression like `x = "george"`, the compiler converts that into a number using ASCII encoding, so you get 103 * 2565 + 101 * 2564 + 111 * 2563 + 114 * 2562 + 103 * 256 + 101 = 113685359126373. These numbers can be converted back into strings, so you can still represent strings, but they are limited to 32 characters in length. Future versions may change this to turn strings into char arrays, which would be accessible via `getch(str, i) -> byte` and `setch(str, i, byte)` -* Serpent has no list comprehensions (expressions like `[x**2 for x in my_list]`), dictionaries or most other advanced features -* Serpent has no function definitions or classes. Future versions may add function definitions - -### Installation - -In order to install the Serpent python library and executable do: - - pip install ethereum-serpent - -[Install the cpp-ethereum cli tools](https://github.com/ethereum/cpp-ethereum/wiki) to run the sc commands in the tutorial - -If you want a library you can directly call from C++, instead do: - - git clone http://github.com/ethereum/serpent - cd serpent - make - sudo make install - -### Tutorial - -Now, let's write our first contract. Paste the following into a file called "mul2.se": - - return(msg.data[0] * 2) - -This contract is a simple one line of code. The first thing to point out is that Serpent sees message data, memory and output in 32-byte chunks; `msg.data[0]` returns bytes 0-31 of the input, `msg.data[5]` returns bytes 160-191, etc, and `return(202020)` returns the value 202020 encoded in binary form padded to 32 bytes. From now on, these mechanics will be assumed; "the zeroth data field" will be synonymous with "bytes 0-31 of the input" and "returns three values a,b,c" will be synonymous with "returns 96 bytes consisting of the values a, b and c, each padded to 32 bytes". - -Note that the Serpent compiler (included in the [cpp-ethereum toolkit](https://github.com/ethereum/cpp-ethereum)) includes some tools to make this conversion convenient; `sc encode_datalist "1 2 3"` gives: - - 000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003 - -And `sc decode_datalist 000..003` gives: - - 1 2 3 - -Additionally, the Pyethereum testing environment that we will be using simply assumes that data input and output are in this format. - -Now, let's try actually compiling the code. Type: - - > sc compile mul2.se - 600e51600c6000396000f20060026000350260405460206040f2 - -And there we go, that's the hexadecimal form of the code that you can put into transactions. Or, if you want to see opcodes: - - > sc pretty_compile mul2.se - PUSH1 14 DUP PUSH1 12 PUSH1 0 CODECOPY PUSH1 0 RETURN STOP PUSH1 2 PUSH1 0 CALLDATALOAD MUL PUSH1 64 MSTORE PUSH1 32 PUSH1 64 RETURN - -Alternatively, you can compile to LLL (the compiler compiles through LLL anyway, so this is just stopping at an intermediate step instead of at the end): - - > sc compile_to_lll mul2.se - (return 0 - (lll - (seq - (set '_temp4_1 (mul (calldataload 0) 2)) - (return (ref '_temp4_1) 32) - ) - 0 - ) - ) - -This shows you the machinery that is going on inside. As with most contracts, the outermost layer of code exists only to copy the data of the inner code during initialization and return it, since the code returned during initialization is the code that will be executed every time the contract is called; in the EVM you can see this with the `CODECOPY` opcode, and in LLL this corresponds to the `lll` meta-operation. In the innermost layer, we take bytes 0-31 from the input, multiply that value by two, and save it in a temp variable called `_temp4_1`. We then supply the memory address of that variable, and the length 32, to the `RETURN` opcode. Note that, when dealing with message and memory data, LLL deals not with 32-byte chunks but with bytes directly, so the conversion needs to introduce these more low-level mechanics. `msg.data[1]`, for examples, is translated into `(calldataload 32)`, and `msg.data[3]` into `(calldataload 96)`. - -Now, what if you want to actually run the contract? That is where [pyethereum](https://github.com/ethereum/pyethereum) comes in. Open up a Python console in the same directory, and run: - - > from pyethereum import tester as t - > s = t.state() - > c = s.contract('mul2.se') - > s.send(t.k0, c, 0, [42]) - [84] - > s.send(t.k0, c, 0, [303030]) - [606060] - -The second line initializes a new state (ie. a genesis block). The third line creates a new contract, and sets `c` to its address. The fourth line sends a transaction from private key zero (the `tester` submodule includes ten pre-made key/address pairs at `k0`, `a0`, `k1`, `a1`, etc) to the address of the contract with 0 wei and with data input 42, and we see 84 predictably come out. - -And there you go. - -### Lesson 2: Name Registry - -Having a multiply-by-two function on the blockchain is kind of boring. So let's do something marginally more interesting: a name registry. Our name registry will be fairly simple; it will take in two data items (ie. 64 bytes), treating the first item as the key and the second as the value. If the key is not yet registered, then it registers the key/value pair and returns 1; otherwise, it returns 0. Let's try it out: - - key = msg.data[0] - value = msg.data[1] - # Key not yet claimed - if not contract.storage[key]: - contract.storage[key] = value - return(1) - else: - return([0], 1) # Key already claimed - -Here, we see a few parts in action. First, we have the `msg.data` pseudo-array, which can be used to access message input data items. Then, we have `key` and `value`, which are variables that we set. The third line is a comment; it does not get compiled and only serves to remind you what the code does. Then, we have a standard if/else clause, which checks if `contract.storage[key]` is zero (ie. unclaimed), and if it is then it sets `contract.storage[key] = value` and returns 1. Otherwise, it returns zero (which we expressed as a literal array just to exhibit this other style of returning; it's more cumbersome but lets you do return multiple values). `contract.storage` is also a pseudo-array, acting like an array but without any particular memory location. - -Now, paste the code into "namecoin.se", if you wish try compiling it to LLL, opcodes or EVM, and let's try it out in the pyethereum tester environment: - - > from pyethereum import tester as t - > s = t.state() - > c = s.contract('namecoin.se') - > s.send(t.k0, c, 0, ["george", 45]) - [1] - > s.send(t.k1, c, 0, ["george", 20]) - [0] - > s.send(t.k2, c, 0, ["harry", 65]) - [1] - -### Including files - -Once your projects become larger, you will not want to put everything into the same file; things become particularly inconvenient when one piece of code needs to create a contract. Fortunately, the process for splitting code into multiple files is quite simple. Make the following two files: - -mul2.se: - - return(msg.data[0] * 2) - -returnten.se: - - MUL2 = create('mul2.se') - return(call(MUL2, 5)) - -And open Python: - - > from pyethereum import tester as t - > s = t.state() - > c = s.contract('returnten.se') - > s.send(t.k0, c, 0, []) - [10] - -Another, similar, operation is `(inset 'filename')`, which simply puts code into a particular place without adding a separate contract. - -### Miscellaneous - -Additional Serpent coding examples can be found here: https://github.com/ethereum/serpent/tree/master/examples - -The three other useful features in the tester environment are: - -* Block access - you can dig around `s.block` to see block data (eg. `s.block.number`, `s.block.get_balance(addr)`, `s.block.get_storage_data(addr, index)`) -* Snapshots - you can do `x = s.snapshot()` and `s.revert(x)` -* Advancing blocks - you can do `s.mine(100)` and 100 blocks magically pass by with a 60-second interval between blocks. `s.mine(100, addr)` mines into a particular address. -* Full block data dump - type `s.to_dict()` - -## Complete language spec - -### Expressions - -An expression is defined as anything that fits on one line. An expression is recursively defined as follows: - -* A number is an expression (eg. `125`) -* A number in hex is an expression (eg. `0xdeadbeef`), and evaluates to the corresponding decimal value (in this case, `3735928559`). Uppercase does not work. -* A string is an expression (eg. `"george"`), and evaluates to the corresponding hex (in this case, `0x67656f726765`, ie. `113685359126373`). Note that due to wraparound all but the last 32 characters of a 33+ char string are truncated off. -* A variable is an expression (eg. `a`) -* An arithmetic expression built out of arithmetic operations and expressions is an expression (eg. `2 + 3`, `(4 + 5) ^ 7`, `"george" ^ 2 / (0xdeadbeef - 4848) ^ "harry"`). Supported operations are: - * `+` (`ADD`) - * `-` (`SUB`); note that right now `-5` is converted into `(sub 0 5)` - * `*` (`MUL`) - * `/` (`SDIV`, ie. signed division, where negative values of `x` are stored as `x + 2^256`, eg. -3 is `0xfffffff....ffd`) - * `%` (`SMOD`) - * `@/` (`DIV`, ie. unsigned division) - * `@%` (`MOD`) - * `^` (`EXP`) - * `**` (`EXP`) - * `<` (`SLT`, ie. signed comparison) - * `@<` (`LT`, ie unsigned comparison) - * `>` (`SGT`) - * `@>` (`GT`) - * `==` (`EQ`) - * `|` (`OR`, ie. bitwise or) - * `xor` (`XOR`) - * `or`: `a or b` returns `a` if `a` is nonzero, otherwise `b`; `a` is never evaluated twice, and if `a != 0` then `b` is never evaluated at all - * `and`: `a and b` returns `b` if `a` is nonzero, otherwise `0`; if `a = 0` then `b` is never evaluated at all -* An array literal consisting of expressions is an expression (eg. `[1,2,3]`, `[3 + 5, [8, 12, [24]], 9 ^ 6 / "cow"]`) -* An array access where the accessed array and the index are expressions is an expressoin (eg. `x[4]`, `y[z + 5][c + 2]`) -* A function call where the arguments are expressions is an expression (eg. `return(call(addrs[7], x ^ 3 + 5))`). Supported functions are: - * `array(n)`: returns an empty array of size `n` (in 32-byte chunks) - * `bytes(n)`: returns a byte array of size `n` (in bytes) - * `getch(arr, i)`: returns the `i`th character of the given bytearray - * `setch(arr, i, c)`: sets the `i`th character of the given bytearray to `c` - * `msg(gas, to, value, dataval)`: sends a message with the specified recipient, quantity of ether (in wei) and amount of gas, with `dataval` as a 32-byte input, and returns the first 32 bytes of the output as a value on the stack - * `msg(gas, to, value, datarray, insize)`: sends a message with the specified recipient, quantity of ether (in wei) and amount of gas, taking `insize` values from the specified array as input, and returns the first 32 bytes of the output as a value on the stack - * `msg(gas, to, value, datarray, insize, outsize)`: sends a message with the specified recipient, quantity of ether (in wei) and amount of gas, taking `insize` values from the specified array as input, and returns an `outsize`-sized data array as the output - * `call(addr, dat)` - equivalent to `msg(tx.gas - 25, addr, 0, dat)` where `tx.gas` is the remaining gas - * `call(addr, datarray, insize)` - equivalent to `msg(tx.gas - 25, addr, 0, datarray, insize)` - * `call(addr, datarray, insize, outsize)` - equivalent to `msg(tx.gas - 25, addr, 0, datarray, insize, outsize)` - * `send(gas, addr, value)` - sends the desired amount of value to the desired address with the desired gas limit - * `send(addr, value)` - equivalent to `send(tx.gas - 25, addr, value)` - * `create('filename')` - creates a contract out of code from the desired filename and returns the address - * `sha3(value)` - returns the SHA3 of the given value (as 32 bytes, zero-padded if necessary) - * `sha3(str, bytes)` - returns the SHA3 of the given byte array with the given number of bytes - * `return(value)` - exits message execution, returning the given value (as 32 bytes, zero-padded if necessary) (ie. if you run `x = send(C)` and the contract at address `C` reaches a point where there is the code `return(7)`, then in the outer execution `x` will equal 7) - * `return(array, size)` - exits message execution, returning the given array with the given number of 32-byte chunks - * `stop` - exits message execution, reporting nothing - * `suicide(addr)` - destroys the contract, sending all ether to the given address - * `debug(num)` - does nothing (in the pyethereum implementation with the `DUP POP POP` sequence of opcodes). However, implementations may wish to show the number in some kind of debug output. - -### Code blocks - -A code block constitutes a complete program in Ethereum. A code block is defined as follows: - -(1) An expression is a code block. - -(2) A statement of the form: - - a - b - -is a code block, where `a` and `b` are code blocks. Note that this can be expanded to basically mean that any number of code blocks with the same indenting level put together is a code block. - -(3) A statement of the form: - - if a: - b - -is a code block, where `a` is an expression and `b` is a code block. - -(4) A statement of the form: - - if a: - b - else: - c - -is a code block, where `a` is an expression and `b` and `c` are code blocks. - -(5) A statement of the form: - - if a: - b - elif c: - d - else: - e - -is a code block, and an unlimited number of other elif clauses can be added in the middle. - -(6) A statement of the form: - - while a: - b - -is a code block, where `a` is an expression and `b` is a code block. - -(7) A statement of the form: - - init: - a - code: - b - -is a code block. This block should only be used at the top level; the `init` sub-block is called during initialization and the `code` sub-block is called during future executions. - -(8) A statement of the form: - - shared: - a - init: - b - code: - c - -is a code block, and is synonymous with: - - init: - a - b - code: - a - c - -(9) `inset('filename')` is a code block, and is substituted at compile time with the text of the file. \ No newline at end of file diff --git a/Serpent.md b/Serpent.md deleted file mode 100644 index 4ee0944a0..000000000 --- a/Serpent.md +++ /dev/null @@ -1,494 +0,0 @@ ---- -name: Serpent -category: ---- - -See https://github.com/ethereum/wiki/wiki/Serpent-1.0-(old) for Serpent 1.0. - -Serpent is one of the high-level programming languages used to write Ethereum contracts. The language, as suggested by its name, is designed to be very similar to Python; it is intended to be maximally clean and simple, combining many of the efficiency benefits of a low-level language with ease-of-use in programming style, and at the same time adding special domain-specific features for contract programming. The latest version of the Serpent compiler, available [on github](http://github.com/ethereum/serpent), is written in C++, allowing it to be easily included in any client. - -This tutorial assumes basic knowledge of how Ethereum works, including the concept of blocks, transactions, contracts and messages and the fact that contracts take a byte array as input and provide a byte array as output. If you do not, then go [here](https://github.com/ethereum/wiki/wiki/Ethereum-Development-Tutorial) for a basic tutorial. - -### Differences Between Serpent and Python - -The important differences between Serpent and Python are: - -* Python numbers have potentially unlimited size, Serpent numbers wrap around 2256. For example, in Serpent the expression `3^(2^254)` suprisingly evaluates to 1, even though in reality the actual integer is too large to be recorded in its entirety within the universe. -* Serpent has no decimals. -* Serpent has no list comprehensions (expressions like `[x**2 for x in my_list]`), dictionaries or most other advanced features -* Serpent has no concept of first-class functions. Contracts do have functions, and can call their own functions, but variables (except storage) do not persist across calls. -* Serpent has a concept of persistent storage variables (see below) -* Serpent has an `extern` statement used to call functions from other contracts (see below) - -### Installation - -In order to install the Serpent python library and executable do: - - $ sudo pip install ethereum-serpent - -If you want a library you can directly call from C++, instead do: - - $ git clone http://github.com/ethereum/serpent - $ cd serpent - $ make - $ sudo make install - -### Tutorial - -Now, let's write our first contract. Paste the following into a file called `mul2.se`: - - def double(x): - return(x * 2) - -This contract is a simple two lines of code, and defines a function. Functions can be called either by transactions or by other contracts, and are the way that Serpent contracts provide an "interface" to other contracts and to transactions; for example, a contract defining a currency might have functions `send(to, value)` and `check_balance(address)`. - -Additionally, the Pyethereum testing environment that we will be using simply assumes that data input and output are in this format. - -Now, let's try actually compiling the code. Type: - -``` -$ serpent compile mul2.se -604380600b600039604e567c01000000000000000000000000000000000000000000000000000000006000350463eee9720681141560415760043560405260026040510260605260206060f35b505b6000f3 -``` - -And there we go, that's the hexadecimal form of the code that you can put into transactions. Or, if you want to see opcodes: - - $ serpent pretty_compile mul2.se - [PUSH1, 67, DUP1, PUSH1, 11, PUSH1, 0, CODECOPY, PUSH1, 78, JUMP, PUSH29, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, PUSH1, 0, CALLDATALOAD, DIV, PUSH4, 238, 233, 114, 6, DUP2, EQ, ISZERO, PUSH1, 65, JUMPI, PUSH1, 4, CALLDATALOAD, PUSH1, 64, MSTORE, PUSH1, 2, PUSH1, 64, MLOAD, MUL, PUSH1, 96, MSTORE, PUSH1, 32, PUSH1, 96, RETURN, JUMPDEST, POP, JUMPDEST, PUSH1, 0, RETURN] - -Alternatively, you can compile to LLL to get an intermediate representation: - -``` -$ serpent compile_to_lll mul2.se -(return 0 - (lll - (with '__funid - (div (calldataload 0) - 26959946667150639794667015087019630673637144422540572481103610249216 - ) - (unless (iszero (eq (get '__funid) 4008276486)) - (seq - (set 'x (calldataload 4)) - (seq - (set '_temp_521 (mul (get 'x) 2)) - (return (ref '_temp_521) 32) - ) - ) - ) - ) - 0 - ) -) -``` - -This shows you the machinery that is going on inside. As with most contracts, the outermost layer of code exists only to copy the data of the inner code during initialization and return it, since the code returned during initialization is the code that will be executed every time the contract is called; in the EVM you can see this with the `CODECOPY` opcode, and in LLL this corresponds to the `lll` meta-operation. Inside of the LLL, we have a wrapper whose purpose it is to grab the first four bytes of the contract data, (that's the `(div (calldataload 0) 26959946667150639794667015087019630673637144422540572481103610249216)`; we grab four bytes by grabbing the first 32 bytes and dividing it by 2^224) to get the function ID that is being called, and then inside of that we have a series of functions (in this case only one function) that checks the function ID provided against all function IDs supported by the contract. If the function ID is 4008276486, then it sets a variable `'x` to the message data bytes 4-35 (that's `(calldataload 4)`), sets a temporary variable to equal to `2 * x`, and returns the 32 byte memory slice that contains that variable. - -The function ID is calculated by computing a hash based on the function name and arguments and taking the first four bytes. In this case we have a function named `double` with a single integer as an argument; on the command line we can do: - - $ serpent get_prefix double i - 4008276486 - -Note that you can have multiple functions with the same name, if they take different combinations of inputs. For instance, a hypothetical function double that takes three integers as input (and, say, returns an array consisting of 2x each one) would have a different prefix: - - $ serpent get_prefix double iii - 1142360101 - -The letter `i` is meant for integers, and for fixed-length (up to 32 byte) strings (which are treated the same as integers in Serpent and EVM). Use the letter `s` for variable-length string arguments, and `a` for arrays; more on these later. - -Now, what if you want to actually run the contract? That is where [pyethereum](https://github.com/ethereum/pyethereum) comes in. Open up a Python console in the same directory, and run: - - >>> from ethereum import tester as t - >>> s = t.state() - >>> c = s.abi_contract('mul2.se') - >>> c.double(42) - [84] - -The second line initializes a new state (ie. a genesis block). The third line creates a new contract, and creates an object in Python which represents it. You can use `c.address` to access this contract's address. The fourth line calls the contract with argument 42, and we see 84 predictably come out. - -Note that if you want to send a transaction to such a contract in the testnet or livenet, you will need to package up the transaction data for "call function double with an integer as an input with data 42". The command line instruction for this is *deprecated*: - - $ serpent encode_abi double i 42 - eee97206000000000000000000000000000000000000000000000000000000000000002a - -### Example: Name Registry - -Having a multiply-by-two function on the blockchain is kind of boring. So let's do something marginally more interesting: a name registry. The main function will be a `register(key, value)` operation which checks if a given key was already taken, and if is unoccupied then register it with the desired value and return 1; if the key is already occupied return 0. We will also add a second function to check the value associated with a particular key. Let's try it out: - - def register(key, value): - # Key not yet claimed - if not self.storage[key]: - self.storage[key] = value - return(1) - else: - return(0) # Key already claimed - - def ask(key): - return(self.storage[key]) - -Here, we see a few parts in action. First, we have the `key` and `value` variables that the function takes as arguments. The second line is a comment; it does not get compiled and only serves to remind you what the code does. Then, we have a standard if/else clause, which checks if `self.storage[key]` is zero (ie. unclaimed), and if it is then it sets `self.storage[key] = value` and returns 1. Otherwise, it returns zero. `self.storage` is also a pseudo-array, acting like an array but without any particular memory location. - -Now, paste the code into `namecoin.se`, if you wish try compiling it to LLL, opcodes or EVM, and let's try it out in the pyethereum tester environment: - - >>> from ethereum import tester as t - >>> s = t.state() - >>> c = s.abi_contract('namecoin.se') - >>> c.register(0x67656f726765, 45) - [1] - >>> c.register(0x67656f726765, 20) - [0] - >>> c.register(0x6861727279, 65) - [1] - >>> c.ask(0x6861727279) - [65] - -If we wanted to encode the transaction data for that first call, we would do: - - - $ serpent encode_abi register ii 0x67656f726765 45 - d66d6c10000000000000000000000000000000000000000000000000000067656f726765000000000000000000000000000000000000000000000000000000000000002d - -### Including files, and calling other contracts - -Once your projects become larger, you will not want to put everything into the same file; things become particularly inconvenient when one piece of code needs to create a contract. Fortunately, the process for splitting code into multiple files is quite simple. Make the following two files: - -mul2.se: - - def double(x): - return(x * 2) - -returnten.se: - - extern mul2.se: [double:i:i] - - MUL2 = create('mul2.se') - def returnten(): - return(MUL2.double(5)) - -And open Python: - - >>> from ethereum import tester as t - >>> s = t.state() - >>> c = s.abi_contract('returnten.se') - >>> c.returnten() - [10] - -Note that here we introduced several new features. Particularly: - -* The `create` command to create a contract using code from another file -* The `extern` keyword to declare a class of contract for which we know the names of the functions -* The interface for calling other contracts - -`create` is self-explanatory; it creates a contract and returns the address to the contract. - -The way `extern` works is that you declare a class of contract, in this case `mul2`, and then list in an array the names of the functions, in this case just `double`. To generate `extern mul2.se: [double:i:i]` use - - $ serpent mk_signature mul2.se - -From there, given any variable containing an address, you can do `x.double(arg1)` to call the address stored by that variable. The arguments are the values provided to the function. If you provide too few arguments, the rest are filled to zero, and if you provide too many the extra ones are ignored. Function calling also has some other optional arguments: - -* `gas=12414` - call the function with 12414 gas instead of the default (all gas) -* `value=10^19` - send 10^19 wei (10 ether) along with the message -* `data=x`, `datasz=5` - call the function with 5 values from the array `x`; note that this replaces other function arguments. `data` without `datasz` is illegal -* `outsz=7` - by default, Serpent processes the output of a function by taking the first 32 bytes and returning it as a value. However, if `outsz` is used as here, the function will instead return an array containing 7 values; if you type `y = x.fun(arg1, outsz=7)` then you will be able to access the output via `y[0]`, `y[1]`, etc. - -Another similar operation to `create` is `inset('filename')`, which simply puts code into a particular place without adding a separate contract. - -returnten.se - - inset('mul2.se') - - def returnten(): - return(self.double(5)) - -### Storage data structures - -In more complicated contracts, you will often want to store data structures in storage to represent certain objects. For example, you might have a decentralized exchange contract that stores the balances of users in multiple currencies, as well as open bid and ask orders where each order has a price and a quantity. For this, Serpent has a built-in mechanism for defining your own structures. For example, in such a decentralized exchange contract you might see: - - data user_balances[][] - data orders[](buys[](user, price, quantity), sells[](user, price, quantity)) - -Then, you might do something like: - - def fill_buy_order(currency, order_id): - # Available amount buyer is willing to buy - q = self.orders[currency].buys[order_id].quantity - # My balance in the currency - bal = self.user_balances[msg.sender][currency] - # The buyer - buyer = self.orders[currency].buys[order_id].user - if q > 0: - # The amount we can actually trade - amount = min(q, bal) - # Trade the currency against the base currency - self.user_balances[msg.sender][currency] -= amount - self.user_balances[buyer][currency] += amount - self.user_balances[msg.sender][0] += amount * self.orders[currency].buys[order_id].price - self.user_balances[buyer][0] -= amount * self.orders[currency].buys[order_id].price - # Reduce the remaining quantity on the order - self.orders[currency].buys[order_id].quantity -= amount - -Notice how we define the data structures at the top, and then use them throughout the contract. These data structure gets and sets are converted into storage accesses in the background, so the data structures are persistent. - -The language for doing data structures is simple. First, we can do simple variables: - - data blah - - x = self.blah - self.blah = x + 1 - -Then, we can do arrays, both finite and infinite: - - data blah[1243] - data blaz[] - - x = self.blah[505] - y = self.blaz[3**160] - self.blah[125] = x + y - -Note that finite arrays are always preferred, because it will cost less gas to calculate the storage index associated with a finite array index lookup. And we can do tuples, where each element of the tuple is itself a valid data structure: - - data body(head(eyes[2], nose, mouth), arms[2], legs[2]) - - x = self.body.head.nose - y = self.body.arms[1] - -And we can do arrays of tuples: - - data bodies[100](head(eyes[2], nose, mouth), arms[2](fingers[5], elbow), legs[2]) - - x = self.bodies[45].head.eyes[1] - y = self.bodies[x].arms[1].fingers[3] - -Note that the following is unfortunately not legal: - - data body(head(eyes[2], nose, mouth), arms[2], legs[2]) - - x = self.body.head - y = x.eyes[0] - -Accesses have to descend fully in a single statement. To see how this could be used in a simpler example, let's go back to our name registry, and upgrade it so that when a user registers a key they become the owner of that key, and the owner of a key has the ability to (1) transfer ownership, and (2) change the value. We'll remove the return values here for simplicity. - - data registry[](owner, value) - - def register(key): - # Key not yet claimed - if not self.registry[key].owner: - self.registry[key].owner = msg.sender - - def transfer_ownership(key, new_owner): - if self.registry[key].owner == msg.sender: - self.registry[key].owner = new_owner - - def set_value(key, new_value): - if self.registry[key].owner == msg.sender: - self.registry[key].value = new_value - - def ask(key): - return([self.registry[key].owner, self.registry[key].value], items=2) - -Note that in the last ask command, the function returns an array of 2 values. If you wanted to call the registry, you would have needed to do something like `o = registry.ask(key, outsz=2)` and you could have then used `o[0]` and `o[1]` to recover the owner and value. - -### Simple arrays in memory - -The syntax for arrays in memory are different: they can only be finite and cannot have tuples or more complicated structures. - -Example: - - def bitwise_or(x, y): - blah = array(1243) - blah[567] = x - blah[568] = y - blah[569] = blah[567] | blah[568] - return(blah[569]) - -There are also two functions for dealing with arrays: - - len(x) - -Returns the length of array x. - - slice(x, items=start, items=end) - -Takes a slice of x starting with position start and ending with position end (note that we require `end >= start`; otherwise the result will almost certainly result in an error) - -### Arrays and Functions - -Functions can also take arrays as arguments, and return arrays. - - def compose(inputs:arr): - return(inputs[0] + inputs[1] * 10 + inputs[2] * 100) - - def decompose(x): - return([x % 10, (x % 100) / 10, x / 100]:arr) - -Putting the `:arr` after a function argument means it is an array, and putting it inside a return statement returns the value as an array (just doing `return([x,y,z])` would return the integer which is the memory location of the array). - -If a contract calls one of its functions, then it will autodetect which arguments should be arrays and parse them accordingly, so this works fine: - - def compose(inputs:arr, radix): - return(inputs[0] + inputs[1] * radix + inputs[1] * radix ** 2) - - def main(): - return self.compose([1,2,3,4,5], 100) - -However, if a contract wants to call another contract that takes arrays as arguments, then you will need to put a "signature" into the extern declaration: - - extern composer: [compose:ai, main] - -Here, `ai` means "an array followed by an integer". You can do things like `iiaa`, meaning 2 integers followed by 2 arrays or `iss` meaning an integer followed by 2 strings. If a colon is not provided, as in `main` in this example, that means that the function takes no arguments. If you want to determine the signature to use from a given file, you can do: - - > serpent mk_signature compose_test.se - extern compose_test: [compose:ai, main] - -### Strings - -There are two types of strings in Serpent: short strings, eg. `"george"`, and long strings, eg. `text("afjqwhruqwhurhqkwrhguqwhrkuqwrkqwhwhrugquwrguwegtwetwet")`. Short strings, given simply in quotes as above, are treated as numbers; long strings, surrounded by the `text` keyword as above, are treated as array-like objects; you can do `getch(str, index)` and `setch(str, index)` to manipulate characters in strings (doing `str[0]` will treat the string as an array and try to fetch the first 32 characters as a number). - -To use strings as function arguments or outputs, use the `str` tag, much like you would use `arr` for arrays. `len(s)` gives you the length of a string, and `slice` works for strings the same way as for arrays too. - -Here is an example of returning/retrieving a string: -``` -data str - -def t2(): - self.str = text("01") - log(data=self.str) - return(self.str, chars=2) - -def runThis(): - s = self.t2(outsz=2) - log(data=s) -``` - -### Macros - -**WARNING: Relatively new/untested feature, here be ~~dragons~~ serpents** - -Macros allow you to create rewrite rules which provide additional expressivity to the language. For example, suppose that you wanted to create a command that would compute the median of three values. You could simply do: - - macro median($a, $b, $c): - min(min(max($a, $b), max($a, $c)), max($b, $c)) - -Then, if you wanted to use it somewhere in your code, you just do: - - x = median(5, 9, 7) - -Or to take the max of an array: - - macro maxarray($a:$asz): - $m = 0 - $i = 0 - while i < $asz: - $m = max($m, $a[i]) - $i += 1 - $m - - x = maxarray([1, 9, 5, 6, 2, 4]:6) - -For a highly contrived example of just how powerful macros can be, see https://github.com/ethereum/serpent/blob/poc7/examples/peano.se - -Note that macros are not functions; they are copied into code every time they are used. Hence, if you have a long macro, you may instead want to make the macro call an actual function. Additionally, note that the dollar signs on variables are important; if you omit a dollar sign in the pattern $a then the macro will only match a variable actually called a. You can also create dollar sign variables that are in the substitution pattern, but not the search pattern; this will generate a variable with a random prefix each instance of the macro. You can also create new variables without a dollar sign inside a substitution pattern, but then the same variable will be shared across all instances of the pattern and with uses of that variable outside the pattern. - -### Types - -**WARNING: Relatively new/untested feature, here be ~~dragons~~ serpents** - -An excellent compliment to macros is Serpent's ghetto type system, which can be combined with macros to produce quite interesting results. Let us simply show this with an example: - - type float: [a, b, c] - - macro float($x) + float($y): - float($x + $y) - - macro float($x) - float($y): - float($x - $y) - - macro float($x) * float($y): - float($x * $y / 2^32) - - macro float($x) / float($y): - float($x * 2^32 / $y) - - macro unfloat($x): - $x / 2^32 - - macro floatfy($x): - float($x * 2^32) - - macro float($x) = float($y): - $x = $y - - macro with(float($x), float($y), $z): - with($x, $y, $z) - - a = floatfy(25) - b = a / floatfy(2) - c = b * b - return(unfloat(c)) - -This returns 156, the integer portion of 12.5^2. A purely integer-based version of this code would have simply returned 144. An interesting use case would be rewriting the [elliptic curve signature pubkey recovery code](https://github.com/ethereum/serpent/blob/df0aa0e1285d7667d4a0cc81b1e11e0abb31fff3/examples/ecc/jacobian_add.se) using types in order to make the code neater by making all additions and multiplications implicitly modulo P, or using [long integer types](https://github.com/ethereum/serpent/blob/poc7/examples/long_integer_macros.se) to do RSA and other large-value-based cryptography in EVM code. - -### Miscellaneous - -Additional Serpent coding examples can be found here: https://github.com/ethereum/serpent/tree/master/examples - -The three other useful features in the tester environment are: - -* Block access - you can dig around `s.block` to see block data (eg. `s.block.number`, `s.block.get_balance(addr)`, `s.block.get_storage_data(addr, index)`) -* Snapshots - you can do `x = s.snapshot()` and `s.revert(x)` -* Advancing blocks - you can do `s.mine(100)` and 100 blocks magically pass by with a 60-second interval between blocks. `s.mine(100, addr)` mines into a particular address. -* Full block data dump - type `s.block.to_dict()` - -Serpent also gives you access to many "special variables"; the full list is: - -* `tx.origin` - the sender of the transaction -* `tx.gasprice` - gas price of the transaction -* `msg.gas` - gas remaining -* `msg.sender` - the sender of the message -* `msg.value` - the number of wei (smallest units of ether) sent with the message -* `self` - the contract's own address -* `self.balance` - the contract's balance -* `x.balance` (for any x) - that account's balance -* `block.coinbase` - current block miner's address -* `block.timestamp` - current block timestamp -* `block.prevhash` - previous block hash -* `block.difficulty` - current block difficulty -* `block.number` - current block number -* `block.gaslimit` - current block gaslimit - -Serpent recognises the following "special functions": - -* `def init():` - executed upon contract creation, accepts no parameters -* `def shared():` - executed before running `init` and user functions -* `def code():` - executed before any user functions - -There are also special commands for a few crypto operations; particularly: - -* `addr = ecrecover(h, v, r, s)` - determines the address that produced the elliptic curve signature `v, r, s` of the hash `h` -* `x = sha256(a, items=4)` - returns the sha256 hash of the 128 bytes consisting of the 4-item array starting from `a` -* `x = ripemd160(a, items=4)` - same as above but for ripemd160 -* To hash an arbitrary number of bytes, use chars syntax. Example: `x = sha256([0xf1fc122bc7f5d74df2b9441a42a1469500000000000000000000000000000000], chars=16)` - returns the sha256 of the first 16 bytes. Note: padding with trailing zeroes, otherwise the first 16 bytes will be zeroes, and the sha256 of it will be computed instead of the desired. -* you can also use sha3 instead of sha256, e.g. `sha3(a, items=4)` -### Tips - -* If a function is not returning the result you expect, double-check that all variables are correct: there is no error/warning when using an undeclared variable. - -* `Invalid argument count or LLL function` usually means you just called foo() instead of `self.foo()`. - -* Sometimes you may be intending to use unsigned operators. eg div() and lt() instead of '/' and '<'. - -* To upgrade Serpent, you may need to do `pip uninstall ethereum-serpent` and `python setup.py install`. (Avoid `pip install ethereum-serpent` since it will get from PyPI which is probably old.) - -* When calling abi_contract(), if you get this type of error `Exception: Error (file "main", line 1, char 5): Invalid object member (ie. a foo.bar not mapped to anything)` make sure you are specifying correct path to the file you are compiling. - -* If you get a core dump when calling `abi_contract()`, check that you do not have functions with the same name. - -* Use macro for constants, example: -``` -macro CONSTANT: 99 -``` - -* Be careful that if your flow requires going through a number of contracts, that someone can't just directly short-circuit and call one of your latter contracts with data they've manipulated elsewhere. Example: If you have contract C which gives someone ether, but relies on computation from Contract A->B->C, that someone can't just call B or C to give themselves ether. - -### Other -http://mc2-umd.github.io/ethereumlab/docs/serpent_tutorial.pdf - some outdated but can generally be helpful \ No newline at end of file diff --git a/Serpent_3.0.md b/Serpent_3.0.md deleted file mode 100644 index 2c8f8c7b6..000000000 --- a/Serpent_3.0.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -name: Serpent 3.0 -category: ---- - -The following is a suggested spec for Serpent 3.0. - - -1. Everything is strongly typed, but types are inferred, so there is no need to specify types explicitly. - -For example, consider the code: - - data bar[6] - - def foo(): - x = 5 - y = [1,2,3,4,5,6] - z = "123123124" - w1 = y[1] - w2 = z[2] - self.bar = y - return(x) - -A script would run through the code and assign types: - - x: int - y: arr[int] - z: string - w1: int - w2: int - self.bar: arr[int] :: storage - -When checking the type for w1, the script would see the line `w1 = y[1]`, note that `y` is already known as an `arr[int]` so `y[1]` will be recognized as `int`. Meanwhile, `z` will be known as `string`, and so `z[1]` will be recognized as a character, ie. `int`. Note that this means that `y[1]` will be compiled as `(mload (add y 32))` whereas `z[2]` will be compiled as `(byte (mload (add z 2)) 0)`. `self.bar = y` will be processed recursively so as to copy the entire contents of `y` into `self.bar`. \ No newline at end of file diff --git a/Solidity,-Docs-and-ABI.md b/Solidity,-Docs-and-ABI.md deleted file mode 100644 index e9b609379..000000000 --- a/Solidity,-Docs-and-ABI.md +++ /dev/null @@ -1,231 +0,0 @@ ---- -name: Solidity Docs and ABI -category: ---- - -*NOTE: This is intended largely as a vague overview and a historical reference. For specific details and the latest specification, see [Ethereum Contract ABI](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI), [Ethereum Natural Specification Format](https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format) and [Solidity Tutorial](https://github.com/ethereum/wiki/wiki/Solidity-Tutorial).* - -An ABI is intended to serve as the de facto method for encoding & decoding data into & out of transactions. - -For this ABI, contracts are treated as objects. They export a particular interface, not dissimilar from that of an OO language, for example for a contract `Foo`: - -``` -contract Foo -{ - function sam(string32 in1) { ... } - function bar(uint256 in1, string in2) returns (string out1, bool out2) { ... } - function baz(uint32 in1, real in2) returns bool { ... } - -state: - uint256 tom; -} -``` - -Note you haven't seen this language before. This is a new high level language codenamed Solidity, that will feel mostly similar to something between JavaScript and C++ but with a number of syntactic additions to make it suitable for writing contracts within Ethereum. Language additions include: - -* static typing; -* contracts as first-class entities; -* state as part of a contract able to map & segment information into the storage; -* invariants, pre- and post-conditions as part of a contract; -* variadic return values with named components; -* a safe language subset allowing guaranteed static analysis & proofs; -* an inbuilt test-generation and execution environment for situations where formal proofing is not practical. - -The above would result in three methods being exposed: `bar`, `baz` and `sam`, roughly expressed in JSON as: - -``` -{ - "bar": { - "inputs": [ - "in1": "uint256", - "in2": "string" - ], - "outputs": [ - "out1": "string", - "out2": "bool" - ] - }, - "baz": { - "inputs": [ - "in1": "uint32", - "in2": "real" - ], - "outputs": [ - "__default": "bool" - ] - }, - "sam": { - "inputs": [ - "in1": "string32" - ], - "outputs": [] - } -} -``` - - -In previous versions of the proof-of-concept series, only simple 32-byte values were supported; the ABI adds the ability to also have variably sized arguments. - -### ABI - -See [Ethereum Contract ABI](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI). - -### Documentation - -It is expected that each method, together with the contract itself, will be documented in several ways. Aside from informal descriptions, each method should come with a formalised method to describe exactly its effect on the state of Ethereum. It should also include, where possible, pre- and post-conditions on the contract state, and the contract itself should include invariants over its own state, again each translated into natural language. - -For GavCoin, a meta coin that that is sub-divisible down to 1,000, and includes two functions `balance` and `send`, we might see the basic, undocumented contract as: - -``` -contract GavCoin -{ - function send(address to, uint256 valueInmGAV) { - balances[to] += valueInmGAV; - balances[transaction.sender] -= valueInmGAV; - } - function balance(address who) constant returns (uint256 balanceInmGAV) { - balanceInmGAV = balances[who]; - } - -invariants: - reduce(0, +, map(valueOf, balances)) == 100000000000; - -construction: - balances[transaction.sender] = 100000000000; - -state: - mapping balances (address) returns uint256 with function(address a) returns uint256 { return a; }; -}; -``` - -Of course it is wrong. A static checker will analyse this (with the language assertion that the uint256 type must not be allowed to underflow unless explicitly given that attribute) and come back with something like: - -``` -Line 8: >>> balances[transaction.sender] -= valueInmGAV <<<: - balances[...] may underflow with '-=' operation using unbounded operand valueInmGAV. - Suggestion: surround code with conditional to bound operand valueInmGAV. -``` - -This is basically saying that it can see no reason why `valueInmGAV` could be no bigger than `balances[transaction.sender]`. And it's right. We forgot to check the parameters. It's easily fixed by adding the conditional and altering the method to: - -``` - void send(address to, uint256 valueInmGAV) { - if (balances[transaction.sender] >= valueInmGAV) { - balances[to] += valueInmGAV; - balances[transaction.sender] -= valueInmGAV; - } - } -``` - -This would then be formally documented: - -``` -/// @title Some title here. -/// @author Homer Simpson -contract GavCoin -{ - /// @notice Send `(valueInmGAV / 1000).fixed(0,3)` GAV from the account of - /// `message.caller.address()`, to an account accessible only by `to.address()`. - /// @dev This is the developer documentation. - /// @param to The docs for the first param. - /// @param valueInmGav The docs for the second param. - function send(address to, uint256 valueInmGAV) { - if (balances[message.caller] >= valueInmGAV) { - balances[to] += valueInmGAV; - balances[message.caller] -= valueInmGAV; - } - } - - /// @notice `(balanceInmGAV / 1000).fixed(0,3)` GAV is the total funds available to `who.address()`. - function balance(address who) constant returns (uint256 balanceInmGAV) { - balanceInmGAV = balances[who]; - } - -invariants: - /// @notice The sum total amount of GAV in the system is 1 million. - reduce(0, add, map(valueOf, balances)) == 100000000000; - -construction: - /// @notice Endows `message.caller.address()` with 1m GAV. - balances[message.caller] = 100000000000; - -state: - mapping balances(address) returns uint256 with function(address a) returns uint256 { return a; }; -}; -``` - -This documentation would then allow the Ethereum browser to translate any message (and thus transaction) going in to this contract into English (and on to other languages hence). It would also allow a lay viewer to immediately discern what the contract conforms to; in this case they could see that it's premined in favour of the transaction sender and that the total amount of coins in the system never changes. - -For example, should a DApp, malicious or otherwise, attempt to send a transaction that gives all the user's GAV to itself, the user would, prior to signing and submission, receive a message saying something like: - -``` -Untrusted ÐApp "Foo Sprocket DApp" attempting to transact in your name: -Send 45.780 GAV from the account of Your Name Here to an account accessible only by Foo Sprocket DApp. -Do you wish to allow this? -``` - -Of course, they might be a bit more cunning and send it to an anonymous address, however, by differentiating friends' (and other known people) addresses from anonymous or untrusted addresses both visibly and clearly, we can imagine a mechanism that, at least for simple contracts, allow users a good level of security without excessive harm to their experience. - -### Getting the Documentation in - -The documentation, would be extracted from the source code ready to sit in a (probably JSON) file: - -``` -{ - "source": "...", - "language": "Solidity", - "languageVersion": 1, - "methods": { - "send": { "notice": "Send `(valueInmGAV / 1000).fixed(0,3)` GAV from the account of `message.caller.address()`, to an account accessible only by `to.address()`." }, - "balance": { "notice": "`(balanceInmGAV / 1000).fixed(0,3)` GAV is the total funds available to `who.address()`." } - }, - "invariants": [ - { "notice": "The sum total amount of GAV in the system is 1 million." } - ], - "construction": [ - { "notice": "Endows `message.caller.address()` with 1m GAV." } - ] -} -``` - -The full documentation format, that includes developer-specific documentation includes several more attributes: - -``` -{ - "author": "Gav Wood", - "description": "Some description of this contract.", - "methods": { - "send": { - "title": "Send some GAV.", - "details": "..." - }, - "balance": { - "title": "Send some GAV.", - "details": "..." - } - }, - "invariants": [ - { "title": "...", "details": "Markdown description of the first invariant." } - ], - "construction": { - "details": "Creates the contract with..." - } -} -``` - -This file would be hashed and distributed (either on a centralised website or, more preferably, through Swarm). It would be referenced by the Ethereum Singleton Trust contract in order to allow people or organisations that you know or trust to help inform you of its audit results and trustworth. Of course if you were a coder you could audit it manually (in this case it's pretty trivial) and determine how well the formal documentation matches the code, and also submit newer versions, perhaps in different languages that incorporate changes you feel are required to better descibe its actions & ramifications. - -### The ABI-Description File - -So the ABI description file ("header file") for the contract would be trivially derivable from the contract source code. It would be distributed by the author for anyone who wanted to message or transact with it. It would contain only enough information to compose the input data for a transaction and to decode the output data. Here's how the GAVCoin example contract would look: - -TODO: include `const`ness in the JSON: - -``` -[ - { "name": "send", "const": false, "input": [ { "name": "to", "type": "address" }, { "name": "valueInmGAV", "type": "uint256" } ], "output": [] }, - { "name": "balance", "const": true, "input": [ { "name": "who", "type": "address" } ], "output": [ { "name": "balanceInmGAV", "type": "uint256" } ] } -] -``` - -And that's it. Any questions to Gav. \ No newline at end of file diff --git a/Solidity-Changelog.md b/Solidity-Changelog.md deleted file mode 100644 index 6273ca08f..000000000 --- a/Solidity-Changelog.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -name: Solidity Changelog -category: ---- - -These contents moved. Please see https://github.com/ethereum/solidity/releases diff --git a/Solidity-Features.md b/Solidity-Features.md deleted file mode 100644 index e131facdb..000000000 --- a/Solidity-Features.md +++ /dev/null @@ -1,1084 +0,0 @@ ---- -name: Solidity Features -category: ---- - -This is a list to explain and demonstrate new Solidity features as soon as they are completed. -It is used as a kind of changelog and items introduced at some point might be changed at a later point. The official reference is the [Documentation](https://ethereum.github.io/solidity/) which should always reflect the current state of the language. - -## Special Type Treatment for Integer Literals - -[PT](https://www.pivotaltracker.com/story/show/83393282) Expressions only involving integer literals are now essentially treated as "big integers" (i.e. they do not overflow) until they are actually used with a non-literal. The type of the expression is only determined at that point as the smallest integer type that can contain the resulting value. Example: - -``` -contract IntegerLiterals { - function f() { - // The folloing would have caused a type error in earlier versions (cannot add int8 to uint8), - // now the value of x is set to 9 and the type to uint8. - var x = -1 + 10; - // It is even possible to use literals that do not fit any of the Solidity types as long as - // the final value is small enough. The value of y will be 1, its type uint8. - var y = (0x100000000000000000001 * 0x100000000000000000001 * 0x100000000000000000001) & 0xff; - } -} -``` - -## Contracts Inherit all Members from Address - -[PT](https://www.pivotaltracker.com/story/show/85006746) Contract types are implicitly convertible to `address` and explicitly convertible to and from all integer types. Furthermore, a contract type contains all members of the address type with the semantics applying to the contract's address, unless overwritten by the contract. - -``` -contract Helper { - function getBalance() returns (uint bal) { - return this.balance; // balance is "inherited" from the address type - } -} -contract IsAnAddress { - Helper helper; - function setHelper(address a) { - helper = Helper(a); // Explicit conversion, comparable to a downcast - } - function sendAll() { - // send all funds to helper (both balance and send are address members) - helper.send(this.balance); - } -} -``` - -## ABI requires arguments to be padded to 32 bytes - -[PT](https://www.pivotaltracker.com/story/show/85006670) The latest version of the ABI specification -requires arguments to be padded to multiples of 32 bytes. This is not a language feature that can be demonstrated as code examples. Please see the automated tests `SolidityEndToEndTests::packing_unpacking_types` and `SolidityEndToEndTests::packing_signed_types`. - -## Specify value and gas for function calls - -[PT](https://www.pivotaltracker.com/story/show/84983014) External functions have member functions "gas" and "value" that allow to change the default amount of gas (all) and wei (0) sent to the called contract. "new expressions" also have the value member. - -``` -contract Helper { - function getBalance() returns (uint bal) { return this.balance; } -} -contract Main { - Helper helper; - function Main() { helper = new Helper.value(20)(); } - /// @notice Send `val` Wei to `helper` and return its new balance. - function sendValue(uint val) returns (uint balanceOfHelper) { - return helper.getBalance.value(val)(); - } -} -``` - -## delete for structs - -[PT](https://www.pivotaltracker.com/story/show/82574620) `delete` clears all members of a struct. - -``` -contract Contract { - struct Data { - uint deadline; - uint amount; - } - Data data; - function set(uint id, uint deadline, uint amount) { - data.deadline = deadline; - data.amount = amount; - } - function clear(uint id) { delete data; } -} -``` - -Note that, unfortunately, this only works directly on structs for now, so I would propose to not announce "delete" as a feature yet. - -## Contract Inheritance - -[PT1](https://www.pivotaltracker.com/story/show/84976094) -[PT2](https://www.pivotaltracker.com/story/show/86666936) Contracts can inherit from each other. - -``` -contract owned { - function owned() { owner = msg.sender; } - address owner; -} - -// Use "is" to derive from another contract. Derived contracts can access all members -// including private functions and storage variables. -contract mortal is owned { - function kill() { if (msg.sender == owner) suicide(owner); } -} - -// These are only provided to make the interface known to the compiler. -contract Config { function lookup(uint id) returns (address adr) {} } -contract NameReg { function register(string32 name) {} function unregister() {} } - -// Multiple inheritance is possible. Note that "owned" is also a base class of -// "mortal", yet there is only a single instance of "owned" (as for virtual -// inheritance in C++). -contract named is owned, mortal { - function named(string32 name) { - address ConfigAddress = 0xd5f9d8d94886e70b06e474c3fb14fd43e2f23970; - NameReg(Config(ConfigAddress).lookup(1)).register(name); - } - -// Functions can be overridden, both local and message-based function calls take -// these overrides into account. - function kill() { - if (msg.sender == owner) { - address ConfigAddress = 0xd5f9d8d94886e70b06e474c3fb14fd43e2f23970; - NameReg(Config(ConfigAddress).lookup(1)).unregister(); -// It is still possible to call a specific overridden function. - mortal.kill(); - } - } -} - -// If a constructor takes an argument, it needs to be provided in the header. -contract PriceFeed is owned, mortal, named("GoldFeed") { - function updateInfo(uint newInfo) { - if (msg.sender == owner) info = newInfo; - } - - function get() constant returns(uint r) { return info; } - - uint info; -} -``` - -## Function Modifiers - -[PT](https://www.pivotaltracker.com/story/show/85007072) Modifiers can be used to easily change the behaviour of functions, for example to automatically check a condition prior to executing the function. They are inheritable properties of contracts and may be overridden by derived contracts. -``` -contract owned { - function owned() { owner = msg.sender; } - address owner; - - // This contract only defines a modifier but does not use it - it will - // be used in derived contracts. - // The function body is inserted where the special symbol "_" in the - // definition of a modifier appears. - modifier onlyowner { if (msg.sender == owner) _ } -} -contract mortal is owned { - // This contract inherits the "onlyowner"-modifier from "owned" and - // applies it to the "kill"-function, which causes that calls to "kill" - // only have an effect if they are made by the stored owner. - function kill() onlyowner { - suicide(owner); - } -} -contract priced { - // Modifiers can receive arguments: - modifier costs(uint price) { if (msg.value >= price) _ } -} -contract Register is priced, owned { - mapping (address => bool) registeredAddresses; - uint price; - function Register(uint initialPrice) { price = initialPrice; } - function register() costs(price) { - registeredAddresses[msg.sender] = true; - } - function changePrice(uint _price) onlyowner { - price = _price; - } -} -``` - -Multiple modifiers can be applied to a function by specifying them -in a whitespace-separated list and will be evaluated in order. -Explicit returns from a modifier or function -body immediately leave the whole function, while control flow reaching the -end of a function or modifier body continues after the "_" in the previous -modifier. -Arbitrary expressions are allowed for modifier arguments and in this context, -all symbols visible from the function are visible in the modifier. Symbols -introduced in the modifier are not visible in the function (as they might -change by overriding). - - -## Conversion between String and Hash types - -[PT](https://www.pivotaltracker.com/story/show/85907772) The explicit conversion between `string` and `hash` types of equal size is now allowed. Example: - -``` -contract Test { - function convert(hash160 h, string20 s) returns (string20 res_s, hash160 res_h) { - res_s = string20(h); - res_h = hash160(s); - } -} -``` - -## Access to super - -[PT](https://www.pivotaltracker.com/story/show/86688340) In the following contract, the function `kill` is overridden by sibling classes. Due to the fact that the sibling classes do not know of each other, they can only call `mortal.kill()` with the effect that one of the overrides is completely bypassed. A reasonable implementation would call the kill functions in all classes in the inheritance hierarchy. -``` -contract mortal { function kill() { suicide(msg.sender); } } -contract named is mortal { function kill() { /*namereg.unregister();*/ mortal.kill(); } } -contract tokenStorage is mortal { function kill() { /*returnAllTokens();*/ mortal.kill(); } } -contract MyContract is named, tokenStorage {} -``` - -The `super` keyword solves this. Its type is the type of the current contract if it were empty, i.e. it contains all members of the current class' bases. Access to a member of super invokes the usual virtual member lookup, but it ends just above the current class. Using this keyword, the following works as expected: -``` -contract mortal { function kill() { suicide(msg.sender); } } -contract named is mortal { function kill() { /*namereg.unregister();*/ super.kill(); } } -contract tokenStorage is mortal { function kill() { /*returnAllTokens();*/ super.kill(); } } -contract MyContract is named, tokenStorage {} -``` -## State Variable Accessors -[PT](https://www.pivotaltracker.com/story/show/86308642) Public state variables now have accessors created for them. Basically any `public` state variable can be accessed by calling a function with the same name as the variable. - -``` -contract test { - function test() { - data = 42; - } - uint256 data; -} -``` - -For example in the above contract if you tried to call test's `data()` method then you would obtain the result 42. - -``` -contract test { - function test() { - data = 42; - } -private: - uint256 data; -} -``` -On the other hand on the above contract there is no accessor generated since the state variable is private. - -## Events - -[PT](https://www.pivotaltracker.com/story/show/86896642) Events allow the convenient usage of the EVM logging facilities. Events are inheritable members of contracts. When they are called, they cause -the arguments to be stored in the transaction's log. Up to three parameters can receive the -attribute `indexed` which will cause the respective arguments to be treated as log topics instead -of data. The hash of the signature of the event is always one of the topics. All non-indexed -arguments will be stored in the data part of the log. Example: -``` -contract ClientReceipt { - event Deposit(address indexed _from, hash indexed _id, uint _value); - function deposit(hash _id) { - Deposit(msg.sender, _id, msg.value); - } -} -``` -Here, the call to `Deposit` will behave identical to -`log3(msg.value, 0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20, sha3(msg.sender), _id);`. Note that the large hex number is equal to the sha3-hash of "Deposit(address,hash256,uint256)", the event's -signature. - -## Fallback Functions - -[PT](https://www.pivotaltracker.com/story/show/87035858) A contract can have exactly one unnamed -function. This function cannot have arguments and is executed on a call to the contract if -none of the other functions matches the given function identifier (or if no data was supplied at all). - -``` -contract Test { - function() { x = 1; } - uint x; -} - -contract Caller { - function callTest(address testAddress) { - Test(testAddress).send(0); - // results in Test(testAddress).x becoming == 1. - } -} -``` - -## Events in Exported Interfaces - -[PT](https://www.pivotaltracker.com/story/show/87036508) Events are exported to the JSON and Solidity interfaces generated by the compiler. The contract -``` -contract c { - event ev(uint indexed a); -} -``` -generates the JSON interface -``` -[ - { - "inputs" : [ - { - "indexed" : true, - "name" : "a", - "type" : "uint256" - }, - { - "indexed" : false, - "name" : "b", - "type" : "uint256" - } - ], - "name" : "ev", - "type" : "event" - } -] -``` -and the Solidity interface -`contract c{event ev(uint256 indexed a,uint256 b);}`. - -## Visibility Specifiers - -[PT](https://www.pivotaltracker.com/story/show/86635568) Functions and storage variables can be specified as being `public`, `protected` or `private`, where the default for functions is `public` `protected` for storage variables. Public functions are part of the external interface and can be called externally, while for storage variables, an automatic accessor function is generated. Non-public functions are only visible inside a contract and its derived contracts (there is no distinction between `protected` and `private` for now). - -``` -contract c { - function f(uint a) private returns (uint b) { return a + 1; } - uint public data; -} -``` -External functions can call `c.data()` to retrieve the value of `data` in storage, but are not able to call `f`. - -## Numeric Literals with Ether Subdenominations -[PT](https://www.pivotaltracker.com/story/show/84986568) Numeric literals can also be followed by the common ether subdenominations and the value of the assigned to variable will be multiplied by the proper amount. -``` -contract c { - function c() - { - val1 = 1 wei; // 1 - val2 = 1 szabo; // 1 * 10 ** 12 - val3 = 1 finney; // 1 * 10 ** 15 - val4 = 1 ether; // 1 * 10 ** 18 - } - uint256 val1; - uint256 val2; - uint256 val3; - uint256 val4; -} -``` - -## SHA3 with arbitrary arguments -[PT](https://www.pivotaltracker.com/story/show/86896766). `sha3()` can now take an arbitrary number and type of arguments. -``` -contract c { - function c() - { - val2 = 123; - val1 = sha3("foo"); // sha3(0x666f6f) - val3 = sha3(val2, "bar", 1031); //sha3(0x7b626172407) - } - uint256 val1; - uint16 val2; - uint256 val3; -} -``` - -## Optional Parameter Names -[PT](https://www.pivotaltracker.com/story/show/85594334). The names for function parameters and return parameters are now optional. -``` -contract test { - function func(uint k, uint) returns(uint){ - return k; - } -} -``` - -## Generic call Method -[PT](https://www.pivotaltracker.com/story/show/86084248) Address types (and contracts by inheritance) have a method `call` that can receive an arbitrary number of arguments of arbitrary types (which can be serialized in memory) and will invoke a message call on that address while the arguments are ABI-serialized. If the first type has a memory-length of exactly four bytes, it is not padded to 32 bytes, so it is possible to specify a function signature. -``` -contract test { - function f(address addr, uint a) { - addr.call(string4(string32(sha3("fun(uint256)"))), a); - } -} -``` - -## Byte arrays -[PT](https://www.pivotaltracker.com/story/show/87037182) Basic support for variable-length byte arrays. This includes - - `bytes` type for storage variables - - `msg.data` is of `bytes` type and contains the calldata - - functions taking arbitrary parameters (`call`, `sha3`, ...) can be called with `bytes` arguments. - - copying between `msg.data` and `bytes` storage variables - -What is not possible yet: - - function parameters of `bytes` type - - local variables of `bytes` type - - index or slice access - -``` -contract c { - bytes data; - function() { data = msg.data; } - function forward(address addr) { addr.call(data); } - function getLength() returns (uint) { return addr.length; } - function clear() { delete data; } -} -``` - -## Enums -[PT](https://www.pivotaltracker.com/story/show/86670106) Solidity now supports enums. Enums are explicitly convertible to all integer types but implicit conversion is not allowed. - -``` -contract test { - enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill }; - function test() - { - choices = ActionChoices.GoStraight; - } - function getChoice() returns (uint d) - { - d = uint256(choices); - } - ActionChoices choices; - } -``` - -## Visibility Specifiers - -[PT](https://www.pivotaltracker.com/story/show/86487946) The visibility of a function can be specified by giving at most one of the specifiers `external`, `public`, `inheritable` or `private`, where `public` is the default. "External" functions can only be called via message-calls, i.e. from other contracts or from the same contract using `this.function()` (note that this also prevents calls to overwritten functions in base classes). Furthermore, parameters of "external" functions are immutable. "Public" functions can be called from other contracts and from the same contract using stack-based calls. "Inheritable" and "private" functions can only be called via stack-based calls, while "inheritable" functions are only visible in the contract itself and its derived contracts and "private" functions are not even visible in derived contracts. - -``` -contract Base { - function exte() external { } - function publ() public /* can be omitted */ { } - function inhe() inheritable { priv(); } - function priv() private { } -} -contract Derived is Base { - function g() { - this.exte(); - // impossible: exte(); - this.publ(); - publ(); - // impossible: this.inhe(); - inhe(); - // impossible: this.priv(); - // impossible: priv(); - } -} -``` - -## Import Statement -[PT](https://www.pivotaltracker.com/story/show/87165660) We can now import other contracts and/or standard library contracts using the `import` keyword. -``` -import "mortal"; - -contract Test is mortal { - // since we import the standard library "mortal" contract and we inherit from it - // we can call the kill() function that it provides - function killMe() { kill();} -} -``` - -## Inline members initialization -[PT](https://www.pivotaltracker.com/story/show/84982976) Inline members can be initialized at declaration time. -``` -contract test { - function test(){ - m_b = 6; - } - uint m_a = 5; - uint m_b; -} -``` - -## The arguments of the constructor of base contract -[PT](https://www.pivotaltracker.com/story/show/88454388) It is possible to pass arguments to the base contracts constructor. The arguments for the base constructor in the header will be optional later. -``` -contract Base { - function Base(uint i) - { - m_i = i; - } - uint public m_i; -} -contract Derived is Base(0) { - function Derived(uint i) Base(i) {} -} -``` - -## Detect failed CALLs -[PT](https://github.com/ethereum/cpp-ethereum/pull/1212) If a CALL fails, do not just silently continue. Currently, this issues a STOP but it will throw an exception once we have exceptions. -``` -contract C { - function willFail() returns (uint) { - address(709).call(); - return 1; - } -} -``` -`willFail` will always return an empty byte array (unless someone finds the correct private key...). - -## Basic features for arrays -[PT](https://www.pivotaltracker.com/story/show/84119688) Byte arrays and generic arrays of fixed and dynamic size are supported in calldata and storage with the following features: Index access, copying (from calldata to storage, inside storage, both including implicit type conversion), enlarging and shrinking and deleting. Not supported are memory-based arrays (i.e. usage in non-external functions or local variables), array accessors and features like slicing. -Access to an array beyond its length will cause the execution to STOP (exceptions are planned for the future). -``` -contract ArrayExample { - uint[7][] data; - bytes byteData; - function assign(uint[4][] input, bytes byteInput) external { - data = input; // will assign uint[4] to uint[7] correctly, would produce type error if reversed - byteData = byteInput; // bytes are stored in a compact way - } - function indexAccess() { - data.length += 20; - data[3][5] = data[3][2]; - byteData[2] = byteData[7]; // this will access sigle bytes - } - function clear() { - delete data[2]; // will clear all seven elements - data.length = 2; // clears everything after the second element - delete data; // clears the whole array - } -} -``` - -## Now Variable -[PT](https://www.pivotaltracker.com/story/show/89728640) The global scope contains an immutable variable called `now` which is an alias to `block.timestamp`, i.e. it contains the timestamp of the current block. -``` -contract TimedContract { - uint timeout = now + 4 weeks; -} -``` - -## HashXX and StringXX to bytesXX -[Link to PT] (https://www.pivotaltracker.com/story/show/88146508) -+ We replace `hash(XX*8)` and `stringXX` by `bytesXX`. -+ `bytesXX` behaves as `hash(XX*8)` in terms of convertability and operators and as `stringXX` in terms of layout in memory (alignment, etc). - -+ `byte` is an alias for `bytes1`. - -+ `string` is reserved for future use. - - -## `msg.sig` returns the function's signature hash -[Link to PT] (https://www.pivotaltracker.com/story/show/86896308) -New magic type `msg.sig` that will provide the hash of the current function signature as `bytes4` type. - -``` -contract test { - function foo(uint256 a) returns (bytes4 value) { - return msg.sig; - } -} -``` - -Calling that function will return `2FBEBD38` which is the hash of the signature of `foo(uint256)`. - -## Constant variables -[PT](https://www.pivotaltracker.com/story/show/86670364) -Added `constant` specifier for uint, mapping and bytesXX types. Variables declared with `constant` specifier should be initialized at declaration time and can not be changed later. For now local variables can not be constant. Constant variables are not stored in Storage. - -``` -contract Foo { - function getX() returns (uint r) { return x; } - uint constant x = 56; -} -``` - -## Anonymous Events -[PT](https://www.pivotaltracker.com/story/show/89518344) -Added `anonymous` specifier for Event. For the event declared as anonymous the hash of the signature of the event will not be added as a first topic. The format is - -``` -event ([index list]) anonymous; -``` -Anonymous property is also visible for ABI document. - -## Tightly packed storage - -[PT](https://www.pivotaltracker.com/story/show/90011896) -Items in storage are packed tighly as far as possible according to the following rules: - - - The first item in a storage slot is stored lower-order aligned. - - Elementary types use only that many bytes that are necessary to store them. - - If an elementary type does not fit the remaining part of a storage slot, it is moved to the next storage slot. - - Structs and array data always start a new slot and occupy whole slots (but items inside a struct or array are packed tightly according to these rules). - -Examples: -``` -contract C { - uint248 x; // 31 bytes: slot 0, offset 0 - uint16 y; // 2 bytes: slot 1, offset 0 (does not fit in slot 0) - uint240 z; // 30 bytes: slot 1, offset 2 bytes - uint8 a; // 1 byte: slot 2, offset 0 bytes - struct S { - uint8 a; // 1 byte, slot +0, offset 0 bytes - uint256 b; // 32 bytes, slot +1, offset 0 bytes (does not fit) - } - S structData; // 2 slots, slot 3, offset 0 bytes (does not really apply) - uint8 alpha; // 1 byte, slot 4 (start new slot after struct) - uint16[3] beta; // 3*16 bytes, slots 5+6 (start new slot for array) - uint8 gamma; // 1 byte, slot 7 (start new slot after array) -} -``` - -## Common Subexpression Elimination Excluding Memory and Storage - -[PT](https://www.pivotaltracker.com/story/show/89148380) -The optimizer splits code into blocks (at all operations that have non-local side effects like JUMP, CALL, CREATE and for also all instructions that access or modify memory or storage), analyses these blocks by creating an expression graph and establishes equivalences in a bottom-up way, simplifying expressions that e.g. involve constants. In the following code-generation phase, it re-creates the set of instructions that transform a given initial stack configuration into a given target stack configuration utilizing the simplest representatives of these equivalence classes. -In conjunction with the already present jump-optimization, the two code snippets given below should be compiled into the same sequence of instructions: -``` -contract test { - function f(uint x, uint y) returns (uint z) { - var c = x + 3; - var b = 7 + (c * (8 - 7)) - x; - return -(-b | 0); - } -} -``` -``` -contract test { - function f(uint x, uint y) returns (uint z) { - return 10; - } -} -``` - -## Common Subexpression Elimination for Memory and Storage - -[PT](https://www.pivotaltracker.com/story/show/90785926) -This adds support for memory and storage operations to the common subexpression eliminator. This makes it possible to e.g. stretch the equality inference engine across SSTORE, MSTORE and even SHA3 computations (which go via memory). Without optimizer (because of packed storage), there are 4 SLOAD, 3 SSTORE and 4 SHA3 operations. The optimizer reduces those to a single SLOAD, SHA3 and SSTORE each. -``` -contract test { - struct s { uint8 a; uint8 b; uint8 c; } - mapping(uint => s) data; - function f(uint x, uint8 _a, uint8 _b, uint8 _c) { - data[x].a = _a; - data[x].b = _b; - data[x].c = data[x].a; - } -} -``` -## External Types -[PT](https://www.pivotaltracker.com/story/show/88772706) -All functions with visibility more than internal should have external types (ABI types) otherwise raise an error. -For Contract type external type is address type. -``` -contract Foo {} -contract Test { - function func() { - Foo arg; - this.Poo(arg); - Poo(arg); - } - function Poo(Foo c) external {} -} -``` -the ABI interface for Poo is Poo(address) when the Solidity interface is still Poo(Foo). - -## Accessor for Arrays -[PT](https://www.pivotaltracker.com/story/show/88500646) -For Arrays the accessor is generated which accepts the index as parameter and returns an array element -``` -contract test { - uint[3] public data; - function test() { - data[0] = 0; - data[1] = 1; - data[2] = 2; - } -} -``` -In the above contract if you tried to call the data(1) method of the test you would obtain the result 1. - -## Overloading Functions -[PT](https://www.pivotaltracker.com/story/show/85511572) Contracts can have multiple functions of the same name as long as the parameters differ in number or type. If such an overloaded function is referenced, it has to be called immediately to resolve the ambiguity using the types of the arguments. It is an error if not exactly one of the possible functions can be called with the given arguments. - -``` -contract Base { - function f(uint a) {} -} -contract Derived is Base { - function f(uint8 b) {} - function g() { - // f(250); would create a type error since 250 can be implicitly - // converted both to a uint8 and to a uint type - f(2000); // calls f from Base - } -} -``` -Of course overloading a function does not need inheritance, i.e. `f(uint a)` could as well have been defined directly in `Derived`. - -Overloaded functions are also present in the external interface. It is an error if two externally visible functions differ by their Solidity types but not by their external types, e.g. `f(Derived _d)` and `f(address _a)` both end up accepting an `address` type for the ABI although they are considered different inside Solidity. - -## Merging of Basic Blocks -[PT](https://www.pivotaltracker.com/story/show/89148124) Blocks of assembly instructions that do not contain jumps, stops or returns are moved and modified according to the following rules: - -* if the control never simply flows into a block, but it is jumped to unconditionally, the block is moved, eliminating the jump -* blocks that are never jumped to are removed - -These optimizations might sound not very powerful, but together with "Common Subexpression Elimination" (which is does much more than its name might suggest), the following contract is optimized to store `8` in the mapping and return the value without any jump. - -``` -contract c { - function () returns (uint) { return g(8); } - function g(uint pos) internal returns (uint) { setData(pos, 8); return getData(pos); } - function setData(uint pos, uint value) internal { data[pos] = value; } - function getData(uint pos) internal { return data[pos]; } - mapping(uint => uint) data; -} -``` - -## Interface contracts - -[PT](https://www.pivotaltracker.com/story/show/88344782) Contracts can be marked as "not fully implemented" by containing at least one abstract function. A function is abstract if it does not have a body defined. - -``` -contract base { function foo(); } -contract derived is base { function foo() {} } -``` - -For example in the above, foo is an abstract function and as such the base contract is an interface contract. All non-interface contracts that derive from it must implement its abstract functions. - -## Bare Callcode - -[PT](https://www.pivotaltracker.com/story/show/94682212) The address type receives a method `callcode` which is similar to `call`, but uses `CALLCODE` instead of `CALL` when the function is invoked. This means that the code at the given address will be executed in the context of the current contract. Example: - -``` -contract Code { - uint m_data; - function (uint v) { m_data = v; } -} -contract ActualContract { - uint public m_data; - function f() { Code(0x12345).callcode(7); } -} -``` -Assuming the contract `Code` is deployed at the address `0x12345`, calling `f()` of `ActualContract` will result in `m_data` of `ActualContract` being modified. The user has to ensure that the layout of storage in both contracts is suitable for callcode to be used. - -## Gas Estimation - -[PT](https://www.pivotaltracker.com/story/show/90098268) Solidity provides two ways to compute an upper bound on the gas usage of code: A structural one, which can be used to identify expensive statements and a functional one which tries to give an exact gas estimation for each function. -Some gas costs depend on the state of the virtual machine, e.g. on the cost of `sha3` depends on the length of the argument and writing to storage has different costs depending on whether the storage slot had the value zero or not. - -For the structural gas estimation, the gas cost of each opcode is computed assuming the intersection of all states in which the VM could reach this opcode. These costs are accumulated for each opcode that results from a specific statement (in some situations also other AST nodes) in the AST. So in this mode, opcodes are not counted multiple times even if they occur in loops. - -The functional gas estimation takes a different approach: For each function in a contract, the execution of this function is "simulated". As we want to provide an upper bound on the gas costs independent of the actual arguments, this is sometimes not accurate and may even result in "infinite" gas costs. Note that the gas costs of message-called functions are not included in the gas costs of a function. - -## Re-introduce string type - -[PT](https://www.pivotaltracker.com/story/show/95173586) -`string` is added as a type which behaves exactly like `bytes` with the following differences: - - index access is not allowed - - it does not have a length member - -In the ABI encoding (wiki already changed), string is a dynamic type whose "number of elements" field is the number of bytes, not the number of characters. -The encoding of the string is assumed to be UTF-8, but is not yet used inside Solidity. - -## In-memory types - -[PT](https://www.pivotaltracker.com/n/projects/1189488/stories/88238440) -Variables of reference type (structs and arrays including `string` and `bytes`) can either point to memory, storage or calldata. The keywords `storage` and `memory` as part of their declaration are used to indicate that (calldata cannot be used explicitly). Parameters (not return parameters) of external functions are forced to point to calldata. Parameters (also return parameters) of public and return parameters of external functions are forced to point to memory. In all other cases, if neither storage nor memory is given, function parameters default to point to memory and local variables default to point to storage. - -Note that this story enforces the constraints on memory-stored structs, but does not yet fully implement the code-generation part. Arrays, on the other hand, are fully implemented. - -As part of this change, references to storage are also cleaned up: An assignment of a state variable to a local variable or temporary converts it from a reference to a pointer. Assignments to storage pointers do not modify storage but only change the pointer. This means that it is not possible to assign a memory array to a storage pointer. Furthermore, it is illegal to pass a memory-array as an argument to a function that requires a storage reference (note that storage is statically allocated, i.e. there is no place to put this value). Es an example: -```js -contract c { - uint[] x; - function f(uint[] memoryArray) { - x = memoryArray; // works, copies the array to storage - var y = x; // works, assigns a pointer - y[7]; // fine, returns the 8th element - y.length = 2; // fine, modifies storage - delete x; // fine, clears the array - // y = memoryArray; // does not work, would need to create a new temporary / unnamed array in storage, but storage is "statically" allocated - // delete y; // does not work, would set pointer to zero and does not make sense for pointer - } -} -``` - -If possible (i.e. from anything to memory and from anything to a storage reference that is not a pointer), conversions between these data locations are performed automatically by the compiler. Sometimes, this is still not possible, i.e. mappings cannot reside in memory (as their size is unknown) and for now, some types in memory are not yet implemented, this includes structs and multi-dimensional arrays. - -Of course, once a storage array is converted to memory, modifications do not affect the array in storage. You can either assign the modified array back to storage (though this would be vastly inefficient) or you can pass around a storage pointer to begin with. As an example: - -```js -contract BinarySearch { - /// Finds the position of _value in the sorted list _data. - /// Note that "internal" is important here, because storage references only work for internal or private functions - function find(uint[] storage _data, uint _value) internal returns (uint o_position) { - return find(_data, 0, _data.length, _value); - } - function find(uint[] storage _data, uint _begin, uint _len, uint _value) private returns (uint o_position) { - if (_len == 0 || (_len == 1 && _data[_begin] != _value)) - return uint(-1); // failure - uint halfLen = _len / 2; - uint v = _data[_begin + halfLen]; - if (_value < v) - return find(_data, _begin, halfLen, _value); - else if (_value > v) - return find(_data, _begin + halfLen + 1, halfLen - 1, _value); - else - return _begin + halfLen; - } -} -``` - - -On memory usage: Since memory is wiped after each external function call, the Solidity runtime does not include proper memory management. It includes a "level indicator" which points to the next free memory slot. If memory is needed (because a storage object is copied to memory or an external function is called), it is allocated starting from this pointer. Functions that return objects stored in memory will not reset this pointer. This means that temporary memory objects will still take up space in memory even if they are not needed anymore. On the other hand, if a function does not return any memory-stored object, it resets the pointer to the value it had upon function entry (this is not yet implemented). - -The EVM does not allow `CALL` to be used with variably-sized return values. Because of this, return types of message-called functions which are dynamically sized are transparently changed to `void`. Clearing up the confusion which might arise in face of the resulting error message remains to do. - -Memory-stored objects as local variables are correctly zero-initialised: Members of structs and elements of fixed-size arrays are recursively initialised, dynamic arrays are set to zero length. `delete x` assigns a new zero-initialised value to `x`. - -## Positive integers conversion to signed - -[PT](https://www.pivotaltracker.com/n/projects/1189488/stories/92691082) -Positive integer literals are now convertible to signed if in value range. -``` -int8 x = 2; -``` - -## Exceptions in Solidity - -[PT](https://www.pivotaltracker.com/n/projects/1189488/stories/92929256) -Currently, there are two situations, where exceptions can happen in Solidity: If you access an array beyond its length (i.e. x[i] where i >= x.length) or if a function called via a message call does not finish properly (i.e. it runs out of gas or throws an exception itself). In such cases, Solidity will trigger an "invalid jump" and thus cause the EVM to revert all changes made to the state. - -It is planned to also throw and catch exceptions manually. - -## Structs in Memory - -[PT](https://www.pivotaltracker.com/n/projects/1189488/stories/84119690) -Structs can be passed around as function arguments, be returned from functions -and created in memory. - -```js -contract C { - struct S { uint a; uint b; } - struct A { uint x; uint y; S s; } - A data; - function f() internal returns (A) { - // Construct structs inline, pass to a function and return from it. - // Memory is allocated only once, pointers are passed around. - // Construction by member name is possible. - return g(A(5, 7, S({b: 1, a: 2}))); - } - function g(A _a) internal returns (A) { - _a.s.b = 2; - data = _a; // performs a copy - return _a; - } -} -``` - -## Flexible String Literals - -[PT](https://www.pivotaltracker.com/n/projects/1189488/stories/98462528) -String literals can be implicitly converted to `bytesX` (if they are not too long), -`string` and `bytes`, especially, they can be much longer than 32 bytes. - -```js -contract C { - bytes32 x; - function greet() returns (string) { - x = "Hello, World!"; - return "Hello, World!"; - } -} -``` - -## Strings as Mapping Keys - -Strings are allowed as keys for mappings. -```js -contract C { - mapping (string => uint) counter; - function inc(string _s) { counter[_s]++; } -} -``` - -## Libraries (without inheritance) - -[PT](https://www.pivotaltracker.com/n/projects/1189488/stories/82180360) - -Libraries are similar to contracts, but their purpose is that they are deployed only once at a specific address and their functions are called using CALLCODE, i.e. the library's code is called in the context of the calling contract. - -```js -library Math { - function max(uint a, uint b) returns (uint) { - if (a > b) return a; - else return b; - } - function min(uint a, uint b) returns (uint) { - if (a < b) return a; - else return b; - } -} -contract C { - function register(uint value) { - value = Math.max(10, Math.min(100, value)); // clamp value to [10, 100] - // ... - } -} -``` - -The calls to `Math.max` and `Math.min` are both compiled as calls (CALLCODEs) to an external contract. as the compiler cannot know where the library will be deployed at, these addresses have to be filled into the final bytecode by a linker. If the addresses are not given as arguments to the compiler, the compiled hex code will contain placeholders of the form `__Math______` (where `Math` is the name of the library). The address can be filled manually by replacing all those 40 symbols by the hex encoding of the address of the library contract. - -Restrictions for libraries in comparison to contracts: - - no state variables - - cannot inherit nor be inherited - -(these might be lifted at a later point) - -How to use the commandline compiler to link binaries: - -New option `--libraries` to either give a file containing the library addresses or directly as a string (tries to open as a file). Syntax: `:
[, or Whitespace] ...` -The address is a hex string that is optionally prefixed with `0x`. - -If solc is called with the option `--link`, all input files are interpreted to be unlinked binaries (hex-encoded) and are linked in-place (if the input is read from stdin, it is written to stdout). -All options except `--libraries` are ignored (including `-o`). - -## Throw - -[PT](https://www.pivotaltracker.com/story/show/96275370) - -throw is a statement that triggers a solidity exception and thus can be used to revert changes made during the transaction. It does not take any parameters and jumps to the error tag. -``` -contract Sharer { - function sendHalf(address addr) returns (uint balance) { - if (!addr.send(msg.value/2)) - throw; // also reverts the transfer to Sharer - return address(this).balance; - } -} -``` - -## Tightly Stored Byte Arrays and Strings - -[PT](https://www.pivotaltracker.com/story/show/101758652) - -Byte arrays (`bytes`) and strings (`string`) are stored more tightly packed in storage: -Short values (less than 32 bytes) are stored directly together with the length: -`` (the 31 higher-significant bytes contain the value, the least significant byte contains the doubled length) -Long values (at least 32 bytes) are stored as they were stored before, just that the length is doubled and the least significant bit is set to one to indicate "long string". - -Example: "abcdef" is stored as `0x61626364656600000...000d` while `"abcabcabc....abc"` (of length 40) is stored as `0x0000000...0051` in the main slot, and `616263616263...` is stored in the data slots. - -## Internal Types for Libraries - -[PT](https://www.pivotaltracker.com/story/show/101774798) Storage reference types are allowed to be passed to library functions. Together with this change, it is now possible to access internal types of other contracts and libraries and a compiler version stamp is added at the beginning of library runtime code. - -Example: - -``` -/// @dev Models a modifiable and iterable set of uint values. -library IntegerSet -{ - struct data - { - /// Mapping item => index (or zero if not present) - mapping(uint => uint) index; - /// Items by index (index 0 is invalid), items with index[item] == 0 are invalid. - uint[] items; - /// Number of stored items. - uint size; - } - function insert(data storage self, uint value) returns (bool alreadyPresent) - { - uint index = self.index[value]; - if (index > 0) - return true; - else - { - if (self.items.length == 0) self.items.length = 1; - index = self.items.length++; - self.items[index] = value; - self.index[value] = index; - self.size++; - return false; - } - } - function remove(data storage self, uint value) returns (bool success) - { - uint index = self.index[value]; - if (index == 0) - return false; - delete self.index[value]; - delete self.items[index]; - self.size --; - } - function contains(data storage self, uint value) returns (bool) - { - return self.index[value] > 0; - } - function iterate_start(data storage self) returns (uint index) - { - return iterate_advance(self, 0); - } - function iterate_valid(data storage self, uint index) returns (bool) - { - return index < self.items.length; - } - function iterate_advance(data storage self, uint index) returns (uint r_index) - { - index++; - while (iterate_valid(self, index) && self.index[self.items[index]] == index) - index++; - return index; - } - function iterate_get(data storage self, uint index) returns (uint value) - { - return self.items[index]; - } -} - -/// How to use it: -contract User -{ - /// Just a struct holding our data. - IntegerSet.data data; - /// Insert something - function insert(uint v) returns (uint size) - { - /// Sends `data` via reference, so IntegerSet can modify it. - IntegerSet.insert(data, v); - /// We can access members of the struct - but we should take care not to mess with them. - return data.size; - } - /// Computes the sum of all stored data. - function sum() returns (uint s) - { - for (var i = IntegerSet.iterate_start(data); IntegerSet.iterate_valid(data, i); i = IntegerSet.iterate_advance(data, i)) - s += IntegerSet.iterate_get(data, i); - } -} -``` - -## Destructuring Assignments - -[PT](https://www.pivotaltracker.com/story/show/99085194) Inline tuples can be created and assigned to newly declared local variables or already existing lvalues. This makes it possible to access multiple return values from functions. - -``` function f() returns (uint, uint, uint) { return (1,2,3); }``` -``` -var (a,b,c) = f(); -var (,x,) = f(); -var (,y) = f(); -var (z,) = f(); -``` -For newly declared variables it is not possible to specify the types of variables, they will be inferred from the assigned value. Any component in the assigned tuple can be left out. If the first or last element is left out, they can consume an arbitrary number of values. At the end of this code, we will have: -`a == 1`, `b == 2`, `c == 3`, `x == 2`, `y == 3`, `z == 1`. - -For newly constructed tuples, elements may not be left out, except for one special case that allows to distiguish between 1-tuples and single expressions: `(x)` is equivalent to `x`, but `(x,)` is a 1-tuple containing `x`. - -Assigning to pre-existing lvalues is similar to declaring multiple variables and also allows wildcards: - -``` -contract c { - string s; - struct Data {uint a; uint b;} - mapping(uint => Data) data; - function f() { - (s, data[45]) = ("abc", Data(1, 2)); - } -} -``` - -## `.push()` for Dynamic Storage Arrays - -Dynamically-sized storage arrays have a member function `push`, such that -`var l = arr.push(el);` is equivalent to `arr[arr.length++] = el; var l = arr.length;`. - -``` -contract c { - struct Account { address owner; uint balance; } - Account[] accounts; - function newAccount(address _owner, uint _balance) { - accounts.push(Account(_owner, _balance)); - } -} - -``` \ No newline at end of file diff --git a/Solidity-Tutorial.md b/Solidity-Tutorial.md deleted file mode 100644 index 737ccc077..000000000 --- a/Solidity-Tutorial.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -name: Solidity Tutorial -category: ---- - -Solidity is a high-level language whose syntax is similar to that of JavaScript and it is designed to compile to code for the Ethereum Virtual Machine. This -tutorial starts with a basic introduction to Solidity and assumes some knowledge of -the Ethereum Virtual Machine and programming in general. It tries to explain all features present in the language but does not cover features like -the [natural language specification](Ethereum-Natural-Specification-Format) -or formal verification and is also not meant as a final specification -of the language. - -See also [Russian version (русский перевод)](https://github.com/ethereum/wiki/wiki/%D0%A0%D1%83%D0%BA%D0%BE%D0%B2%D0%BE%D0%B4%D1%81%D1%82%D0%B2%D0%BE-%D0%BF%D0%BE-Solidity) ->>>>>>> 787d2cbb44d0ad68fdc567516393c19127d08270 - -*** - -English version moved to a new [site](https://solidity.readthedocs.io/en/latest/). diff --git a/Solidity-standard-library.md b/Solidity-standard-library.md deleted file mode 100644 index afc10ce8d..000000000 --- a/Solidity-standard-library.md +++ /dev/null @@ -1,156 +0,0 @@ ---- -name: Solidity Standard Library -category: ---- - -# Solidity standard library - -### overview - -This is poc of solidity standard library. -Probably all of the contracts, but `owned` && `mortal` will be removed soon. - -Here is solidity tutorial prepared by Eris team. [Click](https://eng.erisindustries.com/tutorials/2015/03/11/solidity-1/) - - -### contracts - -- [owned](#owned) -- [mortal](#mortal) - - -#### owned -``` -contract owned{ - function owned() { - owner = msg.sender; - } - - modifier onlyowner() { - if(msg.sender==owner) _ - } - - address owner; -} -``` - -#### mortal - -``` -import "owned"; - -contract mortal is owned { - function kill() { - if (msg.sender == owner) suicide(owner); - } -} -``` - -### poc_contracts -- [Coin](#coin1) -- [Config](#config) -- [CoinReg](#coinreg) -- [configUser](#configuser) -- [Config](#config) -- [named](#named) -- [NameReg](#namereg) -- [service](#service) -- [std](#std) - -#### coin -``` -import "CoinReg"; -import "Config"; -import "configUser"; - -contract coin is configUser { - function coin(string3 name, uint denom) { - CoinReg(Config(configAddr()).lookup(3)).register(name, denom); - } -} -``` - -#### Coin -``` -contract Coin { - function isApprovedFor(address _target,address _proxy) constant returns(bool _r) {} - function isApproved(address _proxy)constant returns(bool _r){} - function sendCoinFrom(address _from,uint256 _val,address _to){} - function coinBalanceOf(address _a)constant returns(uint256 _r){} - function sendCoin(uint256 _val,address _to){} - function coinBalance()constant returns(uint256 _r){} - function approve(address _a){} -} -``` - -#### CoinReg -``` -contract CoinReg { - function count()constant returns(uint256 r){} - function info(uint256 i)constant returns(address addr,string3 name,uint256 denom){} - function register(string3 name,uint256 denom){}function unregister(){} -} -``` - -#### configUser -``` -contract configUser { - function configAddr()constant returns(address a){ - return 0xc6d9d2cd449a754c494264e1809c50e34d64562b; - } -} -``` - -#### Config -``` -contract Config { - function lookup(uint256 service)constant returns(address a){} - function kill(){}function unregister(uint256 id){} - function register(uint256 id,address service){} -} -``` - -#### configUser -``` -import "Config"; -import "NameReg"; -import "configUser"; - -contract named is configUser { - function named(string32 name) { - NameReg(Config(configAddr()).lookup(1)).register(name); - } -} -``` - -#### NameReg -``` -contract NameReg { - function register(string32 name){} - function addressOf(string32 name)constant returns(address addr){} - function unregister(){}function nameOf(address addr)constant returns(string32 name){} -} -``` - - -#### service -``` -import "Config"; -import "configUser"; - -contract service is configUser { - function service(uint _n){ - Config(configAddr()).register(_n, this); - } -} -``` - -#### std -``` -import "owned"; -import "mortal"; -import "Config"; -import "configUser"; -import "NameReg"; -import "named"; -``` \ No newline at end of file diff --git a/Solidity.md b/Solidity.md deleted file mode 100644 index b819e94e1..000000000 --- a/Solidity.md +++ /dev/null @@ -1,128 +0,0 @@ ---- -name: Solidity -category: ---- - -## This page might be outdated. - -Solidity is probably the first example of a Contract-Oriented Language, a slight reworking of the well-established group of Object-Oriented Languages. Here's an example of Solidity: - -``` -contract PriceFeed is owned, mortal, priced, named("GoldFeed") -{ - function updateInfo(uint newInfo) onlyowner { - info = newInfo; - } - - function get() constant costs returns(uint r) { - r = info; - } - - uint info; -} -``` - -From the syntax, it will feel mostly similar to something between JavaScript and C++ but with a number of additions to make it suitable for writing contracts within Ethereum. Language additions include: - -* static typing; -* property-based language transforms; -* contracts as first-class entities; -* state as part of a contract able to map & segment information into the permanent storage; -* invariants, pre- and post-conditions as part of a contract; -* variadic return values with named components; -* a safe language subset allowing guaranteed static analysis & proofs; -* an inbuilt test-generation and execution environment for situations where formal proofing is not practical. - -### Documentation - -It is expected that each method, together with the contract itself, will be documented in several ways. Aside from informal descriptions, each method should come with a formalised method to describe exactly its effect on the state of Ethereum. It should also include, where possible, pre- and post-conditions on the contract state, and the contract itself should include invariants over its own state, again each translated into natural language. - -For GavCoin, a meta coin that that is sub-divisible down to 1,000, and includes two functions `balance` and `send`, we might see the basic, undocumented contract as: - -``` -contract GavCoin is named("GavCoin") -{ - function GavCoin() { - balances[transaction.sender] = 100000000000; - } - function send(address to, uint256 valueInmGAV) { - balances[to] += valueInmGAV; - balances[transaction.sender] -= valueInmGAV; - } - function balance(address who) constant returns (uint256 balanceInmGAV) { - balanceInmGAV = balances[who]; - } - - invariant reduce(0, +, map(valueOf, balances)) == 100000000000; - - mapping (address => uint256) balances; -}; -``` - -Of course it is wrong. A static checker will analyse this (with the language assertion that the uint256 type must not be allowed to underflow unless explicitly given that attribute) and come back with something like: - -``` -Line 8: >>> balances[transaction.sender] -= valueInmGAV <<<: - balances[...] may underflow with '-=' operation using unbounded operand valueInmGAV. - Suggestion: surround code with conditional to bound operand valueInmGAV. -``` - -This is basically saying that it can see no reason why `valueInmGAV` could be no bigger than `balances[transaction.sender]`. And it's right. We forgot to check the parameters. It's easily fixed by adding the conditional and altering the method to: - -``` - void send(address to, uint256 valueInmGAV) { - if (balances[transaction.sender] >= valueInmGAV) { - balances[to] += valueInmGAV; - balances[transaction.sender] -= valueInmGAV; - } - } -``` - -This would then be formally documented: - -``` -/// @title Some title here. -/// @author Homer Simpson -contract GavCoin is named("GavCoin") -{ - /// @notice Endows `message.caller.address()` with 1m GAV. - function GavCoin() { - balances[transaction.sender] = 100000000000; - } - - /// @notice Send `(valueInmGAV / 1000).fixed(0,3)` GAV from the account of - /// `message.caller.address()`, to an account accessible only by `to.address()`. - /// @dev This is the developer documentation. - /// @param to The docs for the first param. - /// @param valueInmGav The docs for the second param. - function send(address to, uint256 valueInmGAV) { - if (balances[message.caller] >= valueInmGAV) { - balances[to] += valueInmGAV; - balances[message.caller] -= valueInmGAV; - } - } - - /// @notice `(balanceInmGAV / 1000).fixed(0,3)` GAV is the total funds available to `who.address()`. - function balance(address who) constant returns (uint256 balanceInmGAV) { - balanceInmGAV = balances[who]; - } - - /// @notice The sum total amount of GAV in the system is 1 million. - invariant reduce(0, add, map(valueOf, balances)) == 100000000000; - - mapping (address => uint256) balances; -}; -``` - -This documentation would then allow the Ethereum browser to translate any message (and thus transaction) going in to this contract into English (and on to other languages hence). It would also allow a lay viewer to immediately discern what the contract conforms to; in this case they could see that it's premined in favour of the transaction sender and that the total amount of coins in the system never changes. - -For example, should a DApp, malicious or otherwise, attempt to send a transaction that gives all the user's GAV to itself, the user would, prior to signing and submission, receive a message saying something like: - -``` -Untrusted ÐApp "Foo Sprocket DApp" attempting to transact in your name: -Send 45.780 GAV from the account of Your Name Here to an account accessible only by Foo Sprocket DApp. -Do you wish to allow this? -``` - -Of course, they might be a bit more cunning and send it to an anonymous address, however, by differentiating friends' (and other known people) addresses from anonymous or untrusted addresses both visibly and clearly, we can imagine a mechanism that, at least for simple contracts, allow users a good level of security without excessive harm to their experience. - diff --git a/Standardized_Contract_APIs.md b/Standardized_Contract_APIs.md deleted file mode 100644 index 68ccb0a68..000000000 --- a/Standardized_Contract_APIs.md +++ /dev/null @@ -1,295 +0,0 @@ ---- -name: Standardized Contract APIs -category: ---- - -Ethereum allows you to standardize common use cases that allow users and applications to more easily interact with each other. This includes currency units, registering names, making offers on exchanges, and other similar functions. A standard typically consists of function signatures for methods, eg. `send`, `register`, `delete`, providing the set of arguments and their formats in the [Ethereum contract ABI](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI) language. - -The standards described below have sample implementations available [here](https://github.com/ethereum/dapp-bin/tree/master/standardized_contract_apis). - -All function names are in lower camelCase (eg. `sendCoin`), and all event names are in upper CamelCase (eg. `CoinTransfer`). - -Input variables are in underscore-prefixed lower camelCase (eg. `_offerId`). - -Output variables are `_r` for pure getter (ie. constant) functions - `_success` (always boolean) when denoting success or failur, and other values (eg. `_maxValue`) for methods that perform an action but need to return a value as an identifier. -Addresses are referred to using `_address` when generic, and otherwise if a more specific description exists (eg. `_from`, `_to`). - -# Transferable Fungibles - -Also known as tokens, coins and sub-currencies. - -## Token - -### Methods - -#### transfer - -```js -transfer(address _to, uint256 _value) returns (bool success) -``` -Send `_value` amount of coins to address `_to` - -#### transferFrom - -```js -transferFrom(address _from, address _to, uint256 _value) returns (bool success) -``` -Send `_value` amount of coins from address `_from` to address `_to` - -#### balanceOf - -```js -balanceOf(address _address) constant returns (uint256 balance) -``` -Get the account balance of another account with address `_address` - ---- -The `transferFrom` method is used for a "direct debit" workflow, allowing contracts to send coins on your behalf, for example to "deposit" to a contract address and/or to charge fees in sub-currencies. The command should fail unless the `_from` account has deliberately authorized the sender of the message via some mechanism. We propose these standardized APIs for approval: - -#### approve - -```js -approve(address _address) returns (bool _success) -``` -Allow `_address ` to direct debit from your account with full custody. Only implement if absolutely required and use carefully. See `approveOnce` below for a more limited method. - -#### unapproved - -```js -unapprove(address _address) returns (bool _success) -``` -Unapprove address `_address ` to direct debit from your account if it was previously approved. Must reset both one-time and full custody approvals. - -#### isApprovedFor - -```js -isApprovedFor(address _target, address _proxy) constant returns (bool _r) -``` -Returns 1 if `_proxy` is allowed to direct debit from `_target` - -#### approveOnce - -```js -approveOnce(address _address, uint256 _maxValue) returns (bool _success) -``` -Makes a one-time approval for `_address ` to send a maximum amount of currency equal to `_maxValue` - -#### isApprovedOnceFor - -```js -isApprovedOnceFor(address _target, address _proxy) returns (uint256 _maxValue) -``` -Returns `_maxValue` if `_proxy` is allowed to direct debit the returned `_maxValue` from address `_target` only once. The approval must be reset on any transfer by `_proxy` of `_maxValue` or less. - -### Events -#### Transfer - -```js -Transfer(address indexed from, address indexed to, uint256 value) -``` -Triggered when tokens are transferred. - -#### AddressApproval - -```js -AddressApproval(address indexed address, address indexed proxy, bool result) -``` -Triggered when an `address` approves `proxy` to direct debit from their account. - -#### AddressApprovalOnce - -```js -AddressApprovalOnce(address indexed address, address indexed proxy, uint256 value) -``` -Triggered when an `address` approves `proxy` to direct debit from their account only once for a maximum of `value` - -## TF Registries - -Token registries contain information about tokens. There is at least one global registry (though other may create more like the global Registry) to which you can add your token. Adding your token to it would increase the experience of the user that the GUI Client can use or not. - -#### symbol - -```js -setSymbol(string _s) -symbol(address _token) constant returns (string) -``` - -Sets or returns a short sequence of letters that are used to represent the unit of the coin. When setting, it assumes the `msg.sender` is the token. Solidity string is on UTF-8 format so this should support any character supported by UTF-8. Symbols are chosen by the contract and it's up to the client to decide how to handle different currencies with similar or identical symbols. - -Examples or symbols: `USDX`, `BOB$`, `Ƀ`, `% of shares`. - -#### name - -```js -setName(string _s) -name(address _token) constant returns (string) -``` - -Sets or returns the name of a token. Solidity string is on UTF-8 format so this should support any character supported by UTF-8. Names are chosen by the contract and it's up to the client to decide how to handle different currencies with similar or identical names. - -Examples of names: `e-Dollar`, `BobToken`, `Bitcoin-Eth`. - -#### baseUnit - -```js -setBaseUnit(uint _s) -baseUnit(address _token) constant returns (uint256) -``` - -Sets or returns the base unit of a token. Although most tokens are displayed to the final user as containing decimal points, token values are unsigned integers counting in the smallest possible unit. The client should always display the total units divided by `baseUnit`. Base units can be any integer but we suggest only using powers of 10. At the moment there is no support for multiple sub-units. - -Example: Bob has a balance of 100000 BobTokens whose base unit is 100. His balance will be displayed on the client as **BOB$100.00** - -## Registries - -Registries (eg. domain name systems) have the following API: - -### Methods -#### reserve - -```js -reserve(string _name) returns (bool _success) -``` -Reserves a name and sets its owner to you if it is not yet reserved. - -#### owner - -```js -owner(string _name) constant returns (address _r) -``` -Get the owner of a particular name. - -#### transfer - -```js -transfer(string _name, address _newOwner) -``` -Transfer ownership of a name. - -#### setAddr - -```js -setAddr(string _name, address _address) -``` - -Set the primary address associated with a name (similar to an A record in traditional DNS.) - -#### addr - -```js -addr(string _name) constant returns (address _r) -``` -Get the primary address associated with a name. - -#### setContent - -```js -setContent(string _name, bytes32 _content) -``` - -If you are the owner of a name, sets its associated content. - -#### content - -```js -content(string _name) constant returns (bytes32 _r) -``` - -Get the content associated with a name. - -#### setSubRegistrar - -```js -setSubRegistrar(string _name, address _subRegistrar) -``` - -Records the name as referring to a sub-registrar at the given address. - -#### subRegistrar - -```js -subRegistrar(string _name) constant returns (address _r) -``` -Gets the sub-registrar associated with the given name. - -#### disown - -```js -disown(string _name) -``` - -Relinquishes control over a name that you currently control. - -### Events - -#### Changed - -```js -event Changed(string name, bytes32 indexed __hash_name) -```` - -Triggered when changed to a domain happen. - - -## Data feeds - -The data feed standard is a _templated standard_, ie. in the below descriptions one should be free to replace `` with any desired data type, eg. `uint256`, `bytes32`, `address`, `real192x64`. - -### Methods -#### get - -```js -get(bytes32 _key) returns ( _r) -``` - -Get the value associated with a key. - -#### set - -```js -set(bytes32 _key, _value) -``` - -Set the value associated with a key if you are the owner. - -#### setFee - -```js -setFee(uint256 _fee) -``` - -Sets the fee. - -#### setFeeCurrency - -```js -setFeeCurrency(address _feeCurrency) -``` - -Sets the currency that the fee is paid in - -The latter two methods are optional. Also, note that the fee may be charged either in ether or subcurrency. If the contract charges in ether then the `setFeeCurrency` method is unnecessary. - - -## Forwarding contracts (eg. multisig) - -Forwarding contracts will likely work very differently depending on what the authorization policy of each one is. However, there are some standard workflows that should be used as much as possible: - -### Methods -#### execute - -```js -execute(address _to, uint _value, bytes _data) returns (bytes32 _id) -``` - -Create a message with the desired recipient, value and data. Returns a "pending ID" for the transaction. - -#### confirm - -```js -confirm(bytes32 _id) returns (bool _success) -``` - -Confirm a pending message with a particular ID using your account; returns success or failure. If enough confirmations are made, sends the message along. - -Access policies can be of any form, eg. multisig, an arbitrary CNF boolean formula, a scheme that depends on the _value_ or _contents_ of a transaction, etc. diff --git a/Subtleties.md b/Subtleties.md deleted file mode 100644 index 8c3cb7e52..000000000 --- a/Subtleties.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -name: Subtleties -category: ---- - -## Memory - -* Storage is a key/value store where keys and values are both 32 bytes -* Values on the stack are 32 bytes -* Memory is a byte-array. Memory starts off zero-size, but can be expanded in 32-byte chunks by simply accessing or storing memory at indices greater than its current size. -* The fee for expanding memory is determined via a subtract-the-integrals method. Specifically, `TOTALFEE(SZ) = SZ * 3 + floor(SZ**2 / 512)` is the total fee for expanding the memory to `SZ` 32-byte chunks (note: partially filled chunks are counted, so 33 bytes = 2 chunks), and if a particular operation expands memory from size `x` to `y`, the additional gas cost is `TOTALFEE(y) - TOTALFEE(x)` -* If an operation writes a slice of data zero bytes wide to memory, even if the start index of the slice exceeds the current memory size, memory is NOT expanded. - -## Nonces - -* If an externally-owned account sends a transaction, its nonce is incremented before execution -* If an externally-owned account creates a contract, its nonce is incremented before execution -* If a contract sends a message, no nonce increments happen -* If a contract creates a contract, the nonce is incremented before the rest of the sub-execution -* The pre-increment nonce is used to determine the contract address -* Nonce increments are never reverted - -## Exceptional conditions - -* The following count as exceptions: - * Execution running out of gas - * An operation trying to take more slots off the stack than are available on the stack - * Jumping to a bad jump destination - * An invalid opcode (note: the code of an account is assumed to be followed by an infinite tail of STOP instructions, so the program counter "walking off" the end of the code is not an invalid opcode exception. However, jumping outside the code is an exception, because STOP is not a valid jump destination) -* If a transaction triggers an exception, then: - * The value transfer from sender to recipient still takes place - * The fee transfer from sender to miner still takes place - * The entire `STARTGAS` is added to `gas_used` - * All other execution is reverted -* If a contract-producing transaction triggers an exception, then: - * The fee transfer from sender to miner still takes place - * The endowment is subtracted from the sender's account - * The account that would have been created gets created anyway, keeps its original endowment, but has the empty string as its code - * The entire `STARTGAS` is added to `gas_used` - * All other execution is reverted -* If a `CALL` operation's sub-execution triggers an exception, then: - * Ether value is still sent - * All gas is consumed - * `0` is appended onto the stack - * All other execution is reverted -* If a `CREATE` operation's sub-execution triggers an exception, then: - * Ether value is lost - * All gas is consumed - * All other execution is reverted - * The current implementations add `0` onto the stack, but it does not matter, since with 0 gas remaining the parent execution will instaquit anyway -* After a successful `CREATE` operation's sub-execution, if the operation returns `x`, `5 * len(x)` gas is subtracted from the remaining gas before the contract is created. If the remaining gas is less than `5 * len(x)`, then no gas is subtracted, the code of the created contract becomes the empty string, but this is not treated as an exceptional condition - no reverts happen. -* If a contract tries to `CALL` or `CREATE` a contract with either (i) insufficient balance, or (ii) stack depth already at maximum (1024), the sub-execution and transfer do not occur at all, no gas gets consumed, and 0 is added to the stack. -* Because of the depth limit, a contract may not be aware that a call that it is about to make is going to fail. Contract programmers should be very careful about this, and either use the 0 pushed to the stack to catch errors or use, eg, the identity contract to "test the waters" before making a substantial number of calls. - -## Arithmetic - -* All arithmetic is modulo 2256. For division, modulo and comparison, both signed and unsigned operators exist (eg. `(0 - 27) / 3` returns -9 if `SDIV` is used, but `38597363079105398474523661669562635951089994888546854679819194669304376546636` if `DIV` is used. -* Truncation and modulo operations with negative operators in the `SDIV`/`SMOD` case are handled as in Python (eg. , ) -* `DIV`, `SDIV`, `MOD` and `SMOD` with dividend (second argument) equal to 0 push 0 to the stack. - -### Other operations - -* The `CREATE` opcode takes three values: endowment (ie. initial amount of ether), memory start and memory length, and pushes onto the stack the address of the new contract. `CREATE` gives the initializing sub-execution all the gas that you have (and if gas remains then it gets refunded back to the parent execution) -* The `CALL` opcode takes seven values: gas, recipient, ether value, memory location of start of input data, length of input data, memory location to put start of output data, length of output data. It puts onto the stack either 1 for success (ie. did not run out of gas) or 0 for failure. -* When a contract calls `SUICIDE`, its ether is immediately sent to the desired address, but the contract continues existing until the end of transaction execution. Note that this leads to the interesting effect that, unlike Bitcoin where funds can be locked away forever but never destroyed, if a contract either SUICIDEs into itself or receives ether in the context of the same transaction execution after it has SUICIDED that ether is actually destroyed. -* If contract A calls contract B calls contract A, then the inner execution of A will have its own, fresh, memory, stack and PC, but it will modify and read the same balance and storage. -* If contract initialization returns an empty array, then no contract will be created. This allows you to "abuse" contract initialization as an atomic multi-operation, which might be useful in some protocols where you want to do multiple things but you don't want some of them to be able to process without others. -* `JUMP` and `JUMPI` instructions are only allowed to jump onto destinations that are (1) occupied by a `JUMPDEST` opcode, and (2) are not inside `PUSH` data. Note that properly processing these conditions requires preprocessing the code; a particularly pathological use case is `PUSH2 JUMPDEST PUSH1 PUSH2 JUMPDEST PUSH1 PUSH2 JUMPDEST PUSH1 ...`, as this code has all `JUMPDEST`s invalid but an alternative piece of code equivalent to this but only with the leading `PUSH2` replaced with another op (eg. `BALANCE`) will have all `JUMPDESTS`s valid. -* `CALL` has a multi-part gas cost: - * 40 base - * 9000 additional if the value is nonzero - * 25000 additional if the destination account does not yet exist (note: there is a difference between zero-balance and nonexistent!) -* `CALLCODE` operates similarly to call, except without the potential for a 25000 gas surcharge. -* The child message of a nonzero-value `CALL` operation (NOT the top-level message arising from a transaction!) gains an additional 2300 gas on top of the gas supplied by the calling account; this stipend can be considered to be paid out of the 9000 mandatory additional fee for nonzero-value calls. This ensures that a call recipient will always have enough gas to log that it received funds. \ No newline at end of file diff --git a/Swarm-Hash.md b/Swarm-Hash.md deleted file mode 100644 index ac53ec54d..000000000 --- a/Swarm-Hash.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -name: Swarm Hash -category: ---- - -# Introduction - -Swarm Hash (a.k.a. [`bzzhash`](https://github.com/ethersphere/go-ethereum/tree/bzz/bzz/bzzhash)) is a Merkle tree hash designed for the purpose of efficient storage and retrieval in content-addressed storage, both local and networked. While it is used in [Swarm](https://github.com/ethereum/go-ethereum/wiki/Swarm---distributed-preimage-archive), there is nothing Swarm-specific in it and the authors recommend it as a drop-in substitute of sequential-iterative hash functions (like SHA3) whenever one is used for referencing integrity-sensitive content, as it constitutes an improvement in terms of performance and usability without compromising security. For instance in the [URL Hint Protocol](https://github.com/ethereum/wiki/wiki/URL-Hint-Protocol). - -In particular, it can take advantage of parallelisms (including SMP and massively-parallel architectures such as GPU's) for faster calculation and verification, can be used to verify the integrity of partial content without having to transmit all of it. Proofs of security to the underlying hash function carry over to Swarm Hash. - -# Description - -Swarm Hash is constructed using a regular hash function (in our case, SHA3) with a generalization of Merkle's tree hash scheme. The basic unit of hashing is a _chunk_, that can be either a _leaf chunk_ containing a section of the content to be hashed or an _inner chunk_ containing hashes of its children, which can be of either variety. - -Hashes of leaf chunks are defined as the hashes of the concatenation of the 64-bit length (in LSB-first order) of the content and the content itself. Because of the inclusion of the length, it is resistant to length extension attacks, even if the underlying hash function is not. Note that this "safety belt" measure is extensively used in the latest edition of OpenPGP standard. It is, however, important to emphasize that Swarm Hash is obviously vulnerable to length extension attacks, but can be easily protected against them, when necessary, using similar measures in a higher layer. A possibly very profitable performance optimization (not currently implemented) is to initialize the hash calculation with the length of the standard chunk size (e.g. 4096 bytes), thus saving the repeated hashing thereof. - -Hashes of inner chunks are defined as the hashes of the concatenation of the 64-bit length (in LSB-first order) of the content hashed by the entire (sub-) tree rooted on this chunk and the hashes of its children. - -To distinguish between the two, one should compare the length of the chunk to the 64-bit number with which every chunk begins. If the chunk is exactly 8 bytes longer than this number, it is a leaf chunk. If it is shorter than that, it is an inner chunk. Otherwise, it is not a valid Swarm Hash chunk. - -# Strict interpretation - -A strict Swarm Hash is one where every chunk with the possible exception of those on the rightmost branch is of a specified length, i.e. 4 kilobytes. Those on the rightmost branch are no longer, but possibly shorter than this length. The hash tree must be balanced, meaning that all root-to-leaf branches are of the same length. - -The strict interpretation is unique in that only one hash value matches a particular content. The strict interpretation is only vulnerable to length extension attacks if the length of the content is a multiple of the chunk size, and the number of leaf chunks is an integer power of branching size (the fix maximum chunk size divided by hash length). - -A [parallelized implementation in Go](https://github.com/ethersphere/go-ethereum/tree/bzz/bzz) is available as well as [a command-line tool](https://github.com/ethersphere/go-ethereum/tree/bzz/bzz/bzzhash) for hashing files on the local filesystem using the strict interpretation. - -# Loose interpretations - -Swarm Hash interpreted less strictly may allow for different tree structures, imposing fewer restrictions or none at all. In this way, different hash values can resolve to the same content, which might have some adverse security implications. - -However, it might open the door for different applications where this does not constitute a vulnerability. For example, accepting single-leaf hashes in addition to strict Swarm hashes allows for referencing files without having to implement the whole thing. - -# References - -- [Merkle tree](http://en.wikipedia.org/wiki/Merkle_tree) -- [Length extension attack on wikipedia](http://en.wikipedia.org/wiki/Length_extension_attack) -- [IETF RFC4880](https://tools.ietf.org/html/rfc4880) -- [bzzhash code](https://github.com/ethersphere/go-ethereum/tree/bzz/bzz/bzzhash) -- [Swarm documentation and draft specs](https://github.com/ethereum/go-ethereum/wiki/Swarm---distributed-preimage-archive) \ No newline at end of file diff --git a/Tags-for-Solidity-in-code-documentation.md b/Tags-for-Solidity-in-code-documentation.md deleted file mode 100644 index 8b1378917..000000000 --- a/Tags-for-Solidity-in-code-documentation.md +++ /dev/null @@ -1 +0,0 @@ - diff --git a/Template:-This-Week-in-Ethereum-w-YY.md b/Template:-This-Week-in-Ethereum-w-YY.md deleted file mode 100644 index 8024ddac7..000000000 --- a/Template:-This-Week-in-Ethereum-w-YY.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -name: This Week in Ethereum Template -category: ---- - -###Current Status - -### Protocol - -## Clients - -### AlethZero - -### Mist - -###pyethereum - -##Projects - -##People - -##In the Media - -##Upcoming Events - -### Meetups diff --git a/The-Solidity-Programming-Language.md b/The-Solidity-Programming-Language.md deleted file mode 100644 index d72d918e5..000000000 --- a/The-Solidity-Programming-Language.md +++ /dev/null @@ -1,239 +0,0 @@ ---- -name: The Solidity Programming Language -category: ---- - -# This page is not actively maintained. - -The current Solidity documentation can be found at http://ethereum.github.io/solidity/ - -# Foreword - -Solidity is roughly speaking, an object-oriented language designed for writing contracts in Ethereum. Contracts are (typically) small programs which govern the behaviour of accounts within the Ethereum state. These programs operate within the context of the Ethereum environment. Such accounts are able to pass messages between themselves as well as doing practically Turing complete computation. - -Solidity is perhaps the first example of a *contract-oriented* programming language; a slight tweak on the notion of object-orientation. While closely related to object-oriented languages, this is a language designed specifically to help express agreements that must encode ideas and relationships relevant to Real Life, or some formal model thereof. As such we see notions such as ownership, identity, protections and restrictions forming a core part of the vocabulary and idiomatic grammar. - -We see language grammar actually tieing in with many of the aspects of this: the `event` primitives along with the `indexed` keyword explicitly address the logging environment which Ethereum provides. The variadic return values mimic the fact that output data of Ethereum's calling mechanism is, like the input data, an arbitrary byte array. - -# Basic Contract Anatomy - -## Hello, World! - -No language would be complete without a Hello World program. Operating within the Ethereum environment, Solidity has no obvious way of "outputting" a string. The closest we can do is to use a log event to place a string into the blockchain: - -``` -contract HelloWorld { - event Print(string out); - function() { Print("Hello, World!"); } -} -``` - -This contract, if placed on the blockchain and called, would create a log entry on the blockchain of type `Print` with a parameter `"Hello, World!"`. Easy, eh? - -## The Contract - -The contract is the basic structure of Solidity. It is a prototype of an object which lives on the blockchain. A contract may be instantiated into a contract-account (or 'object', or sometimes just 'account') at which point it gets a uniquely identifying address with which is may be called. The address here is similar to a reference or pointer in C-like languages, or just a plain old object in Javascript. Like plain objects in many object-oriented languages, contracts can never run themselves - they may only be called, or, put another way, they can only react to the receipt of a message; they can never be proactive. - -We denote a contract with the `contract` keyword and a name, followed by its definition enclosed in braces (`{` & `}`). Here is the most basic contract: - -``` -contract MostBasicContract { -} -``` - -It doesn't do anything. To make it do something when it receives a message, we can introduce a function. The function you've already seen is the so-called default function. Why this is default will be properly explained later, but for now, suffice it to say that it is simply the function that gets called when this contract (well, an instantiation of it, anyway) receives a message from the Ethereum Environment. - -The syntax of a function is similar to Javascript: it begins with the `function` keyword, then has a parenthesised parameter list, and finally has a braced expression block. - -``` -contract MostBasicContract { - function() { - // executed when a message is received. - } -} -``` - -This expression block is very similar to other C-like languages including Javascript. Within our expression block, we are able to do arbitrary computation; for instance, we might try to determine what the sum of 1 and 1 is and place it into a variable called `two`: - -``` -contract Simple { - function() { - var two = 1 + 1; - } -} -``` - -Unlike in Javascript, all variables must be declared prior to use and typed. However, for convenience, `var` is provided as a way to automatically determine the type through the expression it is initialised to. In this case, the type is `uint`, but more on the types later. - -## Simple Types - -The type system in Solidity revolves largely around the 256-bit word size of the EVM. To this end, there are 4 major types, each of which are specifically 256-bits wide: - -- `uint`: 256-bit unsigned integer, operable with bitwise and unsigned arithmetic operations. -- `int`: 256-bit signed integer, operable with bitwise and signed arithmetic operations. -- `real`: 256-bit signed fixed-point quantity, 127-bit left of the point, 128-bit right. -- `bytes32`: sequence of 32 bytes (256 bit in total). - -In addition to these, there is the intrinsic `address` type used for identifying specific accounts and a bool type for representing true and false: - -- `address`: account identifier, 160-bits. -- `bool`: two-state value. - -Most of the time, we'll tend to use `uint` und `bytes32`; the former if we intend to do arithmetic, the latter when we need to identify or refer to pieces of data, events, &c. - -So to declare a variable it is very similar to the C-like languages: we simply place the type, followed by the variable name and finish the expression with a `;`. For example to declare a uint named `x` we would write: - -``` -uint x; -``` - -If we then wanted to assign `69` to it, we'd use the assignment operator, `=` (not forgetting to place the trailing `;`: - -``` -uint x; -x = 69; -``` - -There is a shorthand to declaring and assigning; those two statements may be collapsed over the `x` into: - -``` -uint x = 69; -``` - -In this situation, where we are simultaneously declaring and initialising the variable, we are able to substitute the type with the keyword `var`. If we do this, the type will be determined through the type of the expression we are assigning: - -``` -var x = 69; -``` - -If we were to assign a decimal, `var` would become equivalent to a real: - -``` -var x = 69; // here, "var" is equivalent to "uint". -var y = 69.42; // here, "var" is equivalent to "real". -``` - -## Literals - -Solidity includes three types of literals; these are used for expressing specific, well-known values. - -# Integers - -Integer literals are formed from a sequence of numbers in the range 0-9. They are interpreted as decimals. Examples include `69` and `01000000`. - - -In terms of literals, addresses are formed from the characters `0x` followed directly by a sequence of pairs of hexadecimal numbers, in the range 0-9 and a-f (not case sensitive). They are interpreted as hexadecimal-encoded bytes. Examples include: - -``` -address a = 0x0123456789abcdef0123; -``` - -# Byte Strings - -Byte string literals are formed by a sequence of arbitrary characters contained between quote characters (`"`). They are generally interpreted as zero-terminated ASCII encoded text, similar to C. The terminating zero need not be supplied. An examples would be: `"Hello, World!"`. - -# Reals - -Reals are formed similar to integers except that they include a decimal point and at least one number on either side of it. An example would be: `3.14159265` and `42.000001`. - -## Parameters and Returns - -Messages can have arbitrary input and output data. Since functions are our way of expressing how messages should be handled, they need a way of expressing how this data should be utilised. As such, like in Javascript and C, functions may take parameters as input; unlike in Javascript and C, they may so return arbitrary parameters as output. The input parameters, and types, must be named, type followed by name. For example, suppose we want our contract to accept messages that present two integers, we would write something like: - -``` -contract Simple { - function(uint _a, uint _b) { - // do something with _a and _b. - } -} -``` - -Parameters are not allowed to be altered; they are so-called *constant* values and as such may not be used on the left-hand side of an expression. - -Returning information through the message is equally simple using the same syntax with the `returns` keyword. For example, suppose we wished to return two results: the sum and the product of the two given integers, then we would write: - -``` -contract Simple { - function(uint _a, uint _b) returns (uint o_sum, uint o_product) { - o_sum = _a + _b; - o_product = _a * _b; - } -} -``` - -Return parameters are always reset to zero; if they are not explicitly set, then they - -## Arithmetic & Flow-control - -There are a number of - -On-hand, we also have the Keccak, aka SHA-3 function. So, - - -### Fields - -Contracts may have data members. - -### Constant - -## Methods - -### Constant - -## The Constructor - -## The Environment - -# More Complex Typing - -## Contracts & Forward Declarations - -### External Calls - -### Limiting Gas and Passing Value - -## Arrays - -There is also a special type - -- `byte[]`: dynamic-length packed byte array. - -## Mappings - -## Structs and Enums - -# Advanced Solidity - -## Visibility - -- Public -- Private -- External - -## Inheritance - -## Function Modifiers - -## Logging - -## Calling conventions - -# The Solidity Library - -### owned - -### multiowned - -### mortal - -### named - -### daylimit - -# Solidity 2.0 - -## Invariants - -## Pre- & Post-conditions - -## The dynamic Keyword diff --git a/This Week In Ethereum 47.2014.md b/This Week In Ethereum 47.2014.md deleted file mode 100644 index 614edf743..000000000 --- a/This Week In Ethereum 47.2014.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -name: This Week in Ethereum 47 -category: ---- - -###Current Status - -We are in the last days of preparing the POC-7 release. It is scheduled to ship on 21th of November. Latest stable release is Po6, testnet is reachable here, chain explorer here. Release of PoC8 is expected to be on christmas. Alpha releases are expected for mid January 2015. Release of the genesis is scheduled for March 2015. - -### Protocol -* Version update to eth:34 -* Blogs/Blooms/Recipes - There are often going to be situations where contracts need to record events that will be indexible/accessible/provable by light clients and these events are often fire-and-forget. - So filling a storage index for them is very wasteful. - We solve this by adding a an opcode LOG, whose purpose it is to create an event that gets put into the receipt trie of the block but is not stored in the state. The transactions trie is split up into two tries. - (1) transactions only - (2) medstate, gas, and logs (the recipes) - -* Exception severity uniformity - See: https://ethereum.etherpad.mozilla.org/14 - -## Clients -### AlethZero -* Commandline option -v now also reports protocol version -* Cleaned up make files -* ... - -### Mist -* Added LOG opcode -* Refactored XYZ - -###pyethereum -* Added LOG opcode -* Refactored logging to give log structured (machine readable) data - -##Projects - -* Continuous Integration: The bootstrapping node was extended to also host a "eth" protocol node. -* Serpent 2.0: was updated to feature function definitions and proper data structures -* Solidity: First compiled contracts are working and on the PoC7 testnet -* Security Audit - Results of a preliminary GO code audit were provided by Sergio. Jutta is working on contracting external auditors. -* Stress Testing: Sven is working on the infrastructure to run and analyze various scenarios in a synthetic test network. -* Berlin Office: Almost done, move in is scheduled for Monday. - -##People: -* Yann joined DEV Berlin and will work on the IDE -* Jutta joined and will work on security audits - -##In the Media -Worldwide coverage of Vitalik winning the 2014 Software Innovation Award at the World Technology Awards. - -##Upcoming Events - -### Meetups -* Berlin 18.11.14 -* NYC, Paris, Tokio - -###DEVCon-000 -The first Ethereum developer conference is happening during the next week in our new office in Berlin. diff --git a/Todo-before-alpha.md b/Todo-before-alpha.md deleted file mode 100644 index d4d0a113b..000000000 --- a/Todo-before-alpha.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -name: TODO Before Alpha -category: ---- - -## Etereum P2P sub-protocol - -* Fix numbering in [Wire](https://github.com/ethereum/wiki/wiki/Ethereum-Wire-Protocol) protocol. -* Add `gasprice` message - * `[[id, price], [id, price], ...]` \ No newline at end of file diff --git a/URL-Hint-Protocol.md b/URL-Hint-Protocol.md deleted file mode 100644 index 553604489..000000000 --- a/URL-Hint-Protocol.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -name: URL Hint Protocol -category: ---- - -There exists a root `Registry` contract at address 0x42 (this is the auctioning thing). There exists a contract interface, `register`, which `Registry` implements. - -Entries in `register`, when looked up (indexed by a string32 name) have several value fields, including `content` and `register`. - -`content` is the content hash which gets loaded when you enter this name into Mist/AZ. - -`register` is the address of a subregistry contract (some contract implementing `register`) which gets queried recursively. - -### Example - -- `eth://gavofyork` results in the main Registry (at 0x42) being queried for the entry `gavofyork`. The content field of this entry (a SHA3 hash of a zip file OR manifest) is used to display content (see Content section for more info). - -## URL Composition - -All URLs canonically begin `eth://` and are a number of components, each separated by a `/`. The field `register` is used to do a recursive lookup. - -So the components of `gavofyork/tools/site/contact` would comprise four components, in order: `gavofyork`, `tools`, `site`, `contact`. - -Any periods `.` before the left-most slash `/` delineate components which are specified in reverse order. - -So non-canonical forms of the above address are: - -- `tools.gavofyork/site/contact` -- `site.tools.gavofyork/contact` -- `contact.site.tools.gavofyork` - -NOTE: any periods after the leftmost `/` are treated no differently than other alphanumeric characters. - -### Example - -- `eth://gavofyork/site` results in the main Registry (at 0x42) being queried for the entry `gavofyork`. The register field of this entry (an address of a `register`-implementing contract) is then queried for the entry `site`. The `content` field of this entry is used to display content. - -# Content - -Normally Swarm would be used to determine the content from the content hash. - -For 1.0, this will not be possible, so we will fall back to using HTTP distribution. To enable this we will include one or many URLHint contracts, which provide hints of URLs that allow downloading of particular content hashes. Find the contract in dapp-bin. - -The content downloaded should be treated in many ways (and hashed) to discover what the content is. Possible ways include base 64 encoding, hex encoding and raw, and any content-cropping needed (e.g. a HTML page should have everything up to body tags removed). - -It will be up to the dapp/content uploader to keep URLHint entries updated. - -The address of the URLHint contract will be specified on an ad-hoc basis and users will be able to enter additional ones into their browser. - diff --git "a/Useful-\303\220app-Patterns.md" "b/Useful-\303\220app-Patterns.md" deleted file mode 100644 index e40841400..000000000 --- "a/Useful-\303\220app-Patterns.md" +++ /dev/null @@ -1,17 +0,0 @@ ---- -name: Useful DAPP Patterns -category: ---- - -The following page is a collection of useful patterns, Ðapps can use, such as talking to the blockchain reliably. - -The example patterns can possibly change, so don't rely fully on them as of yet. - -## Examples - -- Contract deployment by code: -(Outdated, use `web3.contract(abiArray).new({}, function(e, res){...})`) -https://gist.github.com/frozeman/655a9325a93ac198416e - -- Test a contract transaction with a `call` before actually sending: -https://gist.github.com/ethers/2d8dfaaf7f7a2a9e4eaa diff --git a/Web3-Secret-Storage-Definition.md b/Web3-Secret-Storage-Definition.md deleted file mode 100644 index 0fd0641b3..000000000 --- a/Web3-Secret-Storage-Definition.md +++ /dev/null @@ -1,172 +0,0 @@ ---- -name: Web3 Secret Storage Definition -category: ---- - -This documents version 3 of the Web3 Secret Storage Definition. - -## Definition - -The actual encoding and decoding of the file remains largely unchanged from version 1, except that the crypto algorithm is no longer fixed to AES-128-CBC (AES-128-CTR is now the minimal requirement). Most of the meanings/algorithm are similar to version 1, except `mac`, which is given as the SHA3 (keccak-256) of the concatenation of the last 16 bytes of the derived key together with the full `ciphertext`. - -Secret key files are stored directly in `~/.web3/keystore` (for Unix-like systems) and `~/AppData/Web3/keystore` (for Windows). They may be named anything, but a good convention is `.json`, where `` is the 128-bit UUID given to the secret key (a privacy-preserving proxy for the secret key's address). - -All such files have an associated password. To derive a given `.json` file's secret key, first derive the file's encryption key; this is done through taking the file's password and passing it through a key derivation function as described by the `kdf` key. KDF-dependent static and dynamic parameters to the KDF function are described in `kdfparams` key. - -PBKDF2 must be supported by all minimally-compliant implementations, denoted though: - -- `kdf`: `pbkdf2` - -For PBKDF2, the `kdfparams` include: - -- `prf`: Must be `hmac-sha256` (may be extended in the future); -- `c`: number of iterations; -- `salt`: salt passed to PBKDF; -- `dklen`: length for the derived key. Must be >= 32. - -One the file's key has been derived, it should be verified through the derivation of the MAC. The MAC should be calculated as the SHA3 (keccak-256) hash of the byte array formed as the concatenations of the second-leftmost 16 bytes of the derived key with the `ciphertext` key's contents, i.e.: - -``` -KECCAK(DK[16..31] ++ ) -``` - -(where `++` is the concatenation operator) - -This value should be compared to the contents of the `mac` key; if they are different, an alternative password should be requested (or the operation cancelled). - -After the file's key has been verified, the cipher text (the `ciphertext` key in the file) may be decrypted using the symmetric encryption algorithm specified by the `cipher` key and parameterised through the `cipherparams` key. If the derived key size and the algorithm's key size are mismatched, the zero padded, rightmost bytes of the derived key should be used as the key to the algorithm. - -All minimally-compliant implementations must support the AES-128-CTR algorithm, denoted through: - -- `cipher`: `aes-128-ctr` - -This cipher takes the following parameters, given as keys to the `cipherparams` key: - -- `iv`: 128-bit initialisation vector for the cipher. - -The key for the cipher is the leftmost 16 bytes of the derived key, i.e. `DK[0..15]` - -The creation/encryption of a secret key should be essentially the reverse of these instructions. Make sure the `uuid`, `salt` and `iv` are actually random. - -In addition to the `version` field, which should act as a "hard" identifier of version, implementations may also use `minorversion` to track smaller, non-breaking changes to the format. - -## Test Vectors - -Details: - -- Address: `008aeeda4d805471df9b2a5b0f38a0c3bcba786b` -- ICAP: `XE542A5PZHH8PYIZUBEJEO0MFWRAPPIL67` -- UUID: `3198bc9c-6672-5ab3-d9954942343ae5b6` -- Password: `testpassword` -- Secret: `7a28b5ba57c53603b0b07b56bba752f7784bf506fa95edc395f5cf6c7514fe9d` - -### PBKDF2-SHA-256 - -Test vector using AES-128-CTR and PBKDF2-SHA-256: - -File contents of `~/.web3/keystore/3198bc9c-6672-5ab3-d9954942343ae5b6.json`: -```json -{ - "crypto" : { - "cipher" : "aes-128-ctr", - "cipherparams" : { - "iv" : "6087dab2f9fdbbfaddc31a909735c1e6" - }, - "ciphertext" : "5318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46", - "kdf" : "pbkdf2", - "kdfparams" : { - "c" : 262144, - "dklen" : 32, - "prf" : "hmac-sha256", - "salt" : "ae3cd4e7013836a3df6bd7241b12db061dbe2c6785853cce422d148a624ce0bd" - }, - "mac" : "517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2" - }, - "id" : "3198bc9c-6672-5ab3-d995-4942343ae5b6", - "version" : 3 -} -``` - -Intermediates: - -- Derived key: `f06d69cdc7da0faffb1008270bca38f5e31891a3a773950e6d0fea48a7188551` -- MAC Body: `e31891a3a773950e6d0fea48a71885515318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46` -- MAC `517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2` -- Cipher key: `f06d69cdc7da0faffb1008270bca38f5` - -### Scrypt - -Test vector using AES-128-CTR and Scrypt: - -```json -{ - "crypto" : { - "cipher" : "aes-128-ctr", - "cipherparams" : { - "iv" : "83dbcc02d8ccb40e466191a123791e0e" - }, - "ciphertext" : "d172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c", - "kdf" : "scrypt", - "kdfparams" : { - "dklen" : 32, - "n" : 262144, - "r" : 1, - "p" : 8, - "salt" : "ab0c7876052600dd703518d6fc3fe8984592145b591fc8fb5c6d43190334ba19" - }, - "mac" : "2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097" - }, - "id" : "3198bc9c-6672-5ab3-d995-4942343ae5b6", - "version" : 3 -} -``` - -Intermediates: - -- Derived key: `fac192ceb5fd772906bea3e118a69e8bbb5cc24229e20d8766fd298291bba6bd` -- MAC Body `bb5cc24229e20d8766fd298291bba6bdd172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c` -- MAC: `2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097` -- Cipher key: `fac192ceb5fd772906bea3e118a69e8b` - -## Alterations from Version 1 - -This version fixes several inconsistencies with the version 1 published [here](https://github.com/ethereum/go-ethereum/wiki/Passphrase-protected-key-store-spec). In brief these are: - -- Capitalisation is unjustified and inconsistent (`scrypt` lowercase, `Kdf` mixed-case, `MAC` uppercase). -- `Address` unnecessary and compromises privacy. -- `Salt` is intrinsically a parameter of the key derivation function and deserves to be associated with it, not with the crypto in general. -- `SaltLen` unnecessary (just derive it from `Salt`). -- The key derivation function is given, yet the crypto algorithm is hard specified. -- `Version` is intrinsically numeric yet is a string (structured versioning would be possible with a string, but can be considered out of scope for a rarely changing configuration file format). -- KDF and cipher are notionally sibling concepts yet are organised differently. -- MAC is calculated through a whitespace agnostic piece of data(!) - -Changes have been made to the format to give the following file, functionally equivalent to the example given on the previously linked page: - -```json -{ - "crypto": { - "cipher": "aes-128-cbc", - "ciphertext": "07533e172414bfa50e99dba4a0ce603f654ebfa1ff46277c3e0c577fdc87f6bb4e4fe16c5a94ce6ce14cfa069821ef9b", - "cipherparams": { - "iv": "16d67ba0ce5a339ff2f07951253e6ba8" - }, - "kdf": "scrypt", - "kdfparams": { - "dklen": 32, - "n": 262144, - "p": 1, - "r": 8, - "salt": "06870e5e6a24e183a5c807bd1c43afd86d573f7db303ff4853d135cd0fd3fe91" - }, - "mac": "8ccded24da2e99a11d48cda146f9cc8213eb423e2ea0d8427f41c3be414424dd", - "version": 1 - }, - "id": "0498f19a-59db-4d54-ac95-33901b4f1870", - "version": 2 -} -``` - -## Alterations from Version 2 - -Version 2 was an early C++ implementation with a number of bugs. All essentials remain unchanged from it. \ No newline at end of file diff --git a/What-is-Ethereum.md b/What-is-Ethereum.md deleted file mode 100644 index 0bb7ecfdd..000000000 --- a/What-is-Ethereum.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -name: What is Ethereum? -category: ---- - -# What is Ethereum? - -Ethereum, like any advanced system, will mean different things to different people. As you read this section, some bits may not resonate with you or even make sense. That is fine, just skip to the next paragraph and hopefully that one will be more enlightening. If you reach the end of this section and still feel confused, then jump on a forum and start asking questions. - - -## A World Computer - ->"It is very possible that ... one machine would suffice to solve all the problems ... of the whole [world]" - Sir Charles Darwin, 1946* - -In a technical sense, Ethereum is a "world computer". Harking back to the days of the mainframe, and probably about as fast, Ethereum can be viewed as a single computer that the whole world can use. It notionally has only a single processor (no multi-threading or parallel execution), but as much memory as required. Anybody can upload programs to the Ethereum World Computer and anybody can request that a program that has been uploaded be executed. This does not mean that anyone can ask any program to do anything; on the contrary: the author of the program can specify that requests from anyone but themselves be ignored, for example. Also, in a very strong sense, every program has its own permanent storage that persists between executions. Furthermore, as long as it is in demand, the Ethereum World Computer will always be there: it can't be shut down or turned off. - -You may ask, "why would anyone use such a system?" and again there are many reasons. The main reason is because it makes what you want to do cheaper and easier. This statement needs to be broken down somewhat, which is what the following paragraphs explore. - - -## An Internet Service Platform - ->"Technology gives us the facilities that lessen the barriers of time and distance - the telegraph and cable, the telephone, radio, and the rest." - Emily Greene Balch - -In a more practical sense, Ethereum is an internet service platform for guaranteed computation. More than that, as a platform, it provides a set of integral features which are very useful to the developer: - - * user authentication, via seamless integration of cryptographic signatures - * fully customizable payment logic; easily create your own payment system without any reliance on third parties - * 100% ddos resistant up-time, guaranteed by being a fully decentralized blockchain-based platform - * no-fuss storage: forget about having to set up secure databases; Ethereum gives you as much storage as you want - * ultimate interoperability: everything in the Ethereum ecosystem can trivially interact with everything else, from reputation to custom currencies - * server free zone: your whole application can be deployed on the blockchain meaning no need for setting up or maintaining servers; let your users pay for the cost of their using your service. - -Over the last twenty years in particular, we have seen an acceleration in the development of services and infrastructure to make the overhead of working as a team or running businesses simpler and less expensive, mainly thanks to the internet. The likes of eBay, Drivy and Airbnb have made setting up a shop, car rental company or hotel much easier. These are platforms that allow people to realize their idea quickly, as long as the service they want to provide fits the template offered by the platform. Outside Ethereum, it is very costly to create a new platform if those that already exist do not fit your needs. Ethereum can be seen as a platform for platforms: it allows people to easily create the infrastructure to make it easy to set up new services on the internet. Furthermore, any infrastructure created on Ethereum sits alongside everyone else's creations, and so can interact with those other platforms in a guaranteed and seamless manner. Importantly, because there is not a company or indeed any entity in charge of or controlling Ethereum, the cost of running the infrastructure doesn't have to include any profit margin, so we are likely to see lower costs. - -With the coming of the Mix IDE and the Mist browser, the functionality of Ethereum as a deployment platform for internet services will become more clear. The take-home message from this section, however, is that Ethereum is poised to disrupt industries as diverse as finance and supply chains. - - -## Opt-in Social Contracts - -> "This is an era of organization" - Theodore Roosevelt, 1912** - -At a more abstract level, it is a facility for enabling smart organization, in the sense of groups of entities working together for a particular cause. In the simplest scenario, we have two people working together to achieve a trade. Ultimately, Ethereum could be used to run countries. Somewhere in between there are groups of people wanting to organize baby-sitting circles, film-making collectives, discussion groups, communal houses, etc, and they all have to decide the rules with which they will operate together. Arguably, the harder task is how to implement and enforce the rules, especially given the variety of characters, abilities and motivations that the human race provides. In other words, how do you stop Jo hogging the camera equipment, or Dave never doing his turn of the childcare? Ethereum provides a platform on which rules can be defined and, to an ever increasing degree as technology improves, see enforced. For example, the camera could be listening to the blockchain and only record if the film-making collective's DApp approves Jo's access code. - -Crowdfunding is a key example in the advancement organizational tools. It provides a couple of really important functions: a way for individuals to work together for a particular cause (in this case giving a wedge of cash to a person or group) and a mechanism for individuals to interact meaningfully with potentially large companies (such as a games studio). The first follows from the previous paragraph, but the second point is impressive also, because in general individuals can only communicate with large organizations on the organization's terms, which often default to "ignore"; in the same way you ignore the bacteria on your skin. As it stands, you might be disgruntled by the crowdfunding recipient taking your money and spending it in a wholey inappropriate and therefore inefficient manner. However, it's hard to get the operating company to act on your behalf against the recipient. After all, the crowdfunding service provider is likely to be a large company and there isn't a universal mechanism with which you can meaningfully communicate with it if it does not want you to. Ethereum can help by allowing you to define post-funding milestones or conditions to stage the payment of the total amount raised, and then enforce those conditions for you. As times goes on, we will get more creative in the ways in which Ethereum can interact with the real world and the ability of Ethereum to check that milestones have been completed will extend beyond the obvious such as "30% of the crowd that funded the project (by value) have voted that the milestone has been passed". - - -## Part of the Decentralization Revolution - ->"No matter who you vote for, the government always gets in" - The Bonzo Dog Doo-Dah Band, 1992 - -Philosophically, it is the next step in re-decentralizing the internet. A decentralized system is one that anyone can unilaterally join and participate in, one in which all participants contribute to the running and maintanence, and one in which any participant can unilaterally leave and when they do, the system continues regardless. In a decentralized system, there is no entity that can prevent participation or arbitrarily censor the content or usage. The internet was designed to be decentralized, but the way we use it has become increasingly centralized, to the point where censorship and exclusion are accepted and expected. Blockchain technology, introduced by Satoshi Nakamoto with the proof-of-concept implementation of a simple value transfer system known as bitcoin, represents the best digital system we have (after the internet itself) for administering multi-user interactions without any need for centralized coordination or oversight. Effectively, a decentralized system is its own authority for enforcing the rules (e.g. 'you can only spend your money once' in bitcoin, or 'whatever rule you programmed in to your smart contract' in Ethereum), so participants can be confident that the rules they expect to be enforced will be, without any danger of corruption, bribery, nepotism, political bias, exclusion, arbitrary exceptions, human oversight or absence of staff. - -Ethereum allows people to safely interact trustlessly by entering into neutrally enforceable agreements in a completely peer-to-peer fashion. Now, it must be remembered that Ethereum can only enforce within its own digital limits; Ethereum does not remove the need for an external authority for adjudication over disputes outside its realm---"the other party punched me in the face after putting in the Ethereum contract that he wouldn't" is non-sense, but rules exist elsewhere to cover this---but what Ethereum does do is allow us to push the boundary on what the digital realm can cover. - - -## Conclusion - -Gavin Wood has distilled the description of Ethereum to being a collection of non-localized singleton programmable data structures. What this means will depend on where you are coming from, but wherever you are, it's probably going to be better with Ethereum. - - -### Notes -*Copeland, Jack (2006). Colossus: The Secrets of Bletchley Park's Codebreaking Computers. Oxford University Press. p.109 - -Note that T.J.Watson, the former head of IBM, almost certainly never said, "I think there is a world market for maybe five computers", although for a time (late 1940s, early 1950s) it was indeed the case that there was, in the United States, a market for about five computers. - -**Presidential speech, Milwaukee, Wisconsin. diff --git a/Which-Client?.md b/Which-Client?.md deleted file mode 100644 index a72303a4f..000000000 --- a/Which-Client?.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -name: Which Client? -category: ---- - ------ \ No newline at end of file diff --git a/Whisper-Overview.md b/Whisper-Overview.md deleted file mode 100644 index 539fe5819..000000000 --- a/Whisper-Overview.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -name: Whisper Overview -category: ---- - -### Example ("Dream") API Usage - -```js -var shh = web3.shh; -var appName = "My silly app!"; -var myName = "Gav Would"; -var myIdentity = shh.newIdentity(); - -shh.post({ - "from": myIdentity, - "topic": [ web3.fromAscii(appName) ], - "payload": [ web3.fromAscii(myName), web3.fromAscii("What is your name?") ], - "ttl": 100, - "priority": 1000 -}); - -var replyWatch = shh.watch({ - "topic": [ web3.fromAscii(appName), myIdentity ], - "to": myIdentity -}); -// could be "topic": [ web3.fromAscii(appName), null ] if we wanted to filter all such -// messages for this app, but we'd be unable to read the contents. - -replyWatch.arrived(function(m) -{ - // new message m - console.log("Reply from " + web3.toAscii(m.payload) + " whose address is " + m.from); -}); - -var broadcastWatch = shh.watch({ "topic": [ web3.fromAscii(appName) ] }); -broadcastWatch.arrived(function(m) -{ - if (m.from != myIdentity) - { - // new message m: someone's asking for our name. Let's tell them. - var broadcaster = web3.toAscii(m.payload).substr(0, 32); - console.log("Broadcast from " + broadcaster + "; replying to tell them our name."); - shh.post({ - "from": eth.key, - "to": m.from, - "topics": [ eth.fromAscii(appName), m.from ], - "payload": [ eth.fromAscii(myName) ], - "ttl": 2, - "priority": 500 - }); - } -}); -``` - -### Basic operation - -`post` takes a JSON object containing four key parameters: - -```js -shh.post({ "topic": t, "payload": p, "ttl": ttl, "workToProve": work }); -``` - -- `topic`, provided as either a list of, or a single, arbitrary data items that are used to encode the abstract topic of this message, later used to filter messages for those that are of interest; -- `payload`, provided similarly to topic but left as an unformatted byte array provides the data to be sent. -- `ttl` is a time for the message to live on the network, specified in seconds. This defaults to 50. -- `work` is the amount of priority you want the packet to have on the network. It is specified in milliseconds of processing time on your machine. This defaults to 50. - -Two other parameters optionally specify the addressing: recipient (`to`), sender (`from`). The latter is meaningless unless a recipient has been specified. - -### Use cases -- `shh.post({ "topic": t, "payload": p });` No signature, no encryption: Anonymous broadcast; a bit like an anonymous subject-filtered twitter feed. -- `shh.post({ "from": myIdentity, "topic": t, "payload": p });` Open signature, no encryption: Clear-signed broadcast; a bit like a normal twitter feed - anyone interested can see a particular identity is sending particular stuff out to no-one in particular. -- `shh.post({ "to": recipient, "topic": t, "payload": p });` No signature, encryption: Encrypted anonymous message; a bit like an anonymous drop-box - message is private to the owner of the dropbox. They can't tell from whom it is. -- `shh.post({ "from": myIdentity, "to": recipient, "topic": t, "payload": p });` Secret signature, encryption: Encrypted signed message; like a secure e-mail. One identity tells another something - nobody else can read it. The recipient alone knows it came from the sender. -- `shh.post({ "from": myIdentity, "to": recipient, "topic": t, "payload": p, "deniable": d });` Secret signature, encryption with optional plausible deniability. If boolean parameter `d` is **false**, it is equivalent to the previous call. If `d` is **true**, recipient cannot prove to any third party that the message originates from sender, though still can verify it for herself. This is achieved by the digital signature being calculated on the symmetric session encryption key instead of the message body. - -In addition to the basic use cases, there will also be support for secure multi-casting. For this, you set up a group with `shh.newGroup`: - -``` -var group = shh.newGroup(eth.key, [ recipient1, recipient2 ]); -``` - -Then can use this as a recipient as you would normally: - -``` -shh.post({ "from": eth.key, "to": group, "topic": t, "payload": p }); -``` - -The `newGroup` actually does something like: - -``` -var group = shh.newIdentity(); -shh.post([ "from": myIdentity, "to": recipient1, "topic": [invSHA3(2^255), recipient1], "payload": secretFromPublic(group) ]); -shh.post([ "from": myIdentity, "to": recipient2, "topic": [invSHA3(2^255), recipient2], "payload": secretFromPublic(group) ]); -return keypair; -``` - -Here, the `invSHA3(2^255)` topic is a sub-band topic (intercepted by the Whisper protocol layer) which takes the key and adds it to the key database. When a packet is addressed to `group`, it encrypts with group's public key. `group` is not generally used for signing. `secretFromPublic` obviously isn't a public API and invSHA3 is only possible because we know each item of the topic is SHA3ed prior to amalgamation in the final topic. - -When signing a message (one with a `from` parameter), the message-hash is the hash of the clear-text (unencrypted) payload. - -Topics is constructed from a number of components - this simply compresses (sha3 + crop) each into a final set of 4-byte crypto-secure hashes. When composing filters, it's the same process. Importantly, all such hashes given in the filters must be includes in. - -To filter on sender/recipient, they should be encoded within the topic by the sender. - -### Silent Operation - -In normal operation (and assuming a non-degenerate attack condition), there is a trade-off between true anonymity/plausible deniability over ones communications and efficiency of operation. The more one advertises to ones peers attempting to "fish" for useful messages and steer such message towards oneself, the more one reveals to ones peers. - -For a securely anonymous dynamic two-way conversation, this trade-off becomes problematic; significant topic-advertising would be necessary for the point-to-point conversation to happen with sensible latency and yet so little about the topic can be advertised to guide messages home without revealing substantial information should there be adversary peers around an endpoint. (If substantial numbers of adversary peers surround both endpoints, a tunnelling system similar to TOR must be used to guarantee security.) - -In this situation, dynamic topic generation would be used. This effectively turns the datagram-orientated channel into a connection-oriented channel. The endpoint to begin the conversation sends a point-to-point (i.e. signed and encrypted) conversation-begin message that contains a randomly chosen 256-bit topic seed. The seed is combined (by both endpoints) with a message nonce (beginning at 0 and incrementing over the course of the conversation) to provide a secure chain of single-use topics. It then generates a bloom filter using randomly selected bits from the new topic to match against and gives the filter to its peers; once a randomly selected minimum of messages fitting this filter have been collected (we assume one of these is the message we are interested in), we send our reply, deriving a new topic (incrementing the nonce), then advertise for that with yet another topic (another nonce increment) with another randomly selected group of bits. diff --git a/Whisper-PoC-2-Protocol-Spec.md b/Whisper-PoC-2-Protocol-Spec.md deleted file mode 100644 index 779356b1f..000000000 --- a/Whisper-PoC-2-Protocol-Spec.md +++ /dev/null @@ -1,141 +0,0 @@ ---- -name: Whisper PoC-2 Protocol Spec -category: ---- - -This page, in addition to the Whisper Wire Specification, details the full Whisper protocol for the first proof-of-concept and sets the vision for the final design. It evolve alongside the Whisper protocol as the prototype is refined. From it you should be able to develop compliant Whisper implementations. This document is intended to give only the base specification. Many of the aspects leading to an implementation of Whisper are game theoretic and best not prescribed in the specification, but rather left to individual implementation teams to determine for themselves. - -### What Whisper Is (and Is Not) - -Whisper combines aspects of both DHTs and datagram messaging systems (e.g. UDP). As such it may be likened and compared to both, not dissimilar to the matter/energy duality (apologies to physicists for the blatant abuse of a fundamental and beautiful natural principle). - -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. - -Alternatively, Whisper may be likened to a DHT with a per-entry configurable TTL and conventions for the signing and encryption of values. In this sense, Whisper provides the ability to have multiply-indexable, non-unique entries (i.e. the same entry having multiple keys, some or all of which may be the same as other entries). - -As such, Whisper is not a typical communications system. It is not designed to replace or substitute TCP/IP, UDP, HTTP or any other traditional protocols; it is not designed to provide a connection oriented system, nor for simply delivering data betwixt a pair of specific network endpoints; it does not have a primary goal of maximising bandwidth or minimising latency (though as with any transmission system, these are concerns). - -Whisper is a new protocol designed expressly for a new paradigm of application development. It is designed from the ground up for easy and efficient multi-casting and broadcasting. Similarly, low-level partially-asynchronous communications is an important goal. Low-value traffic reduction or retardation is another goal (which might also be likened to the quest for QoS). It is designed to be a building block in next generation ÐApps which require large-scale many-to-many data-discovery, signal negotiation and modest transmissions with an absolute minimum of fuss and the expectation that one has a very reasonable assurance of complete privacy. - -### Pitch-Black Darkness - -Whisper operates around the notion of being user-configurable with regard to how much information it leaks concerning the ÐApp content and ultimately, the user activities. To understand information leakage, it is important to distinguish between mere encryption, and *darkness*. Many protocols, both those designed around p2p and more traditional client/server models provide a level of encryption. For some, encryption forms an intrinsic part of the protocol and, applied alone, delivers its primary requirement. While decentralising and encrypting is a great start on building a legitimately "post-Snowden" Web, it is not the end. - -Even with encrypted communications, well-funded attackers are still able to compromise ones privacy, often quite easily. Bulk metadata collection becomes the new battleground, and is at once dismissed as a privacy concern by authorities yet trumpeted as the Next Big Thing by big-data outfits. In the case of a simple client/server model, metadata betrays with which hosts one communicates - this is often plenty enough to compromise privacy given that content is, in many cases, largely determinable from the host. - -With decentralised communications systems, e.g. a basic non-routed but encrypted VoIP call or Telehash communication, a network packet-sniffing attacker may not be able to determine the specific content of a transmission, but with the help of ISP IP address logs they would be able to determine to whom one communicated, when and how often. For certain types of applications in various jurisdictions, this is enough to be a concerning lack of privacy. - -Even with encryption and packet forwarding through a third relay node, there is still ample room for a determined bulk transmissions-collector to execute statistical attacks on timing and bandwidth, effectively using their knowledge of certain network invariants and the fact that only a finite amount of actors are involved (i.e. that nodes tend to forward messages between the same two peers with minimal latency and that there aren't all that many pairs of nodes that are trying to communicate via the same relay). There are ways to mitigate this attack vector, such as using multiple third-party relays and switching between them randomly or to use very strict framing, however both are imperfect and can lead to substantial inefficiencies. - -A truly dark system is one that is utterly uncompromising in information leakage from metadata. At its most secure mode of operation, Whisper can (at a considerable cost of bandwidth and latency) deliver 100% dark operation. Even better, this applies not only for metadata collection from inter-peer conduits (i.e. backbone dragnet devices), but even against a much more arduous "100% - 2" attack; i.e. where every node in the network were compromised (though functional) save a pair running ÐApps for people that wanted to communicate without anybody else knowing. - -### Routing and Lack Thereof - -Fundamentally, at least with the present state of computer science, all systems present a trade off between the efficiency of deterministic (and thus supposedly optimal) routing and darkness (or, put another way, routing privacy). One of Whisper's differences is in providing a user-configurable trade-off between ones routing privacy and ones routing efficiency. - -At its most dark, Whisper nodes are entirely reactive - they receive and record pieces of data and forward them trying to maximise the utility of information transmission to the peers. These pieces of information include what is known as a *topic*, which may be viewed both as a secure-probabilistic routing endpoint and/or a DHT multi-key. - -However, Whisper is also designed to be able to route probabilistically using two methods, both giving away minimal routing information and both being exceptionally resilient to statistical attacks from large-scale metadata collection. - -The first builds on the functionality of the ÐΞV-p2p backend. This backend provides the ability of Whisper to rate peers and, over time, probabilistically alter (or *steer*) its set of peers to those which tend to deliver useful (on-topic, timely, required for ones ÐApps to function) information. Ultimately, as the network evolves and the peer-set is steered, the number of hops between this peer and any others that tend to be good conduits of useful information (be they the emitters or simply the well-positioned hubs) will tend to 0. - -Peer steering also provides the incentive for nodes to provide useful information to peers. The fear of being identified as an under-performing peer and thus being rotated out in favour of other nodes gives all nodes incentive to cooperate and share the most useful information. Useful in this case means provably difficult to author (use of a proof-of-work function helps here); a low time-to-live; and well-corresponding to any provided information on what might be useful (read on for more). - -The second is more dynamic. Nodes are informed by their ÐApps over what sort of topics are useful. Nodes are then allowed to advertise to each peer describing these topics. Topics may be described, using masks or Bloom filters, and thus in an incomplete manner, to reduce the amount of information leaked and make passive statistical attacks arbitrarily difficult to execute. The determination of the amount of information to give to peers is both made through an explicit setting from the user and through topic/traffic modelling: "Given the information coming from this peer and my models of information distribution made from total traffic, am I receiving the amount of useful valuable information that I would expect to receive? If so, narrowing it down with additional description information to the peer may be warranted." - -These settings can even be configured per-peer (more trusted/longer-lasting peers may be afforded greater amounts of information), and per-ÐApp (those ÐApps that may be more sensitive could be afforded less advertising than others). We can also make use of proof-of-work algorithms to minimise the changes of both DoS attacks and 'everything-but' attacks (where a peer is flooded with almost-useful information prompting it to give away more about its true requirements than it would do otherwise). - -Through combining and reducing the Blooms/masks, weaker Nth-level information can be provided to peers about their peers' interests, forming a probabilistic topic-reception vortex around nodes, the "topic-space" gravity-well getting weaker and less certain the farther away with the network hop distance from any interested peers. - -## Basic Protocol Elements - -### Envelopes - -There are two key concepts in Whisper: *Envelopes* and *Messages*. Envelopes may be considered items should Whisper be considered a DHT. Should Whisper be considered a datagram messaging system then envelopes become the packet format which house the potentially encrypted datagrams. Envelopes are necessarily comprehensible by any node (i.e. they themselves are unencrypted). - -They contain information to the entry/datagram such as the original time to live (*TTL*), the absolute time for *expiry* and, importantly, the *topics*. Topics are a set of indexes to this item, recorded in order to help an interested party ("recipient") find it or have it routed to them. They might be likened to binary tags or keywords. Envelopes additionally contain a nonce allowing the original insertion node ("sender") to prove that some arbitrary amount of work was done in its composition. Finally, envelopes contain a message-*data* field; this stores the actual payload, together with some information and potentially a signature; together this forms a message. This field may be encrypted. - -Envelopes are transmitted as RLP-encoded structures. The precise definition is given by: - -[`expiry`: `P`, `ttl`: `P`, [`topic0`: `B_4`, `topic1`: `B_4`, ...], `data`: `B`, `nonce`: `P`] - -Here, `ttl` is given in seconds, `expiry` is the Unix time of the intended expiry date/time for the envelope. Following this point in time the envelope should no longer be transmitted (or stored, unless there is some extenuating circumstance). Prior to this point in time less the `ttl` (i.e. the implied insertion time), the envelope is considered utterly invalid and should be dropped immediately and the transmitting peer punished. - -`nonce` is an arbitrary value. We say the work proved through the value of the SHA3 of the concatenation of the nonce and the SHA3 of the RLP of the packet save the nonce (i.e. just a 4-item RLP list), each of the components as a fixed-length 256-bit hash. When this final hash is interpreted as a BE-encoded value, the smaller it is, the higher the work proved. This is used later to judge a peer. - -### Topics - -Topics are cryptographically secure, probabilistic partial-classifications of the message. Each topic in the set (order is unimportant) is determined as the first (left) 4 bytes of the SHA3-256 hash of some arbitrary data given by the original author of the message. These might e.g. correspond to "twitter" hash-tags or an intended recipient's public key hashed with some session nonce or application-identity. - -Four bytes was chosen to minimise space should a large number of topics be mentioned while still keeping a sufficiently large space to avoid large-scale topic-collision (though it may yet be reviewed and possibly made dynamic in later revisions of the protocol). - -### Messages - -A message is formed as the concatenation of a single byte for flags (at present only a single flag is used), followed by any additional data (as stipulated by the flags) and finally the actual payload. This series of bytes is what forms the `data` item of the envelope and is always encrypted. - -In the present protocol version, no explicit authentication token is given to indicate that the data field is encrypted; any would-be readers of the message must know ahead of time, through the choice of topic that they have specifically filtered for, that the message is encrypted with a particular key. This is likely to be altered in a further PoC to include a MAC. - -Any determination that the message is indeed from a particular sender is left for a higher-level to address. This is noted through the Javascript API allowing the `to` parameter to be passed only at the point of specifying the filter. Since the signature is a part of the message and not outside in the envelope, those unable to decrypt the message data are also unable to access any signature. - -- `flags`: 1 byte -- (`signature`: 65 bytes) -- `payload`: not fixed - -Bit 0 of the flags determines whether the signature exists. All other bits are not yet given a purpose and should be set randomly. A message is invalid if bit 0 is set but the total data is less than 66 bytes (since this wouldn't allow it to contain a signature). - -Payloads are encrypted in one of two ways. If the message has a specific recipient, then by using ECIES with the specific recipient's SECP-256k1 public key. If the message has no recipient, then by AES-256 with a randomly generated key. This key is then XORed with each of the *full* topics to form a salted topic. Each salted topic is stored prior to the encrypted data *in the same order as the corresponding topics are in the envelope header*. - -As a recipient, payloads are decrypted in one of two ways. Through use of topics, it should be known whether the envelope is encrypted to a specific recipient (in which case use the private key to decrypt) or to a general multicast audience. In the latter case, we assume that at least one topic is known (since otherwise, the envelope could not be properly "identified"). In this case, we match the known *full* topic to one of the abridged topics in the envelope, determine the index and de-salt the according salted-key at the beginning of the data segment in order to retrieve the final key. - -Encryption using the full topic with "routing" using the abridged topic ensures that nodes which are merely transiently storing the message and have no interest in the contents (thus have access only to routing information via the abridged topics) have no intrinsic ability to read the content of the message. - -The signature, if provided, is the SHA3-256 hash of the unencrypted payload signed using ECDSA with the insertion-identity's secret key. - -The signature portion is formed as the concatenation of the *r*, *s* and *v* parameters of the SECP-256k1 ECDSA signature, in that order. `v` is non-normalised and should be either 27 or 28. `r` and `s` are both big-endian encoded, fixed-width 32-byte unsigned. - -The payload is otherwise unformatted binary data. - -In the Javascript API, the distinction between envelopes and messages is blurred. This is because DApps should know nothing about envelopes whose message cannot be inspected; the fact that nodes pass envelopes around regardless of their ability to decode the message (or indeed their interest in it at all) is an important component in Whisper's dark communications strategy. - -### Basic Operation - -Nodes are expected to receive and send envelopes continuously, as per the [protocol specification](https://github.com/ethereum/wiki/wiki/Whisper-Wire-Protocol). They should maintain a map of envelopes, indexed by expiry time, and prune accordingly. They should also efficiently deliver messages to the front-end API through maintaining mappings between topics and envelopes. - -When a node's envelope memory becomes exhausted, a node may drop envelopes it considers unimportant or unlikely to please its peers. Nodes should consider peers good that pass them envelopes with low TTLs and high proofs-of-work. Nodes should consider peers bad that pass then expired envelopes or, worse, those that have an implied insertion time prior to the present. - -Nodes should always keep messages that its ÐApps have created. Though not in PoC-1, later editions of this protocol may allow ÐApps to mark messages as being "archived" and these should be stored and made available for additional time. - -Nodes should retain a set of per-ÐApp topics it is interested in. - -### Inserting (Authoring) Messages - -To insert a message, little more is needed than to place the envelope containing it in the node's envelope set that it maintains; the node should, according to its normal heuristics retransmit the envelope in due course. Composing an envelope from a basic payload, possible identities for authoring and access, a number of topics, a time-to-live and some parameters concerning work-proving targets is done though a few steps: - -- Compose `data` through concatenating the relevant flag byte, a signature of the payload if the user specified a valid author identity, and the user-given payload. -- Encrypt the data if an access ("destination") identity's public key is given by the user. -- Compose `topics` from the first 4 bytes of the SHA3 of each topic. -- Set user-given attribute `ttl`. -- Set the `expiry` as the present Unix time plus the time-to-live. -- Set the `nonce` as that which provides the most work proved as per the previous definition, after some fixed amount of time of cycling through candidates or after a candidate surpasses some boundary; either should be given by the user. - -### Topic Masking and Advertising - -Nodes can advertise their topics of interest to each other. For that purpose they use a special type of Whisper message (TopicFilterPacket). The size of Bloom Filter they send to each other must be 64 bytes. Subsequently the rating system will be introduced -- peers sending useful messages will be rated higher then those sending random messages. - -A message matches the bloom filter, if any one of the topics in this message, converted to the Whisper bloom hash, will match the bloom filter. - -Whisper bloom function accepts AbridgedTopic as a parameter (size: 4 bytes), and produces a 64-byte hash, where three bits (at the most) are set to one, and the rest are set to zeros, according to the following algorithm: - -0. Set all the bits in the resulting 64-byte hash to zero. - -1. We take 9 bits form the AbridgedTopic, and convert to integer value (range: 0 - 511). - -2. This value defines the index of the bit in the resulting 512-bit hash, which should be set to one. - -3. Repeat steps 1 & 2 for the second and third bit to be set in the resulting hash. - -Thus, in order to produce the bloom, we use 27 bits out of 32 in the AbridgedTopic. For more details, please see the implementation of the function: TopicBloomFilterBase::bloom() [libwhisper/BloomFilter.h]. - -### Coming changes - -Also being considered for is support for plausible deniability through the use of session keys and a formalisation of the multicast mechanism. \ No newline at end of file diff --git a/Whisper-PoC-2-Wire-Protocol.md b/Whisper-PoC-2-Wire-Protocol.md deleted file mode 100644 index bbcc960b9..000000000 --- a/Whisper-PoC-2-Wire-Protocol.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -name: Whisper PoC-2 Wire Protocol -category: ---- - -Peer-to-peer communications between nodes running Whisper clients run using the underlying [ÐΞVp2p Wire Protocol](https://github.com/ethereum/wiki/wiki/%C3%90%CE%9EVp2p-Wire-Protocol). - -This is a preliminary wire protocol for the Whisper subsystem. It will change. - -### Whisper Sub-protocol - -**Status** -[`+0x00`: `P`, `protocolVersion`: `P`] Inform a peer of the **whisper** status. This message should be send _after_ the initial handshake and _prior_ to any **whisper** related messages. -* `protocolVersion` is one of: - * `0x02` for PoC-7. - -**Messages** -[`+0x01`: `P`, [`expiry1`: `P`, `ttl1`: `P`, [`topic1x1`: `B_4`, `topic1x2`: `B_4`, ...], `data1`: `B`, `nonce1`: `P`], [`expiry2`: `P`, ...], ...] Specify one or more messages. Nodes should not resend the same message to a peer in the same session, nor send a message back to a peer from which it received. This packet may be empty. The packet must be sent at least once per second, and only after receiving a **Messages** message from the peer. - -**TopicFilter** -[`+0x02`: `P`, `bloom`: `B_64`] Specify the bloom filter of the topics that the sender is interested in. The bloom method is defined below. - -### Session Management - -For the Whisper sub-protocol, upon an active session, a `Status` message must be sent. Following the reception of the peer's `Status` message, the Whisper session is active. The peer with the greatest Node Id should send a **Messages** message to begin the message rally. From that point, peers take it in turns to send (possibly empty) Messages packets. - -### Topics and Abridged Topics - -*Topics* are 32-byte hashes, typically generated from ÐApp-specified data. The *abridged topic* is the first 4 bytes of the topic. Abridged topics allow the identification (within the bounds of an acceptably high probability) of a given topic, useful for determining the utility of a topic for a given peer, yet do not give away the full topic information itself, allowing it to be used as a strong encryption key whose secret is not inherently available. - -### Bloomed Topics - -The Bloom filter used in the `TopicFilter` message type is a means a identifying a number of topics to a peer without compromising (too much) privacy over precisely what topics are of interest. Precise control over the information content (and thus efficiency of the filter) may be maintained through the addition of bits. - -Blooms are formed by the bitwise OR operation on a number of bloomed topics. The bloom function takes the abridged topic (the first four bytes of the SHA3 of the ÐApp/user level topic description) and projects them onto a 512-bit slice; in total, three bits are marked for each bloomed topic. - -The projection function is defined as a mapping from a a 4-byte slice `S` to a 512-bit slice `D`; for ease of explanation, `S` will dereference to bytes, whereas `D` will dereference to bits. - -``` -LET D[*] = 0 -FOREACH i IN { 0, 1, 2 } DO -LET n = S[i] -IF S[3] & (2 ** i) THEN n += 512 -D[n] = 1 -END FOR -``` - -In formal notation: -``` -D[i] := f(0) == i || f(1) == i || f(2) == i -``` -where: -``` -f(x) := S[x] + S[3][x] * 512 -``` -(assuming a byte value `S[i]` may be further dereferenced into a bit value) - diff --git a/Whisper-Wire-Protocol.md b/Whisper-Wire-Protocol.md deleted file mode 100644 index 8a98baa31..000000000 --- a/Whisper-Wire-Protocol.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -name: Whisper Wire Protocol -category: ---- - -Peer-to-peer communications between nodes running Whisper clients run using the underlying [ÐΞVp2p Wire Protocol](https://github.com/ethereum/wiki/wiki/%C3%90%CE%9EVp2p-Wire-Protocol). - -This is a preliminary wire protocol for the Whisper subsystem. It will change. - -### Whisper Sub-protocol - -**Status** -[`+0x00`: `P`, `protocolVersion`: `P`] Inform a peer of the **whisper** status. This message should be send _after_ the initial handshake and _prior_ to any **whisper** related messages. -* `protocolVersion` is one of: - * `0x02` for PoC-7. - -**Messages** -[`+0x01`: `P`, [`expiry1`: `P`, `ttl1`: `P`, [`topic1x1`: `B_4`, `topic1x2`: `B_4`, ...], `data1`: `B`, `nonce1`: `P`], [`expiry2`: `P`, ...], ...] Specify one or more messages. Nodes should not resend the same message to a peer in the same session, nor send a message back to a peer from which it received. This packet may be empty. The packet must be sent at least once per second, and only after receiving a **Messages** message from the peer. - -### Session Management - -For the Whisper sub-protocol, upon an active session, a `Status` message must be sent. Following the reception of the peer's `Status` message, the Whisper session is active. The peer with the greatest Node Id should send a **Messages** message to begin the message rally. From that point, peers take it in turns to send (possibly empty) Messages packets. - diff --git a/Whisper.md b/Whisper.md deleted file mode 100644 index 1aa067b56..000000000 --- a/Whisper.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -name: Whisper -category: ---- - -### Use case - -* DApps that need to publish small amounts of information to each other and have the publication last some substantial amount of time. For example, a currency exchange DApp may use it to record an offer to sell some currency at a particular rate on an exchange. In this case, it may last anything between tens of minutes and days. The offer wouldn't be binding, merely a hint to get a potential deal started. - -* DApps that need to signal to each other in order to ultimately collaborate on a transaction. For example, a currency exchange DApp may use it to coordinate an offer prior to creating one (or two, depending on how the exchange is structured) transactions on the exchange. - -* DApps that need to provide non-real-time hinting or general communications between each other. E.g. a small chat-room app. - -* DApps that need to provide dark (plausible denial over perfect network traffic analysis) comms to two correspondents that know nothing of each other but a hash. This could be a DApp for a whistleblower to communicate to a known journalist exchange some small amount of verifiable material and arrange between themselves for some other protocol (Swarm, perhaps) to handle the bulk transfer. - -In general, think transactions, but without the eventual archival, any necessity of being bound to what is said or automated execution & state change. - -### Specs - -* **Low-level** API only exposed to DApps, never to users. -* **Low-bandwidth** Not designed for large data transfers. -* **Uncertain-latency** Not designed for RTC. -* **Dark** No reliable methods for tracing packets or -* Typical usage: - * Low-latency, 1-1 or 1-N signalling messages. - * High latency, high TTL 1-* publication messages. - -Messages less than 64K bytes, typically around 256 bytes. - -### Existing solutions - -* UDP: Similar in API-level, native multicasting. No TTL, security or privacy safeguards. -* [0MQ](http://zeromq.org/): A distributed messaging system, no inherant privacy safeguards. -* [Bitmessage](https://bitmessage.org/wiki/Main_Page): Similar in the basic approach of P2P network exchanging messages with baseline PKI for dark comms. Higher-level (e-mail replacement, only "several thousand/day", larger mails), fixed TTL and no hinting to optimise for throughput. Unclear incentivisation. -* [TeleHash](https://github.com/telehash/telehash.org/blob/master/network.md#paths): Secure connection-orientated RTC comms. Similar in approach to BitTorrent (uses modified Kademila tech), but rather than discovering peers for a given hash, it routes to the recipient given its hash. Uses DHT to do deterministic routing therefore insecure against simple statistical packet-analysis attacks against a large-scale attacker. Connection oriented, so no TTL and not designed for asynchronous data publication. -* [Tox](https://github.com/irungentoo/toxcore/blob/master/docs/updates/DHT.md): Higher-level (IM & AV chat) replacement. - -### Basic Design - -Uses the `"shh"` protocol string of ÐΞVP2P. - -Rest coming soon, once I've finished prototyping. Gav. - -### Considerations for Defeating Traffic Analysis -(from lokiverloren) All existing protocols for location obscured instant messaging have complicated problems to do with routing. - -The Bitmessage protocol propagates messages blindly across the network, and the proper recipient knows how to decrypt it and receives it (just like everyone else) but then stores it and lets its' user know it's got a new message. The problem with this of course is that it greatly increases the exposure of the whole network to a body of encrypted material that ideally should not be easily accessed at all. - -None of the others listed above particularly have any means to hide the source and destination of messages. I believe it is one of the core objectives of the Whisper protocol to hide location of sender and receiver and in transit, make it difficult if not impossible to establish one, the other or both. - -The Tor system has a protocol for enabling connections between two nodes without either knowing where the other is, it is the Rendezvous protocol used for hidden services. Most readers of this will already understand how it works, but what happens is that a hidden service (the equivalent of a server listening on a port in the TCP/IP protocol) selects at random a number (I think, usually 6) 'introducer' nodes. In order to do this it establishes the standard 3-hop chain to each of the introducers, and when a user wants to establish a connection with a hidden service, they propagate a request to connect with hidden service that is associated with a particular public key. I'm not sure about how this request is propagated, obviously it would also have to be done through a circuit or the rendezvous introducer node knows who might be about to establish a circuit. Once one's client knows a valid rendezvous node it then establishes a connection to it and requests to have traffic relayed through its' circuit to the hidden service. - -I think there really isn't a better way to implement 'dark' parts of the connection protocol, because there has to be a different identity for a relay node as a client node, the same principle applies in Ethereum. However, using the rendezvous, it again makes possible something for connections between nodes that know each other (though they don't know the account or identity of the initiator) something other than the uniform 3 hop circuit. For generating a circuit to an exit node in Tor, it is of no danger that your client knows the identity of the relays in each hop along the way, but to do that *within* the network compromises location obfuscation security, tying your ethereum identity with your router identity (I think it may need to be explicitly pointed out that routing function is something that Ethereum nodes will perform). When connecting to a rendezvous, you do not thereby reveal your location to the rendezvous, and the rendezvous does not know the location of the hidden service either, and establishing these connections only requires a public directory to be created for routers. It is not consequential information for an attacker and can be revealed directly by probing for a relevant server at your IP addresses anyway. - -The contribution I would like to make to the discussion is this: - -1. It is implied that the whisper protocol has to work through a system of location obfuscation relays like Tor. Not only this, but it must therefore also be using some form of the rendezvous protocol used in Tor for hidden services. - -2. However, as Tor was originally designed first to be a way to stop webservers logging your IP address in association with a session cookie and record, then secondarily added the ability to implement the equivalent of TCP/IP routing (listening ports) within the context of location obfuscation in the form of the rendezvous protocol, it is an artifact, a legacy of the first purpose that leads to the uniform utilisation of 3 hop nodes and connections that remain open rather than a session (connectionless) protocol like used in HTTP. What I suggest is that, depending on the needs of a particular connection, there can be occasion to mix up the obfuscation process so that it is further obscured from traffic analysis in the case of malicious nodes performing data gathering for an attacker. - -Instead of a connection like is normal between a browser and web server, for example, which is usually left open because of the latency of reestablishing such a connection, to make further requests, instead there can be a session cookie, and then you can alter the way your client sends data through the 'connection' to a hidden node. The connection, between two routing nodes, could be direct, 1 proxy intermediary, 2, or 3, it could use shared secrets instead and route fragments of datagrams across multiple heteregenous circuits, as well, and the receiver would then wait for sufficient fragments to assemble the original packets. Indeed, it could be possible in the case of (not quite related to whisper, but to the distributed data storage protocol) larger streams, break the stream up into parts and alter the obfuscation method through the process, further confusing the traffic analysis data. - -The same considerations apply, fundamentally, the only differences have to do with the size of the data being transmitted, whether it's for a messaging system or distributed filesystem. The other criteria for deciding how to scramble the routing is latency. For some purposes one wants lower latency, and other purposes, greater security is vitally important. When in the process streams are fragmented into parts, it can also increase security to apply an All Or Nothing Transform to the entire package, then if part is intercepted but not the complete message, it is impossible to assemble the data, not even for cryptanalysis purposes. \ No newline at end of file diff --git a/[German]-Clearinghaus.md b/[German]-Clearinghaus.md deleted file mode 100644 index 66fc121c8..000000000 --- a/[German]-Clearinghaus.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -name: Clearinghaus -category: ---- - -### Einleitung -Bei manchen Finanzinstrumente wie ["Future"] (http://de.wikipedia.org/wiki/Future) (keine Geldtermingeschäfte) können sich die Parteien gegen Zahlungsausfälle gegenüber dem Geschäftspartner (i.d.R. bei einem Clearinghaus) absichern. Im Wesentlichen liefert eine Clearingstelle diese Garantie über ein Verfahren, bei dem die Gewinne und Verluste, die sich aus dem börslichen Handel dieser Features über die Vertragslaufzeit ergeben, durch tägliche Abrechnung in Bargeld umgewandelt werden. -### Tägliche Abrechnung -Wie erklärt, wird die "tägliche Abrechnung" von Gewinnen oder Verlusten in Bargeld konvertiert. Dieser Vorgang wird auch ** Marktbewertung ** bezeichnet und lässt sich am Besten über ein Beispiel veranschaulichen. -Angenommen zwei Parteien gehen einen Vertrag ein, einen [Vertragsgegenstand] (http://de.wikipedia.org/wiki/Underlying) zu einem vereinbarten Preis von 100 USD in einem Monat zu kaufen/verkaufen. Um diesen Vertrag einzugehen verlangt die Clearingstelle einen Vorschuss beider Partein, die diesen vorab begleichen müssen. Also die Partei, die den Vertragsgegenstand kaufen will [(** Halter der long position **)] (http://de.wikipedia.org/wiki/Long_und_Short) und die Partei, die den Vertragsgegenstand verkaufen will [(** Halter der short position **)] (http://de.wikipedia.org/wiki/Long_und_Short). -Die Vorschusszahlung möge 5 USD betragen und wird einbezahlt in einen **margin account** des Clearinghauses, gebunden an den spezifischen Vertrag. -Während der Laufzeit des Vertrags variiert der Betrag auf dem **margin account**. Die in dem Vertrag involvierten Parteien müssen das Guthaben des **margin account** über einem bestimmten Level halten, genannt **maintenance margin requirement**, der von dem Clearinghaus bestimmt wird und i.d.R. unterhalb der Höhe des Zahlungsvorschusses liegt. -Am Ende eines jeden Tages wird die Clearingstelle einen ** Abrechnungspreis ** bieten (in der Regel ein Durchschnittspreis aller Trades, die im Laufe des Tages passiert sind) um dann das ** Mark-to-Market-Verfahren ** (tägliche Abrechnungs) durchzuführen. -In unserem konkreten Beispiel nehmen wir an, dass die Höhe der Sicherheitsleistung, die nicht unterschritten werden darf (**maintenance margin requirement**) auf einen Betrag von 3 USD festgelegt wird und die kaufende Partei 10 Verträge eingeht. D.h. es wird eine Vorschusszahlung von 10 x 5 USD = 50 USD fällig. Wir gehen auch davon aus, dass das Geld von der Clearingstelle nicht zurückgebucht werden kann (z.B. Überschüsse). Der Initialpreis (des Future Contracts) beträgt 100 USD. -Ein vollständiges beispiel zeigt die folgende Tabelle. Es sei darauf hingeweisen, dass beide Tafeln die täglichen Salden beider Partein berichten (long position und short position). -#### Tafel A. Halter der Long Position von 10 Verträgen -|Tag (1)|Startsaldo (2)|Vorschusszahlung (3)|[Settlementpreis](http://boerse.ard.de/boersenwissen/boersenlexikon/settlement-preis-100.html) (4)| Änderung des Preises des (5)|Gewinn/Verlust (6)|Endsaldo (7)| -|:----------:|-------------:|------:|---:|---:|---:|---:| -|0|0|50|100.0| - | - |50| -|1|50|0|99.20| -0.80| -8|42| -|2|42|0|96.00| -3.20| -32|10| -|3|10|40|101.00|5.00|50|100| -|4|100|0|103.50|2.50|25|125| -|5|125|0|103.00| -0.50| -5|120| -|6|120|0|104.00|1.00|10|130| -#### Tafel B. Halter der Short Position von 10 Verträgen -|Tag (1)|Startsaldo (2)|Vorschusszahlung (3)|[Settlementpreis](http://boerse.ard.de/boersenwissen/boersenlexikon/settlement-preis-100.html) (4)| Änderung des Preises des (5)|Gewinn/Verlust (6)|Endsaldo (7)| -|:----------:|-------------:|------:|---:|---:|---:|---:| -|0|0|50|100.0| -| -|50 -|1|50|0|99.20| -0.80|8|58 -|2|58|0|96.00| -3.20|32|90 -|3|90|0|101.00|5.00| -50|40 -|4|40|0|103.50|2.50| -25| 15 -|5|15|35|103.00| -0.50| 5|55 -|6|55|0|104.00|1.00| -10|45|} -Der Tag des Vertragsabschlusses wird als'' Tag 0'' bezeichnet, an dem beide Parteien eine Vorschusszahlung von 50 USD hinterlegen. Wir nehmen an, dass am "Tag 1" der Preis des Futures auf 99,20 USD fällt, wie in Spalte 4 der Tafel A angegeben. In Spalte 5 können wir die Änderung des Preises des Futures sehen -0,80 USD (99,20 - 100) und dieser Betrag wird mit der Zahl der Verträge (10) multipliziert um in Spalte 6 den Gewinn/Verlust zu erhalten: -0,80 x 10 = - 8 USD. Der Endsaldo ist in Spalte 7 zu sehen, welcher dem Anfangssaldo des nächsten Tages entspricht. Der Endsaldo am Tag 1 für den Inhaber der Long-Position ist 42 USD und liegt somit über dem Mindestsaldo der Sicherheitsleistung (**maintenance margin**) von 3 x 10 USD = 30 USD, so dass keine Nachschuss erforderlich ist, um über diesen Wert zu kommen. -### Ethereum Clearinghaus Implementierung und Logik -* gilt es für alle Verträge? -* welches Falg muss gesetzt werden um die Clearinghaus zu ermöglichen? -* wie werden das Geld / Ether belastet / gutgeschrieben? Push oder Pull System? -* Normalerweise verwenden Clearinghäuser einen durchschnittlichen Tagespreis (nicht den Abschlusspreis). Wie ist das umsetzen? Dies ist wichtig um Preismanipulation zu VERMEIDEN! Ethereum würde noch mehr gefährdet sein als klassische Clearingstellen. -* Was passiert im Falle des Ausfalls (fehlerhafte Nachschussaufforderung)? Reputationssystem? -* viele Verträge benötigen einen externen Marktkurs (z.B. Goldpreis von CME oder LIBOR, kinssätze). Wie können sie damit gefüttert werden? -* kann Geld von der Clearingstelle zurückgebucht werden (z.B. überschüssige Mittel / Gewinne)? Es wäre einfacher, wenn dies nicht der Fall wäre. -* Was ist, wenn die Parteien wirklich den Vertragsgegenstand austauschen wollen? Z.B. keine Bargeld- / Ether- Abmachungen? (NICHT SUPPORTED VOM CLEARINGHAUS) -* Verluste / Gewinne werden durch durch die von der Clearingstelle zur Verfügung gestellten Hebel von Natur aus vergrößert. AKZEPTABEL FUER ETHERUEM? HINWEIS: OBWOHL DIE VOLLSTÄDIGE SUMME NICHT VORAB HINTERLEGT WERDEN BRAUCHT -### Code reference sample diff --git a/[Italian]-Impostare-il-proprio-ambiente-di-sviluppo-Ethereum.md b/[Italian]-Impostare-il-proprio-ambiente-di-sviluppo-Ethereum.md deleted file mode 100644 index 14537ccd2..000000000 --- a/[Italian]-Impostare-il-proprio-ambiente-di-sviluppo-Ethereum.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -name: Impostare il proprio ambiente di sviluppo Ethereum -category: ---- - -Lo sviluppo su Ethereum e’ stato concepito per essere estremamente facile da imparare per gli sviluppatori – e i linguaggi di programmazione sono abbastanza simili allo Javascript che chiunque conosca quel linguaggio dovrebbe acquisirne padronanza piuttosto velocemente. - -Ci sono tre programmi che ogni sviluppatore dovrebbe scaricare – Alethzero, Mist e Mix. - -* **Alethzero** e’ un client a interfaccia grafica con caratteristiche avanzate come chain private, force mining e una webkit suite completa. - -* **Mist** e’ il browser delle Dapp e il client per il mining nel quale gli utenti accederanno alle vostre Dapps. - -* Infine, **Mix** e’ un ambiente di sviluppo integrato – concepito appositamente per sviluppare e debuggare i contratti e i loro corrispettivi front-end. - -## Requisiti software: - -Impostare un ambiente di sviluppo dovrebbe essere abbastanza semplice per chiunque ha mai progettato una pagina web prima d’ora – abbiamo tre programmi specifici che dovreste scaricare: - -In primo luogo, [scaricate](https://github.com/ethereum/cpp-ethereum/wiki) l’ultima versione stabile di Alethzero, il nostro client scritto in C++, e installatelo sul vostro sistema operativo. Se avete problemi con l’ultima versione stabile di sviluppo, provate a passare alla versione cutting edge, che dovrebbe risolvere alcuni dei problemi. Se invece scegliete di fare un build della vostra versione, allora le istruzioni sono qui. - -In secondo luogo, installate [Mix](https://github.com/ethereum/cpp-ethereum/releases) il nostro ambiente di sviluppo integrato disponibile per Windows e Mac. Se utilizzate Linux, seguite le istruzioni qui per installare Mix. - -Infine, installate [Mist](https://github.com/ethereum/go-ethereum#automated-dev-builds) per testare le vostre Dapps e calibrare i vostri front-end a mano a mano che li sviluppate. - -## Extras - -Un text editor o Mix puo’ essere utilizzato per creare il codice backend dei contratti che scriveremo. Per il linguaggio Serpent vi suggeriamo di programmare il vostro editor affinche’ consideri i contratti scritti in Serpent e salvati con il suffisso ‘.se’ come sintassi python e per il linguaggio Solidity vi consigliamo di salvare i files con il suffisso ‘.sol’. - -Il live refresh non e’ raccomandato mentre lavorate sulla vostra front-end in html, dato che non e’ stato testato appieno. - -## Installare Alethzero - -Il nostro ambiente di sviluppo integrato Mix e’ al momento in constante sviluppo e nonostante alcune caratteristiche siano gia’ presenti in questo tutorial ci concentreremo principalmente sullo sviluppo dei contratti, e la costruzione dei frontend utilizzando il nostro client di sviluppo Alethzero. Alethzero ha un compilatore gia’ integrato, una console javascript, e gli strumenti necessari per dare un’occhiata allo stato della blockchain. - -A meno che non sia espressamente specificato, questo tutorial deve essere eseguito su Alethzero utilizzando una chain privata e senza connettersi alla rete – inserire contratti nella rete di test dovrebbe essere riservato a quei contratti che volete condividere con altri. Quando caricate alethzero in questa modalita’ e’ possibile che altri accedano alla vostra chain fintanto che utilizzano lo stesso nome e usano la funzione ‘connect-to-peer’ per connettersi direttamente. diff --git a/[Italian]-Introduzione-allo-sviluppo-su-Ethereum.md b/[Italian]-Introduzione-allo-sviluppo-su-Ethereum.md deleted file mode 100644 index 4bd0b33aa..000000000 --- a/[Italian]-Introduzione-allo-sviluppo-su-Ethereum.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -name: Introduzione allo sviluppo su Ethereum -category: ---- - -_traduzione in Italiano da [Dapps for beginners blog => Introduction to development on Ethereum](https://dappsforbeginners.wordpress.com/tutorials/introduction-to-development-on-ethereum/)_ - -# Ethereum – una rete di consenso decentralizzato - -Per la maggior parte degli sviluppatori imparare come utilizzare una nuova piattaforma, o un linguaggio di programmazione, o un nuovo framework rappresenta un compito familiare, probabilmente ripetuto dozzine di volte durante la loro carriera. Molto diverso e’ l’imparare a sviluppare per un paradigma completamente differente. La rete di consenso decentralizzato, la blockchain, e la sua implementazione piu’ conosciuta ‘bitcoin’ non sono ben compresi neppure dalla comunita’ degli sviluppatori e le sfumature di come questa tecnologia sia radicalmente diversa da cio’ che abbiamo utilizzato fino ad ora sono certamente ignote alla maggior parte del pubblico. - -Tenendo cio’ a mente, prima di procedere a costruire la nostra prima decentralised apps indicheremo l'insieme di quelle tecnologie principali che servono a creare un network di consenso decentralizzato, e la teoria dei giochi che fa uso di queste tecnologie per creare un network. - -## Tecnologie principali - -**[Crittografia a chiave pubblica (anche deta crittografia asimmetrica)](http://it.wikipedia.org/wiki/Crittografia_asimmetrica)** - -La crittografia asimmetrica e’ quell'insieme di metodi di criptazione che richiede la creazione di due chiavi separate; la “chiave privata” - che e’ nota solo al proprietario - e la “chiave pubblica” che e’ nota a chiunque. Questo tipo di crittografia possiede una serie di utili attributi, il primo e’ che chiunque e’ in grado di criptare dati con una chiave pubblica che possono essere decriptati solamente dalla chiave privata. - -Il secondo e’ l’abilita’ per il possessore della chiave privata di “firmare” qualsiasi informazione utilizzando la propria chiave privata, affinche' chiunque abbia la chiave pubblica possa verificare la firma, ma senza che si rilascino informazioni sulla chiave privata. Questo secondo attributo e’ usato per il sistema di account in un network di consenso decentralizzato, e sta alla base dell’invio delle transazioni. - -**[Funzione crittografica di hash](http://it.wikipedia.org/wiki/Funzione_crittografica_di_hash)** - -Una funzione di hash e’ una funzione che prende un segmento di informazione di qualsiasi dimensione e lo mappa su un altro segmento di dimensione fissa, e.g. un file di 1MB o di 500kb - se vengono sottoposti ad una funzione di hash - producono “hashes” di 128 bit di dimensione ciascuno. Una funzione crittografica di hash assolve a questo compito e lo fa anche rispettando tre importanti requisiti: 1) non viene fornita nessuna informazione su che tipo di dati abbiano prodotto l’hash (ovvero, la funzione e’ irreversibile), 2) una piccola variazione nel dato di input produce un hash estremamente differente, in modo che l’hash non puo’ essere calcolato se non utilizzando la funzione di hash (ovvero, niente scorciatoie!!), 3) c’e’ una probabilita’ estremamente bassa che due dati di input diversi producano lo stesso hash. - -**[Il networking peer-to-peer](http://it.wikipedia.org/wiki/Peer-to-peer)** - -A differenza del modello “Client-Server”, il modello “peer-to-peer” consiste di reti di computer connessi direttamente l’un l’altro, senza che questi inoltrino alcuna richiesta ad un server centrale. Tutti i computer che fanno parte della rete sono considerati “peers” (pari, in inglese) e mantengono l’un l’altro una posizione paritaria all’interno della rete stessa. Le reti "peer-to-peer" generalmente si basano sull’altruismo, ovvero ogni computer fornisce alla rete almeno lo stesso ammontare di risorse che trae dalla stessa. - -##Tecnologie della cripto-economia - -**[La Blockchain](http://it.wikipedia.org/wiki/Bitcoin#Tecnologia)** - -La Blockchain in tutte le sue incarnazioni e’ un tipo di database progettato specificatamente per essere utilizzato in una rete di consenso decentralizzato. Puo’ contenere qualsiasi informazione, e puo’ stabilire delle regole sulla maniera in cui l’informazione viene aggiornata. La sua caratteristica principale e’ che viene aggiornata a spezzoni chiamati “blocchi” che sono “incatenati” usando degli hashes del contenuto dei blocchi precedenti. Una blockchain contiene non solo l’informazione contenuta attualmente nel database, ma anche ogni cambiamento apportato al database nel corso della sua storia. Dati lo stato e le transazioni, la blockchain rappresenta un database con una storia completa che non puo’ essere alterata senza alterare ciascuno dei blocchi successivi. Una chiave privata crittografica firma ogni “transazione” o richiesta di cambiare lo stato del database, e la firma stessa e’ custodita nella blockchain. - -**[La Proof-of-work](http://it.wikipedia.org/wiki/Proof-of-work)** - -Pensato inizialmente come un sistema per prevenire lo spam, il sistema di proof of work e’ un semplice metodo per assicurarsi che tu abbia ***probabilmente*** compiuto una grande quantita’ di operazioni matematiche. E’ implementato nella maggior parte dei casi utilizzando una funzione di hash crittografica; dato un segmento di informazione arbitrario, (ad esempio come una lista di transazioni e l’intestazione di un blocco) devi trovare un secondo segmento di infromazione che, unito al primo, produce un hash che ha determinate caratteristiche (come ad esempio un certo numero di zeri consecutivi). Dato che e’ impossibile predirre quale e’ il secondo segmento di informazione che produrra’ l’hash richiesto, devi iterare casualmente attraverso tutti i dati possibili finche’ non trovi quel segmento di dati che produce l’hash di cui hai bisogno. - -## Tecnologie di Ethereum - -**La Ethereum Virtual Machine** - -La Ethereum Virtual Machine e’ l’innovazione principale del progetto Ethereum. Si tratta di una virtual machine progettata per essere eseguita da tutti i partecipanti in una rete peer-to-peer, puo’ leggere e scrivere su una blockchain sia codice eseguibile che dati, verificare firme digitali, e puo’ far girare codice in maniera quasi Turing-completa. Eseguira’ del codice solo quando riceve un messaggio verificato da una firma digitale, e quando l’infomazione che e’ contenuta nella blockchain le dira’ che e’ appropriato farlo. - -**La Rete di Consenso Decentralizzato e la Blockchain Generalizzata** - -Ethereum e’ una rete peer to peer dove ogni peer salva la stessa copia del database blockchain e fa girare una Ethereum virtual machine per mantenere ed alterare il suo stato. La Proof of work e’ integrata nella tecnologia blockchain facendo si’ che la creazione di un nuovo blocco richieda che tutti i membri del network realizzino la proof-of-work. Il consenso e’ ottenuto tramite l’incentivizzazione per i peer ad accettare sempre la sequenza piu’ lunga di blocchi nella blockchain mediante la distribuzione di un gettone di valore crittografico: l’ether. - -In questo modo abbiamo una nuova tecnologia che sicuramente non rientra nel modello client-server ma non si qualifica neppure all’interno di un tradizionale modello peer-to-peer in quanto la sua esistenza e’ incentivizzata, ovvero si puo’ ragionevolmente stare certi che provvedera’ un servizio deterministico consistente. - -Data la sua natura allargata e la sicurezza criptografica costruita al suo interno puo’ fungere da third party, capace di arbitrare senza fiducia e senza interferenza di parti esterne. Attraverso l’uso di decisioni tipiche del sistema di cryptocurrencies fatte dal software possiamo avere conseguenze finanziarie per le persone, le organizzazioni o persino per altro software. - -Cio’ da’ agli sviluppatori un nuovo modo per rendere possibili le interazioni tra le parti su internet. - -Mentre spiegheremo i vari temi dello sviluppo delle decentralized apps illustreremo il motivo del loro utilizzo e faremo del nostro meglio per spiegare l’importanza di ciascuna. - -### Ulteriori letture - -* [Libro Bianco di Ethereum - tradotto in Italiano ](https://github.com/ethereum/wiki/wiki/%5BItalian%5D-Libro-Bianco) -* [Yellow Paper di Ethereum, la specificazione formale - inglese](https://github.com/ethereum/yellowpaper) -* [Blog di Ethereum - inglese](https://blog.ethereum.org/) - -_traduzione di M.Terzi - @terzim - [LinkedIn](https://uk.linkedin.com/in/massimilianoterzi)_ diff --git a/[Italian]-Libro-Bianco.md b/[Italian]-Libro-Bianco.md deleted file mode 100644 index c5a8f20b2..000000000 --- a/[Italian]-Libro-Bianco.md +++ /dev/null @@ -1,503 +0,0 @@ ---- -name: Libro Bianco -category: ---- - -Ethereum: Libro Bianco - White Paper (di Leonardo Maria Pedretti: lm.pedretti@gmail.com) -[Linkedin](https://www.linkedin.com/in/leonardompedretti) - -### Una Piattaforma di Nuova Generazione per i Contratti Intelligenti e le Applicazioni Decentralizzate - -Quando Satoshi Nakamoto diede per primo inizio, nel Gennaio 2009, alla blockchain del Bitcoin, stava introducendo due concetti radicali e, fino ad allora, mai testati. Il primo è il "bitcoin", una moneta online peer-to-peer decentralizzata che mantiene un valore senza nessun supporto, [valore intrinseco](http://bitcoinmagazine.com/8640/an-exploration-of-intrinsic-value-what-it-is-why-bitcoin-doesnt-have-it-and-why-bitcoin-does-have-it/) o emittente centrale. Finora, il "Bitcoin", nella veste di unità monetaria, ha catalizzato la maggior parte dell'attenzione del pubblico, sia in termini di aspetti politici di una moneta senza una banca centrale, sia per l' estrema volatilità, verso l'alto e verso il basso, del prezzo. Comunque c'è anche un'altra, ugualmente importante, parte del grandioso esperimento di Satoshi: il concetto di una blockchain basata sul proof-of-work, che garantisce un pubblico consenso sul sistema delle transazioni. Il Bitcoin, nella veste di applicazione, può essere descritto come un sistema first-to-file: se un'entità ha 50 BTC, e simultaneamente invia gli stessi 50 BTC ad A e a B, solamente la transazione che viene confermata per prima sarà processata. Precedentemente non esisteva alcun modo intrinseco per determinare quale delle due transazioni fosse avvenuta prima, e per decenni ciò ha ostacolato lo sviluppo delle monete digitali decentralizzate. La blockchain di Satoshi era la prima soluzione decentralizzata. Attualmente, l'attenzione sta iniziando rapidamente a spostarsi verso questa secondo risvolto della tecnologia Bitcoin, ed, in particolare, come il concetto di blockchain possa essere utilizzato per qualcosa di più che il denaro. - -Tali nuove applicazioni, includono l'utilizzo di risorse digitali sulla blockchain per rappresentare valute personalizzate e strumenti finanziari (["monete colorate"](https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit)), la proprietà di un dispositivo fisico sottostante (["proprietà intelligente"](htups://en.bitcoin.it/wiki/Smart_Property)), assets non fungibili, quali nomi di dominio ("Namecoin") così come le più avanzate applicazioni tipo un exchange decentrallizzato, derivati finanziari, il gioco d'azzardo peer-to-peer ed il sistema di identità e di reputazione sulla blockchain. Un'altra importante area di indagine sono i "contratti intelligenti" - sistemi che trasferiscono automaticamente assets digitali, in accordo con regole pre-impostate. Per esempio, si potrebbe avere un contratto di tesoreria nella forma "A può trasferire a X alcune unità di moneta al giorno, B può trasferire a Y alcune unità di moneta al giorno, A e B insieme non possono trasferire niente, ed A può precludere l' "abilità di trasferire" di B. La logica estensione di ciò sono le [organizzazioni autonome decentralizzate](http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/) (DAOs) - contratti intelligenti a lungo termine che gestiscono assets e codificano lo statuto di un'intera organizzazione. Quello che Ethereum intende garantire è una blockchain con una linguaggio di programmazione di Turing, completo e costruito al suo interno, che può essere usato per creare "contratti" e per codificare le funzioni arbitrarie di transizione, permettendo agli utenti di creare uno dei sistemi sopra descritti, così come molti altri che ancora non abbiamo immaginato, semplicemente scrivendo la logica in poche righe di codice. - -### Tavola dei Contenuti - -* [Storia](#Storia) - * [Bitcoin come un Sistema di Transizione di Stato](#Bitcoin-come-un-Sistema-di-Transizione-di-Stato) - * [Mining](#mining) - * [Merkle Trees](#merkle-trees) - * [Applicazioni Alternative della Blockchain](#applicazioni-alternative-della-blockchain) - * [Scripting](#scripting) -* [Ethereum](#ethereum) - * [Portafogli Ethereum](#portafogli-Ethereum) - * [Messaggi e Transazioni](#messaggi-e-Transazioni) - * [Ethereum come un Sistema di Transizione di Stato](#ethereum-come-un-sistema-di-transizione-di-stato) - * [Esecuzione del Codice](#esecuzione-del-codice) - * [Blockchain e Mining](#blockchain-e-mining) -* [Applicazioni](#applicazioni) - * [Sistemi di Token](#sistemi-di-token) - * [Derivati Finanziari](#derivati-finanziari) - * [Sistema di Identità e Reputazione](#sistemi-di-identità-e-reputazione) - * [Storage Decentralizzato dei File](#storage-decentralizzato-dei-file) - * [Organizzazioni Decentralizzate Autonome](#organizzazioni-decentralizzate-autonome) - * [Ulteriori Applicazioni](#ulteriori-applicazioni) -* [Miscellanea e Relazioni](#miscellanea-e-relazioni) - * [Implementazione GHOST Modificata](#implementazione-ghost-modificata) - * [Commissioni](#commissioni) - * [Calcolo e Completezza di Turing](#calcolo-e-completezza-di-turing) - * [Moneta ed Emissione](#moneta-ed-emissione) - * [Centralizzazione del Mining](#centralizzazione-del-mining) - * [Scalabilità](#scalabilità) -* [Conclusioni](#conclusioni) -* [Riferimenti ed Ulteriori Letture](#riferimenti-ed-ulteriori-letture) - -## Introduzione al Bitcoin ed ai Concetti Esistenti - -### Storia - -Da decenni sta circolando l'idea di una moneta digitale decentralizzata, così come delle applicazioni alternative come i registri di proprietà. I protocolli anonimi di moneta digitale degli anni '80 e degli anni '90, dipendenti soprattutto su una crittografia primitiva conosciuta come Chaumian blinding, furono rilasciati da una moneta con un alto tasso di privacy, tuttavia questi fallirono principalmente per non essere riusciti a guadagnare terreno, a causa della loro dipendenza da un intermediario centralizzato. Nel 1998, Wei Dai's [b-money](http://www.weidai.com/bmoney.txt) divenne il primo progetto ad introdurre l'idea di creare una moneta attraverso la soluzione di puzzle computazionali assieme al consenso decentralizzato, tuttavia il progetto non offriva sufficienti dettagli su come questo consenso decentralizzato potesse essere concretamente attualizzato. Nel 2005, Hal Finney introdusse il concetto del "[proofs of work riutilizzabile](http://www.finney.org/~hal/rpow/)", un sistema che utilizza le idee provenienti dalla b-moneta, insieme ai puzzle computazionali Hashcash di Adam Back, per creare un concetto di criptomoneta, ma, ancora una volta, non si riuscii ad ottenere il suddetto fine, perché anche quest'ultimo progetto si basava su un calcolo computazionale garantito come back-end. - -Poiché la moneta è un'applicazione first-to-file, dove l'ordine delle transazioni è spesso di cruciale importanza, le monete decentralizzate richiedono una soluzione al consenso decentralizzato. L'innovazione fornita da Satoshi è l'idea di riuscire a combinare un protocollo molto semplice basato su dei nodi su cui avvengono le transazioni, che danno vita ad una sempre crescente blockchain, attraverso la creazione di "blocchi" ogni 10 minuti, con il proof of work come meccanismo attraverso cui i nodi guadagnano il diritto di partecipare al sistema. Mentre i nodi con una grande quantità di potenza di calcolo hanno proporzionalmente maggiore influenza, raggiungere più potenza computazionale rispetto l'intero network è più difficile rispetto al simulare milioni di nodi. Nonostante la crudezza e la semplicità del modello blockchain del Bitcoin, esso ha dimostrato di essere sufficientemente valido, e nel corso dei successivi cinque anni sarebbe diventato il fondamento di oltre duecento monete e protocolli di tutto il mondo. - -### Bitcoin come un Sistema di Transizione di Stato - -![statetransition.png](http://vitalik.ca/files/statetransition.png?2) - -Il libro mastro del Bitcoin può essere pensato, da un punto di vista tecnico, come un sistema di transizione di stato, dove c'è uno "stato" consistente nella proprietà dello status di tutti i Bitcoins esistenti e "la funzione di transizione di stato", che riceve uno stato ed una transizione e trasmette un nuovo stato che ne costituisce il risultato. Nel sistema bancario tradizionale, per esempio, lo stato è il documento costituente il saldo, una transazione è una richiesta di movimentare $X da A a B, e la funzione di transizione di stato sottrae un valore nel conto corrente di A equivalente $X ed incrementa il valore di $X nel conto corrente bancario di B. Se nel conto corrente di A ci sono meno che $X, la funzione di transizione di stato segnala un errore. Quindi, si può formalmente definire: - - APPLY(S,TX) -> S' or ERROR - -Nel sistema bancario definito in precedenza: - - APPLY({ Alice: $50, Bob: $50 },"send $20 from Alice to Bob") = { Alice: $30, Bob: $70 } - -Ma: - - APPLY({ Alice: $50, Bob: $50 },"send $70 from Alice to Bob") = ERROR - -Lo "stato" nel Bitcoin è la raccolta di tutte le monete (tecnicamente, "transazioni in uscita non spese" oUTXO) che sono state effettuate ma non ancora spese, con ogni UTXO che ha una denomoninazione ed un proprietario (definito da un indirizzo da 20-byte che è essenzialmente una chiave crittografica pubblica[1]). Una transazione contiene uno o più inputs, con ogni input che contiene un riferimento ad un UTXO esistente ed una firma crittografica prodotta da una chiave privata associata all'indirizzo del proprietario, ed uno o più outputs, con ogni outpout contenente un nuovo UTXO che deve essere aggiunto allo stato. - -1. Per ogni input in `TX`: - * Se il riferimento UTXO non è in `S`, si ha un errore. - * Se la firma provvista non combacia con il proprietario del UTXO, si ha un errore. -2. Se la somma dei valori di tutti gli input UTXO è inferiore alla somma dei valori di tutti gli outpout UTXO, si ha un errore. -3. Si ha `S` con tutti gli input UTXO meno tutti gli outpout UTXO aggiunti. - -La prima parte del primo step previene che i mittenti delle transazioni possano spendere monete che non esistono, la seconda del primo step previene ai mittenti delle transazioni di spendere monete di altre persone, ed il secondo step fa rispettare la conservazione del valore. Al fine di utilizzare ciò per il pagamento, il protocollo è il seguente. Supponiamo che Alice voglia inviare 11.7 BTC a Bob. Per primo, Alice controllerà di possedere un set di UTXO, che ammonta ad almeno 11.7 BTC. Realisticamente, Alice non sarà in grado di ottenere esattamente 11.7 BTC; si può dire che il valore più piccolo che può ottenere è 6+4+2=12. Lei poi crea una transazione con quei tre inputs ed i due outputs. Il primo output sarà 11.7 BTC con l'indirizzo che appartiene a Bob, ed il secondo output sarà il rimanente 0.3 BTC "scambiato", essendo Alice stessa il proprietario. - -### Mining - -![block_picture.jpg](http://vitalik.ca/files/block_picture.png) - -Se abbiamo avuto accesso a un servizio centralizzato di fiducia, ciò potrebbe essere banale da implementare; esso potrebbe essere codificato esattamente come descritto. Tuttavia, con i Bitcoin noi abbiamo provato a costruire un sistema monetario, combinando il sistema di transizione di stato con un sistema di consenso al fine di assicurare che ognuno sia d'accordo sull'ordine delle transazioni. Il processo di consenso decentralizzato del Bitcoin richiede l'esistenza dei nodi nel network, che continuamente tentano di produrre pacchetti di transazioni chiamati "blocchi". Il network è destinato a produrre all'incirca un blocco ogni dieci minuti, con ogni blocco che contiene una marca temporale, un numero, un riferimento a (ad esempio l'hash del) precedente blocco e una lista di tutte le transazioni che sono avvenute dal precedente blocco. Con il passare del tempo, questo crea una persistente, sempre crescente, "blockchain" che si aggiorna costantemente per rappresentare l'ultimo stato del libro mastro del Bitcoin. - -L'algoritmo per controllare la validità di un blocco, espresso in questo paradigma, è il seguente: - -1. Controllo se il blocco precedente esiste ed è valido. -2. Controllo se la marca temporale del blocco è più grande del blocco precedente[2] ed è inferiore di 2 ore nel futuro. -3. Controllo se il proof of work sul blocco è valido. -4. Sia `S[0]` lo stato alla fine del blocco precedente. -5. Si supponga `TX` la lista della transazione del blocco con `n` transazioni. Per tutti `i` in `0...n-1`, sia impostato `S[i+1] = APPLY(S[i],TX[i])` Se da qualsiasi applicazione risulti un errore, esce e ritorna falso. -6. Ritorna vero, e registra `S[n]` come uno stato alla fine del blocco. - -In definitiva, ogni transazione del blocco deve fornire una transazione di stato che sia valida. Si noti che ogni stato non è codificato, in nessun modo, nel blocco; esso è puramente una astrazione da ricordare per la validazione del nodo e può solo essere (in modo sicuro) computata, per qualsiasi nodo, iniziando dallo stato di genesi e applicata sequenzialmente ad ogni transazione in ogni nodo. Si noti che è importante l'ordine nel quale ogni miner include le transazioni nel blocco; se ci sono due transazioni A e B nel blocco tale che B impiega una UTXO creata da A, poi il blocco sarà validato se A viene prima di B ma non viceversa. - -La parte interessante dell'algoritmo di validazione del blocco è il concetto di "proof of work": la premessa è che l'hash SHA256 di ogni blocco, costituito come un numero di 256-bit, deve essere inferiore di un target regolato dinamicamente, che è al tempo di questo scritto approssimativamente 2192. Lo scopo di ciò è di rendere computazionalmente "difficile" la creazione di un blocco, prevenendo con ciò agli attacchi sibilla dal ricreare l'intera blockchain a loro favore. Poichè SHA256 è progettato per essere una funzione completamente imprevedibile e pseudo-randomica, l'unico modo di creare un blocco valido è semplicemente un test, con l'incremento ripetuto del numero controllando se il nuovo hash corrisponde. Al target corrente di 2192, questo significa un media di 264 tentativi; in generale, il target è ricalibrato dal network ogni 2016 blocchi in modo che, in media, un nuovo blocco è prodotto, ogni dieci minuti, da qualche nodo nel network. Nella prospettiva di compensare i miners per questo lavoro computazionale, ogni dieci minuti il miner è autorizzato ad includere una transazione donando a se stesso 25 BTC da nulla. In aggiunta, se qualche transazione ha un valore totale denominale più alto nei suoi inputs che ne suoi outputs, la differenza va al miner come "commissione di transazione". Incidentalmente, questo è pure l'unico meccanismo attraverso cui avviene l'emissione dei BTC; in assoluto lo stato di genesi non contiene alcuna moneta. - -Nella prospettiva di una migliore comprensione dello scopo del mining, esaminiamo il caso in cui avvenga un attacco criminoso. Visto che la crittografia implicita nel Bitcoin è nota per essere sicura, l'attaccante colpirà l'unica parte del sistema del Bitcoin che non è protetta direttamente dalla crittografia: l'ordine delle transazioni. La strategia dell'attaccante è semplice: - -1. Invio 100 BTC ad un commerciante in cambio di qualche prodotto (preferibilmente un bene digitale consegnabile rapidamente) -2. Attesa per la consegna del prodotto -3. Produzione di un'altra transazione che invia 100 BTC a se stesso -4. Tentativo di convincere il network che la sua transazione a se stesso era quella che è avvenuta per prima. - -Una volta avvenuto lo step (1), dopo qualche minuto qualche miner includerà la transazione nel blocco, ad esempio il blocco numero 270000. Dopo circa un'ora, cinque o più blocchi saranno aggiunti alla chain dopo quel blocco, con ognuno di questi blocchi che indirettamente indicano la transazione e quindi la "confermano". A questo punto, il commerciante accetterà il pagamento come finalizzato e consegnerà il prodotto; considerato che stiamo assumendo che questo sia un bene digitale, consegnato in un istante. Adesso, l'attaccante crea un'altra transazione inviando i 100 BTC a se stesso. Se l'attaccante semplicemente la rilascia, questa non sarà processato; i miners proveranno ad eseguire `APPLY(S,TX)` e prendere nota che `TX` consuma un UTXO che non è più nello stato. Invece, in questo modo, l'attaccante crea una "fork" della blockchain, iniziando a minare un'altra versione del blocco 270000 indirizzando il blocco 269999 come una antecedente ma con una nuova transazione che prende il posto di quella vecchia. Poiché i dati del blocco sono differenti, ciò richiede il rifacimento della "proof-of-work". Inoltre, la nuova versione del blocco 270000 dell'attaccante ha un hash differente, così i blocchi originali da 270001 a 270005 non "conducono" a quello; quindi, la chain originale e quella nuova dell'attaccante saranno completamente separate. La regola è che, nel caso di fork, la blockchain più lunga è considerata essere quella vera e così i legittimi minatori lavoreranno sulla chain del 270005, mentre l'attaccante sta lavorando da solo sulla chain del 270000. Affinché l'attaccante crei la blockchain più lunga, egli dovrebbe avere più potenza computazionale che il resto del network per ottenere (da quel momento, "51% attacco"). - -### Merkle Trees - -![SPV in bitcoin](https://raw.githubusercontent.com/ethereum/www/master-postsale/src/extras/gh_wiki/spv_bitcoin.png) - -_Sinistra: è sufficiente mostrare solo un esiguo numero di nodi in un Merkle tree per avere la prova della validità di un ramo._ - -_Destra: qualunque tentativo di modificare qualsiasi parte del Merkle tree porterà ad un'incongruenza da qualche parte a monte della chain._ - -Un'importante funzione della scalabilità del Bitcoin è che nel blocco è memorizzata una struttura di dati multi-livello. L' "hash" di un blocco è in realtà solo l'hash dell'intestazione del blocco, approssimativamente 200-byte di dati che contengono la marca temporale, un numero, hash del precedente blocco e l'hash principale della struttura dei dati chiamata Merkle tree che contiene tutte le transazioni del blocco. Un Merkle tree è un tipo di struttura binaria, composto da un set di nodi, con un grande numero di nodi dipendenti alla base della struttura, che contengono dati sottostanti, un insieme di nodi intermedi dove ogni nodo è l'hash dei suoi due figli, e alla fine un nodo singolo principale, anch'esso composto dall'hash dei suoi due "figli", che rappresenta l'apice della struttura. La finalità del Merkle tree è quello di consentire che i dati in un blocco siano consegnati in maniera frammentaria: un nodo può scaricare solo l'intestazione di un blocco da una sorgente, la piccola parte della struttura di loro interesse da un'altra sorgente, per assicurarsi che tutti i dati siano correnti. Il motivo per cui questo funziona è che gli hash si propagano verso l'alto: se un utente malevolo tenta di cambiare una transazione falsa verso il punto più basso del Merkle tree, ciò causerà un cambio sul nodo di sopra, e poi un cambio sul nodo sopra quest'ultimo, per cambiare, infine, la struttura principale e pertanto l' hash del blocco, causando che il protocollo registri questo come un blocco completamente differente (quasi certamente con un proof of work invalido). - -Il protocollo Merkle tree è, senza dubbio, essenziale per la sostenibilità a lungo termine. Un "nodo completo" nel Bitcoin network, uno che memorizza ed elabora l'interezza di ogni blocco, richiede all'incirca 15 GB di spazio sul disco nel Bitcoin network alla data di Aprile 2014, e sta crescendo di oltre un gigabyte al mese. Allo stato attuale, ciò è sostenibile per un computer desktop e non per i telefoni, e più in là con il tempo potranno partecipare solo le aziende e gli appassionati. Un protocollo conosciuto come "controllo semplificato del pagamento" (CSP) permette ad un'altra classe di nodi di esistere, chiamati "nodi leggeri", che scaricano le intestazioni del blocco, verificando la proof of work sulle intestazioni del blocco, e successivamente scaricano solo i "rami" associati con le transazioni che sono per loro rilevanti. Questo permette ai nodi leggeri di determinare con una forte garanzia di sicurezza quale sia lo status di una qualsiasi transazione Bicoin, ed il loro corrente bilancio, con soltanto il download di una piccolissima parte dell'intera. - -### Applicazioni Alternative della Blockchain - -L'idea di prendere spunto dalla tecnologia sottostate alla blockchain e di applicarla anche ad altri concetti ha una storia. Nel 2005, Nick Szabo propose il concetto di "[titoli di proprietà sicuri con l'autorizzazione del proprietario](http://szabo.best.vwh.net/securetitle.html)", un documento che descriveva come "nuovi progressi nella tecnologia di un database replicato" consentiranno ad un sistema basato sulla blockchain di conservare un registro di chi possegga una determinata terra, creando un quadro elaborato che include concetti come quello di autosufficienza economica, usucapione e le tasse sulla terra Georgiana. Tuttavia, sfortunatamente, non era disponibile all'epoca un sistema efficace di database replicato, ed il protocollo non fu mai implementato concretamente. Ciononostante, dal 2009 cominciò rapidamente ad emergere, dopo lo sviluppo del consenso decentralizzato del Bitcoin, un numero di applicazioni alternative. - -* **Namecoin** - creato nel 2010, [Namecoin](https://namecoin.org/) conosciuto come un sistema decentralizzato di database per la registrazione di nomi di dominio. Nei protocolli decentralizzati come Tor, Bitcoin e BitMessage, è necessario un modo di identificare gli account in modo che le persone possano interagire tra loro, ma in tutte le soluzioni esistenti l'unico tipo di identificatore disponibile è un hash pseudo casuale come `1LW79wp5ZBqaHW1jL5TCiBCrhQYtHagUWy`. Idealmente, qualcuno potrebbe avere un account con un nome come "george". Tuttavia, il problema è che se una persona può creare un account chiamato "george" poi qualcun altro potrà utilizzare lo stesso processo per registrare "george" per se stesso così come per impersonificare quell'altra persona. L'unica soluzione è il paradigma first-to-file, dove il primo registrante ha successo ed il secondo fallisce - un problema che si adatta perfettamente al protocollo di consenso del Bitcoin. Namecoin è la più vecchia, e di più successo, implementazione di un sistema di registrazione di dominio che utilizza una tale idea. -* **Monete colorate** - lo scopo delle [monete colorate](https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit) è quello di servire come un protocollo per consentire alle persone di creare le proprie valute digitali - o tokens digitali sulla Blockchain del Bitcoin, nel caso frequente e rilevante di una moneta con una sola unità. Nel protocollo delle monete colorate, una persona "emette" una nuova moneta assegnando pubblicamente un colore ad una UTXO specifica del Bitcoin, e il protocollo definisce ricorsivamente il colore dell'altra UTXO al fine che sia dello stesso colore degli inputs di quella transazione da cui deriva (qualche regola speciale si applica nel caso di inputs di colori di monete misti). Ciò permette agli utenti di conservare portafogli di monete che contengono solo una UTXO di uno specifico colore e di inviare questa in modo del tutto simile ai Bitcoins, attraverso lo studio della blockchain per determinare il colore di un qualsiasi UTXO che gli stessi hanno ricevuto. -* **Metacoins** - l'idea dietro un metacoin è quello di avere un protocollo che vive al vertice del Bitcoin, usando le transazioni Bitcoin per conservare le transazioni metacoin, ma avendo una differente funzione di transazione, `APPLY'`. Poiché il protocollo Metacoin non può prevenire che una transazione metacoin invalida sia visualizzata sulla blockchain del Bitcoin, si aggiunge una regola che se `APPLY'(S,TX)`ritorna come un errore, le impostazioni predefinite del protocollo sono`APPLY'(S,TX) = S`. Ciò fornisce un semplice meccanismo per la creazione di un protocollo arbitrario di criptomoneta con funzioni potenzialmente avanzate, che non possono essere implementate all'interno del Bitcoin stesso, ma con un costo di sviluppo molto basso visto che la complessità del mining e del networking sono già gestiti dal protocollo Bitcoin. - -Così, in generale, esistono due approcci per la costruzione di un protocollo di consenso: costruire un network indipendente, e costruire un protocollo sul modello di quello del Bitcoin. Il primo approccio è difficile da implementare, anche se ha avuto un buon successo in applicazioni come Namecoin; ogni implementazione individuale necessità una nuova ed indipendente blockchain, così come la costruzione ed il testing di tutta la transizione di stato ed il codice del network. Per di più, si ipotizza che il set di applicazioni per una tecnologia di consenso decentralizzato seguirà la "power law distribution" dove la maggior parte delle applicazioni sarebbe troppo piccola da garantire la loro propria blockchain, e si noti che esistono grandi classi di applicazioni decentralizzate, in particolare le organizzazioni autonome decentralizzate, che necessitano di interagire tra loro. - -D'altro canto, l'approccio basato sul Bitcoin, ha il difetto di non avere la funzione di verificazione semplificata del Bitcoin. SPV funziona per il Bitcoin perché può impiegare la grandezza della Blockchain come un proxy per la validità; ad un certo punto, una volta che le transazioni precedenti ad un'altra saranno sufficientemente validate, si potrà confermare la legittimità a far par dello stato. I meta-protocolli basati sulla Blockchain, d'altro canto, non possono forzare quest'ultima a non includere le transazioni che non sono valide all'interno del contesto del loro stesso protocollo. Da ciò, un'implementazione di un meta-protocollo SPV altamente sicuro necessiterebbe di analizzare tutte le transazioni fino all'inizio della Blockchain del Bitcoin per determinare quali siano le transazioni valide e quali quelle invalide. Allo stato attuale, tutta la "luce" di implementazioni di meta-protocolli basati sul Bitcoin si basano su un server di fiducia per fornire i dati; probabilmente questo è uno dei migliori risultati possibili soprattutto quando uno degli scopi principali di una Criptovaluta è quello di eliminare la necessità di fiducia. - -### Scripting - -Attualmente il protocollo del Bitcoin, perfino senza nessuna estensione, facilita una debole versione del concetto di "smart contracts". UTXO in Bitcoin può essere posseduta non solo come chiave pubblica, ma anche da uno script più complesso espresso in un semplice linguaggio di programmazione stack-based. In questo paradigma, una spesa di transazione che UTXO deve fornire un dato che soddisfa lo script. Infatti, il meccanismo basico della proprietà della chiave pubblica è implementato con uno script: lo script impiega una firma a curva ellittica come input, confrontando questa con la transazione e l'indirizzo che possiede la UTXO, e ritorna 1 se la verificazione è andata a buon fine altrimenti 0 in caso contrario. Altri scripts più complessi esistono per i più svariati casi. Per esempio, si può costruire uno script che richiede firme da due delle tre chiavi private impiegate per validare ("multisig"), un setup utile per conti delle società, che mettono al sicuro i conti correnti e che forniscono ai commercianti funzioni di escrow. Gli scripts possono anche essere usati per pagare premi per la soluzione di problemi computazionali, e si può perfino costruire uno script che affermi qualcosa come "questo Bitcoin UTXO è tuo se sei in grado di dare prova di un SPV che tu mi invii una transazione di Dogecoin di questo valore", consentendo essenzialmente un cambio tra cripto-monete. - -Tuttavia, il linguaggio di scripting, così come implementato nel Bitcoin, presenta alcune importanti limitazioni: - -* **Manca di completezza del linguaggio di Turing**- vale a dire, mentre esiste un grande sottoinsieme di calcolo che il linguaggio di scripting del Bitcoin supporta, quest'ultimo non supporta quasi tutto. La categoria principale che viene meno è il loop. Questo è reso possibile per evitare cicli infiniti durante la verifica delle transazioni; teoricamente ciò è un ostacolo sormontabile per il programmatori di script, visto che qualsiasi loop può essere simulato semplicemente ripetendo il codice sottostante tante volte con un'istruzione "if", implicando scripts inefficienti dal punto di vista dello storage. Per esempio, l'implementazione di un algoritmo alternativo di firma a curva ellittica necessiterebbe 256 rounds di moltiplicazioni ripetute e tutte incluse individualmente nel codice. -* **Cecità-del-valore** - non c'è un modo per un UTXO di fornire un controllo a setaccio sull'ammontare ritirabile. Per esempio, un buon caso di studio può consistere in un contratto oracolo con un contratto sottostante, dove A e B mettere in valore di $ 1000 di BTC e dopo 30 giorni lo script invia il controvalore di $1000 in BTC ad A ed il resto a B. Ciò necessiterebbe di un oracolo per determinare il valore di 1 BTC in USD, ma anche in questo caso c'è un incremento esponenziale, sia in termini di fiducia che di infrastruttura necessaria, per soluzioni, attualmente disponibili, completamente centralizzate. Tuttavia, poiché UTXO sono tutte-o-nessuna, l'unico modo per raggiungere questo risultato è attraverso l'inefficiente hack di avere molte UTXO di varie denominazioni (es. una UTXO di 2k per ogni k fino a 30) e avendo O scelta dove UTXO spedisce ad A e quindi a B. -* **Mancanza di stato** - UTXO può essere sia speso che non speso; non c'è possiblità per contratti o scripts multi-stage che mantengono qualche altro stato interno oltre questo. Ciò rende difficile creare contratti di opzioni multi-stage, cambi decentralizzati, che offrono protocolli crittografici, a due fasi, dedicati (necessari per premi computazionali sicuri). Questo inoltre significa che UTXO può essere soltanto usata per costruire, contratti unici e un non più complessi contratti "stateful" come le organizzazioni decentralizzate, e creare meta-protocolli difficili da implementare. Lo stato binario, combinato con la cecità-del-valore, significa anche che un'altra importante applicazione, come i limiti al prelievo, risulti impossibile. -* **Cecità-della-Blockchain** - UTXO è cieca alla blockchain come il nonce dell'hash precedente. Questo pregiudica applicazioni nel gioco d'azzardo, e altre molte categorie, privando il linguaggio di scripting di una fonte potenzialmente preziosa di casualità. - -Quindi, esistono tre approcci per costruire applicazioni avanzate sull'apice della criptomoneta: costruire una nuova Blockchain, usando scripting sull'apice del Bitcoin, e costruire un meta-protocollo sull'apice del Bitcoin. Costruire una nuova Blockchain permette una illimitata libertà nel costruire un set di funzionalità, comportando del tempo per lo sviluppo e delle criticità relative alla fase iniziale e a quella di messa in sicurezza del sistema. Usare lo scripting è semplice da implementare e standardizzare, ma implica delle limitazioni nelle sue capacità; al contrario i meta-protocolli, ma soffrono di difetti di scalabilità. Con Ethereum, noi intendiamo costruire un framework alternativo, che fornisce benefici ancora maggiori in termini di semplicità di sviluppo e ancora più forti proprietà di leggerezza per i client, permettendo allo stesso tempo alle applicazioni di condividere un ambiente economico e la sicurezza della Blockchain. - -## Ethereum - -Lo scopo di Ethereum è quello di creare un protocollo alternativo per la costruzione di applicazioni decentralizzate, fornendo un insieme eterogeneo di possibilità che, dal nostro punto di vista, saranno molto utili per una larga classe di applicazioni decentralizzate, in particolar modo nelle situazioni dove sono essenziali: un tempo rapido di sviluppo, la sicurezza per applicazioni utilizzate di rado, e la capacità di far interagire tra loro, in modo molto efficace, applicazioni differenti. Ethereum permette tutto ciò attraverso la costruzione di quello che in sostanza è il definitivo protocollo astratto e fondante: una Blockchain con un linguaggio di programmazione, costruito al suo interno e Turing-complete, che permette ad ognuno di scrivere -Smart Contracts ed applicazioni decentralizzate dove stabilire le proprie regole arbitrarie per la proprietà, i formati delle transazioni e le funzioni di transizione di stato. Una scarna versione di Namecoin può essere scritta in due linee di codice, e gli altri protocolli, come le criptomonete e i sistemi di reputazione, possono essere costruiti al di sotto delle venti linee. Gli smart contracts, i "boxes" crittografici che contengono valore, possono essere sbloccati solo se si verificano certe condizioni, inoltre possono essere anche costruiti sull'apice di della piattaforma, con degli strumenti molto più efficaci di quelli offerti dallo scripting del Bitcoin, grazie agli strumenti offerti dalla completezza del linguaggio di Turing, consapevolezza del valore, dello stato e della blockchain. - -### Ethereum Accounts - -In Ethereum, lo stato è costituito da oggetti chiamati "accounts", in cui ogni account ha un indirizzo di 20-byte e le transizioni di stato sono trasferimenti diretti del valore e dell'informazione tra gli accounts. Un account Ethereum account contiene quattro campi: - -* Il **nonce**, un contatore utilizzato per assicurarsi che ogni transazione può essere elaborata una sola volta -* Il conto corrente dell'account **bilancio ether** -* Il **contract code** dell'account, se presente -* Lo **storage** dell'account (vuoto da default) - -"Ether" è l'interno e principale crypto-carburante di Ethereum, e viene usato per pagare le commissioni di transazione. In generale, esistono due tipi di account: **accounts posseduti dall'esterno**, controllati da chiavi private, e **gli accounts contratto**, controllati dal loro codice di contratto. Un account posseduto dall'esterno non ha codice, e si possono mandare messaggi esterni dall'account posseduto esternamente creando e firmando una transazione; in un account contratto, ogni volta che questo riceve un messaggio, il suo codice si attiva, permettendo a questo di leggere e scrivere verso uno storage interno e spedire altri messaggi o creare contratti a sua volta. - -Si noti che i "contratti" in Ethereum non dovrebbero essere visti come qualcosa da "riempire" o "da complilare con"; piuttosto, essi sono più come "agenti autonomi", che vivono all'interno dell'ambiente di esecuzione di Ethereum, eseguendo sempre una porzione specifica di codice che viene "colpita" da un messaggio o da una transazione, e avendo il controllo diretto sul proprio conto di ether e sulla propria chiave/valore di store, al fine di tenere traccia delle variabili persistenti. - -### Messaggi e Transazioni - -Il termine "transazione" è utilizzato in Ethereum per riferirsi al pacchetto di dati firmati, che contengono un messaggio da inviare da un account posseduto dall'esterno. Le Transazioni contengono: - -* Il destinatario del messaggio -* Una firma che identifica il mittente -* L'ammontare di ether da trasferire al destinatario -* Un campo dati opzionale -* Un valore`STARTGAS`, che rappresenta il massimo numero di steps computazionali che l'esecuzione della transazione può impiegare -* Un valore`GASPRICE`, che rappresenta la commissione che il mittente paga per lo step computazionale - -i primi tre sono campi standard previsti in qualsiasi criptovaluta. Il campo dati non ha nessuna funzione da default, ma la virtual machine ha un codice operativo con cui un contratto può accedere ai dati; come caso di esempio, se un contratto sta funzionando come un servizio di registrazione di dominio basato sulla blockchain, allora può desiderare di interpretare i dati che vengono passati ad esso come contenenti due "campi ", il primo campo essendo un dominio da registrare ed il secondo essendo l'indirizzo IP da registrare. Il contratto dovrebbe leggere questi valori dai dati del messaggi e collocarli appropriatamente nello storage. - -I campi `STARTGAS` e`GASPRICE` sono cruciali per il modello di servizio anti-denial di Ethereum. Al fine di prevenire loops infiniti, accidentali o ostili, o altro spreco computazionale di codice, ad ogni transazione è richiesto di impostare un limite per l'uso di steps computazionali di codice di esecuzione. L'unità fondamentale di computazione è il "gas"; di solito, uno step computazionale costa 1 gas, ma alcune operazioni richiedono più unità di gas, perché esse sono computazionalmente più complesse, o richiedono un numero più elevato di dati che devono essere conservati come una parte dello stato. C'è anche una commissione di gas per ogni byte nei dati della transazione. L'obiettivo del sistema di commissione è quello di richiedere ad un aggressore di pagare proporzionalmente per ogni risorsa che essi consumano, includendo la computazione, larghezza di banda, e storage; quindi, qualsiasi transazione che comporta che il network consumi una quantità più grande di qualsiasi di queste risorse deve avere una commissione gas grosso modo proporzionale alla grandezza dell'incremento. - -### Messaggi - -I contratti hanno l'abilità di inviare "messaggi" ad altri contratti. I messaggi sono oggetti virtuali che non vengono mai serializzati ed esistono solo nell'ambiente di esecuzione di Ethereum. Un messaggio contiene: - -* Il mittente del messaggio (implicito) -* Il destinatario del messaggio -* L'ammontare di ether da inviare attraverso il messaggio -* Un campo dati opzionale -* Un valore `STARTGAS` - -Essenzialmente, un messaggio è come una transazione, eccetto che esso viene prodotto da un contratto e non da un attore esterno. Un messaggio è prodotto quando un contratto che sta eseguendo il codice fa effettua una operazione `CALL`, che produce ed esegue un messaggio. Come una transazione, un messaggio comporta che l'account del destinatario esegua il proprio codice. Quindi, i contratti possono avere relazioni con altri contratti esattamente alla stesso modo che avviene con degli attori esterni. - -Si noti che la quantità di gas, che serve ad una transazione o ad un contratto, si applica alla totalità del gas consumato da quella transazione e da tutte le sub-esecuzioni. Per esempio, se un attore esterno A trasmette una transazione a B con 1000 gas, e B consuma 600 gas prima di inviare il messaggio a C, e l'esecuzione interna di C consuma 300 gas prima di ritornare, poi B può spendere altri 100 gas prima di rimanere a corto di gas. - -### La Funzione di Transizione di Stato di Ethereum - -![ethertransition.png](http://vitalik.ca/files/ethertransition.png?1) - -La funzione di transizione di stato di Ethereum, `APPLY(S,TX) -> S'` può essere definita come segue: - -1. Controlla se la transazione è ben impostata (ie. ha il giusto numero di valori), la firma è valida, e il nonce corrispode a quello dell'account del mittente. In caso contrario, si ha un errore. -2. Calcola la commissione di transazione come `STARTGAS * GASPRICE`, e determina l'indirizzo del mittente dalla firma. Sottrae la commissione dal bilancio dell'account del mittente e incrementa il nonce del mittente. Se non c'è un bilancio sufficiente da spendere, si ha un errore. -3. Inizializza `GAS = STARTGAS`, e toglie una certa quantità di gas per byte per pagare i byte nella transazione. -4. Trasferisce il valore della transazione dall'account del mittente all'account del destinatario. Se l'account del destinatario non esiste ancora, lo crea. Se l'account del ricevente è un contratto, esegue il codice del contratto sia per il completamento o fino a quando l'esecuzione finisce il gas. -5. Se il valore di trasferimento fallisce perché il mittente non ha abbastanza soldi, il code di esecuzione finisce il gas, ripristina tutti i cambiamenti di stato, tranne il pagamento delle commissione , e aggiunge le commissioni sul conto del minatore . -6. Altrimenti, risarcisce al mittente le commissioni per il gas rimanente, ed invia le commissioni pagate per il gas e consumate al miner. - -Per esempio, si supponga che il codice del contratto è: - - se !self.storage[calldataload(0)]: - self.storage[calldataload(0)] = calldataload(32) - -Si noti che in realtà il codice del contratto è scritto in un codice EVM di basso livello; questo esempio è scritto in Serpent, che, per essere chiari, è uno dei nostri linguaggi di alto livello, può essere compilato fino al codice EVM. Si supponga che lo storage del contratto sia inizialmente vuoto, e la transazione è inviata con un valore di 10 ether, 2000 gas, al prezzo di 0.001 ether gas, e 64 bytes di dati, con bytes 0-31 che rappresentano il numero `2` e i bytes 32-63 che rappresentano la stringa `CHARLIE`. Il processo per la funzione di transizione di stato è in questo caso come segue: - -1. Controlla che la transizione è valida è ben impostata. -2. Controlla che il mittente abbia almeno 2000 * 0.001 = 2 ether. If it is, quindi sottrae 2 ether dall'account del mittente. -3. Inizializza gas = 2000; assumendo che la transazione è lunga 170 bytes e la commissione di byte è 5, sottrae 850 così che c'è 1150 gas che rimane. -3. Sottrae altri 10 ether dall'account del mittente, e li aggiunge all'account del contratto. -4. Esegue il codice. In questo caso, questo è semplice: esso controlla che lo storage del contratto all'indice `2` sia usato, prende nota che non lo è, e così imposta lo storage all' index `2` al valore `CHARLIE`. Si supponga che questo impieghi 187 gas, così l'ammontare rimante di gasi sia 1150 - 187 = 963 -5. Aggiunge 963 * 0.001 = 0.963 di nuovo sul conto del mittente, e ritorna lo stato risultante. - -Se non ci fosse alcun contratto alla fine di ricezione della transazione, quindi il totale della commissione di transazione sarebbe semplicemente uguale al `GASPRICE` provvisto moltiplicato per la lunghezza della transazione in bytes, ed i dati inviati per mezzo della transazione sarebbero irrilevanti. - -Si noti che i messaggi lavorano in maniera equivalente alle transazioni in termini di ripristino: se un messaggio in esecuzione finisce il gas, quindi l'esecuzione del messaggio, e tutte le altre esecuzioni innescate da questa esecuzione, tornano indietro, ma le esecuzioni precedenti non hanno bisogno di farlo. Questo significa che è "sicuro" per un contratto di richiamare un altro contratto, se A chiama B con G di gas poi l'esecuzione di A è garantita per perdere al massimo G. Alla fine, si noti che c'è un codice operativo, `CREATE`, che crea un contratto; il proprio meccanismo di esecuzione è generalmente simile a `CALL`, con l'eccezione che questo output di esecuzione determina il codice di un contratto recentemente creato. - -### Esecuzione del Codice - -Il codice nel contratti Ethereum è scritto in un linguaggio di basso livello, linguaggio bytecode a cascata, denominato "codice virtual machine Ethereum" o"codice EVM". Il codice consiste in una serie di bytes, dove ogni byte rappresenta un'operazione. In generale, l'esecuzione del codice è un loop infinito che consiste nel realizzare ripetutamente l'operazione al contatore del programma attuale (che inizia con zero) e incrementando il contatore del programma di uno, fino a che si ottiene la fine del codice od un errore o `STOP` o è rilevato l'istruzione `RETURN`. Le operazioni hanno accesso a tre tipi di spazio nel quale registrare i dati: - -* Lo **stack**, un last-in-first-out contenitore nel quale i valori possono essere spinti e spuntati -* **Memoria**, un array di byte espandibile all'infinito -* Il lungo-termine del contratto **storage**, una chiave/valore di store. A differenza dello stack e della memoria, che si resettano dopo la fine del calcolo, lo storage persiste per un lungo periodo. - -Il codice può anche accedere al valore, mittente e dati del messaggio in arrivo, così come ai dati in testata al blocco, e il codice può anche ritornare come un'array di dati come output. - -Il modello di esecuzione formale del codice EVM è sorprendentemente semplice. Mentre la virtual machine di Ethereum funziona, tutto il suo stato computazionale può essere definito dall'insieme di dati `(stato_del_blocco, transazione, messaggio, codice, memoria, stack, pc, gas)`, dove `stato-del_blocco` è lo stato globale che contiene tutti gli accounts e include i bilanci e lo storage. All'inizio di ogni turno di esecuzione, l'istruzione corrente viene trovata prendendo il `pc`th byte del `codice` (o 0 se `pc >= len(codice)`), e ogni istruzione ha la sua propria definizione in termini di come interagisce con l'insieme di dati. Per esempio, `ADD` espelle due oggetti fuori dallo stack e spinge la loro somma, riduce `gas` di 1 e incrementa `pc` by 1, e `SSTORE` espelle i due oggetti all'apice fuori dallo stack ed inserisce il secondo oggetto nello storage del contratto all'indice specificato dal primo oggetto. Sebbene ci sono molti modi di ottimizzare l'esecuzione della virtual machine di Ethereum attraverso una pronta compilazione, un'implementazione basica di Ethereum can in poche centinaia di righe di codice. - -### Blockchain e Mining - -![apply_block_diagram.png](http://vitalik.ca/files/apply_block_diagram.png) - -La blockchain di Ethereum è in molti modi simile a quella del Bitcoin, seppur con qualche differenza. La differenza princiale tra Ethereum e Bitcoin con riguardo all'architettura della blockchain, è che, contrariamente al Bitcoin, i blocchi di Ethereum contengono una copia sia dell'elenco delle transazioni sia lo stato più recente. A parte questo, gli altri due valori, il numero di blocco e la difficoltà, vengono memorizzati nel blocco. L'algoritmo di validazione del blocco alla base in Ethereum funziona in questo modo: - -1. Controlla se il se il precedente blocco di riferimento esiste ed è valido. -2. Controlla se la marca temporale del blocco è più grande di quella del blocco di riferimento precedente ed inferiore di 15 minuti nel futuro. -3. Controlla che il numero del blocco, difficoltà, l'origine della transazione, la transazione derivata ed il limite del gas ( vari e specifici concetti di basso-livello di Ethereum) sono validi. -4. Controlla se il proof of work sul blocco sia valido. -5. Sia `S[0]` lo stato alla fine del blocco precedente. -6. Sia`TX` la lista delle transazioni del blocco, con `n` transazioni. Per tutti in `0...n-1`, set `S[i+1] = APPLY(S[i],TX[i])`. Se qualsiasi applicazioni dà errore, o se il gas totale è consumato nel blocco fino a che questo punto eccede il `GASLIMIT`, anche questo, dà errore. -7. Sia `S_FINAL` `S[n]`, ma aggiungendo la ricompensa per il blocco pagata al miner. -8. Controlla che lo stato originario del Merkle tree `S_FINAL` sia uguale allo stato finale originario fornito nell'intestazione del blocco. In tal caso, il blocco è valido; in caso contrario, quest'ultimo non è valido. - -L'approccio può sembrare molto inefficiente a prima vista, perché questo necessita di registrare l'intero stato di ogni blocco, ma in realtà l'efficienza dovrebbe essere comparabile a quella del Bitcoin. La ragione sta nel fatto che lo stato è registrato in una struttura ad albero, e dopo ogni blocco una piccola parte dell'albero necessita di essere cambiata. Quindi, in generale, tra due blocchi adiacenti la grande maggioranza dell'albero dovrebbe essere la stessa, e quindi i dati possono essere registrati una sola volta e consultati due volte usando i puntatori (ad es. gli hash degli alberi inferiori). Un tipo speciale di albero conosciuto come "Patricia tree" viene usato per raggiungere questo risultato, includendo una modifica del concetto del Merkle tree, che permette ai nodi di essere inseriti e cancellati, e non solo cambiati, in maniera efficiente. Per di più, poiché tutta l'informazione sullo stato è una parte dell'ultimo blocco, non c'è bisogno di registrare tutta la storia della blockchain - una strategia che, se applicata al Bitcoin, può consentire un risparmio di spazio di 5-20x. - -Un quesito comune che viene posto è "dove" il codice del contratto viene eseguito, in termini di hardware fisico. Questa è una risposta semplice: il processo di esecuzione del codice del contratto è una parte della definizione dello funzione di transizione di stato, che è una parte dell'algoritmo di validazione del blocco, così che se una transazione è aggiunta al blocco `B` l'esecuzione del codice generata da questa transazione sarà eseguita da tutti i nodi, nel presente e nel futuro, scaricando e validando il blocco `B`. - -## Applicazioni - -In generale, ci sono tre tipi di applicazioni costruite su Ethereum. La prima categoria sono le applicazioni finanziarie, che forniscono agli utenti molteplici e più potenti modi di gestire ed usufruire i contratti attraverso l'uso dei proprio soldi. Questo include le sub-monete, i derivati finanziari, ci contratti di hedging, i libretti di risparmio, i testamenti, e per ultimo perfino qualche genere di contratto collettivo di lavoro. -La seconda categoria consiste nelle applicazioni quasi finanziarie, dove è coinvolto il denaro, ma c'è anche un lato non monetario importante per quello viene fatto; un esempio perfetto è l'auto-assegnazione di premi per le soluzioni di problemi computazionali. Infine, ci sono applicazioni come il voto online e il governo decentralizzato che non sono assolutamente finanziarie. - -### Sistema dei Tokens - -Il sistema dei tokens basato sulla blockchain ha molte applicazioni che vanno dalle sub-monete che rappresentano assets come USD o gold di azioni di società, tokens individuali che rappresentano smart property, che assicurano coupons non falsificabili, e perfino sistemi di token senza nessun legame con un valore convenzionale, utilizzati come sistemi di punti di incentivazione. I sistemi di Token sono sorprendentemente semplici da implementare in Ethereum. Il punto chiave è che tutte queste monete, o sistema di token, sono fondamentalmente un database che funzione con una operazione: sottrae X unità da A e conferisce X unità a B, con la condizione che (i) X aveva almeno X unità prima che la transazione e la (2) tansazione sia approvata da A. Tutto quello che serve per implementare un sistema di tokens consiste nell'implementare questa logica in un contratto . - -Il codice basico per implementare un sistema di token attraverso Serpent è come segue: - - def send(to, value): - if self.storage[msg.sender] >= value: - self.storage[msg.sender] = self.storage[msg.sender] - value - self.storage[to] = self.storage[to] + value - -Questa è sostanzialmente un'implementazione letterale della funzione di stato del "sistema bancario" descritta in precedenza in questo documento. Poche altre linee di codice devono essere aggiunte per fornire lo step iniziale per la distribuzione delle unità di moneta nel primo luogo ed in altri casi limite, ed idealmente una funzione sarebbe aggiunta per lasciare agli altri contratti di domandare il saldo di un indirizzo. Ma questo è tutto ciò di cui c'è bisogno. Teoricamente, i sistemi di token basati su Ethereum, che fungono da sub-monete, possono potenzialmente includere un'altra importante caratteristica basata sulla mancanza di meta-monete sulla chain del Bitcoin: l'abilità di pagare le commissioni di transazione direttamente in quella moneta. Il modo in cui questo potrebbe essere implementato consiste che quel contratto manterrebbe un saldo di ether con cui risarcire gli ether usati per pagare le commissioni al mittente, e ricaricherebbe questo saldo raccogliendo le unità di moneta interne che esso impiega in commissioni e rivendendo queste in una costante vendita all'asta. Gli utenti avrebbero bisogno di "attivare" i loro accounts con ether, ma una volta che ether è là esso sarebbe riusabile perché il contratto lo risarcirebbe ogni volta. - -### Derivati Finanziari e Monete dal Valore Stabile - -I derivati finanziari sono la più comune applicazioni di uno "smart contract", e tra i più semplici da implementare nel codice. La sfida più grande nell'implementare i contratti finanziari è che la maggioranza di questi richiede un collegamento ad un indice di prezzo esterno; per esempio, un applicazione molto utile è uno smart contract che assicura dalla volatilità dell'ether (od un altra another criptomoneta) con riferimento ai dollari americani, ma questo richiede al contratto di sapere quale sia il valore tra ETH/USD. Il modo più semplice per farlo è attraverso un contratto "data feed" mantenuto da una parte specifica (eg. NASDAQ) progettato in modo che tale parte ha la possibilità di aggiornare il contratto , se necessario, e fornendo un'interfaccia che permette altri contratti di inviare un messaggio a questo contratto e fornire una risposta che procura il prezzo. - -Avendo fatto queste premesse, il contratto di hedging sarebbe come segue: - -1. Attende la parte A per l'input di 1000 ether. -2. Attende la parte B per l'input di 1000 ether. -3. Registra il controvalore in USD di 1000 ether, calcolato interrogando in contratto di data feed, nello storage, sostenendo che questo è $x. -4. Dopo 30 giorni, viene permesso ad A o B di "riattivare" il contratto al fine di inviare il controvalore $x di ether (calcolato dalla nuova interrogazione del contratto di data feed al fine dell'ottenimento nel nuovo prezzo) ad A ed il resto a B. - -Questo tipo di contratto ha un pontenziale significativo nel commercio in criptomoneta. Uno dei principali problemi riguardo la criptomoneta è la volatilità; tuttavia molti utenti e commercianti potrebbero preferire la sicurezza e la convenienza di trattare gli asset crittografici, senza l'eventualità di prospettare una perdita del 23% del valore dei loro fondi in un unico giorno. Fino ad ora, la soluzione più comune proposta è stata quella degli assets garantiti dall'emittente; l'idea è che un emittente crei una sub-moneta in cui ha diritto di emettere o revocare unità, e fornire un'unità della moneta a chiunque le procuri (offline) un'unità di un asset sottostante (ad es. oro, USD). L'emittente successivamente promette di fornire un'unità dell'asset sottostante a chiunque le reinvii un'unità del crypto-asset. Questo meccanismo permette a qualsiasi asset non crittografico di "elevarsi" ad asset crittografico, fornito dall'emittente fidato. - -In pratica, tuttavia, gli emittenti non sono sempre fidati, e in qualche caso l'infrastruttura della banca è troppo debole, o troppo ostile, affinché esista ogni servizio. I derivati finanziari forniscono un'alternativa. Qui, al contrario del caso in cui il singolo emittente che fornisce i fondi per garantire un asset, fa la sua parte un mercato decentralizzato di speculatori, scommettendo che il prezzo dell'asset di riferimento (ad. es. ETH) salirà. A differenza degli emittenti, gli speculatori non hanno opzioni di default dalla loro parte del patto, poiché il contratto trattiene i loro fondi in un escrow. Si noti che con questo approccio non è pienamente decentralizzato, perché una risorsa fidata è ancora necessaria al fine di fornire l'indice del prezzo, anche se probabilmente perfino questo è un miglioramento enorme in termini di riduzione dei requisiti dell'infrastruttura (a differenza dall'essere un emittente, diramare un feed del prezzo non richiede license e può essere classificato come libertà di pensiero) diminuendo il potenziale per frode. - -### Sistemi di Identità e Reputazione - -La prima criptomoneta alternativa in assoluto, [Namecoin](http://namecoin.org/), ha tentato di utilizzare una blockchain tipo quella del Bitcoin al fine di fornire un sistema di registrazione di nomi di dominio, dove gli utente possono registrare i loro nomi di dominio in un database pubblico insieme ad altri dati. Il più importante caso d'uso citato è per un sistema [DNS](http://en.wikipedia.org/wiki/Domain_Name_System) , che collega i nomi di dominio come "bitcoin.org" (o, nel caso di Namecoin, "bitcoin.bit") ad un indirizzo IP. Altri casi d'uso includono l'autenticazione nell'email e potenzialmente sistemi di reputazione più avanzati. Qui c'è un contratto basico che fornisce un sistema di registrazione di nome di dominio tipo tipo Namecoin attraverso Ethereum: - - def register(name, value): - if !self.storage[name]: - self.storage[name] = value - -Il contratto è molto semplice; tutto questo è un database che può essere inserito all'interno del network di Ethereum, ma non modificato o rimosso. Chiunque può registrare un nome di dominio con qualche valore, e questa registrazione rimane per sempre. Un contratto di registrazione di nomi di dominio più sofisticato avrà anche una "clausola di funzione" che permette agli altri contratti di interrogarlo, così come un meccanismo per il "proprietario" (ad es. il primo registrante) di un nome di dominio di modificare i dati o trasferire la proprietà. Un individuo può perfino aggiungere, sull'apice, un sistema di reputazione ed una funzionalità web-della-fiducia. - -### Storage Decentralizzato di Files - -Nel corso degli ultimi anni, sono emerse un numero di startups popolari che si occupano dello storage online dei files, tra cui la più importante è divenuta Dropbox, che permette agli utenti di fare un backup tramite upload dei loro hard disk, di avere un servizio di storage del backup e quindi accedervi in cambio di un abbonamento mensile. Tuttavia, oggi giorno il mercato dello storage dei files è allo stato relativamente inefficiente; un rapido excursus alle varie [soluzioni esistenti](http://online-storage-service-review.toptenreviews.com/) mostra che, con particolare riferimento alla "strana valle" al livello di 20-200 GB, alla quale né abbonamenti gratuiti né quelli di livello aziendale danno soluzione, i costi sostenuti mensilmente per i servizi più celebri di file storage sono maggiori, con riferimento alla finestra temporale di un singolo mese di abbonamento, rispetto a quelli relativi all'acquisto di un intero hard disk. I contratti in Ethereum permettono lo sviluppo di un ecosistema decentralizzato di file storage, dove i singoli utenti possono guadagnare piccole somme di denaro dall'affitto dei propri hard disks ed in cui lo spazio inutilizzato può essere impiegato per spingere verso il basso i costi di archiviazione dei files. - -Il punto chiave di tale dispositivo sarebbe quello che abbiamo chiamato "il contratto Dropbox decentralizzato". Questo contratto funziona come segue. Per primo, vengono divisi i dati desiderati in blocchi, crittografando ogni blocco per questioni di privacy, costruendo un Merkle tree al di fuori di questo. Quindi viene definito un contratto con la regola che, ogni N blocchi, il contratto possa scegliere un indice randomico nel Merkle tree (usando l'hash del blocco precedente, accessibile dal codice del contratto, come generatore di causualità), e vengono dati X ether alla prima entità per fornire una transazione con un un sistema semplificato di verificazione del pagamento come la "prova di proprietà" del blocco con quel particolare indice nel tree. Quando gli utenti vogliono ri-scaricare i loro files, possono usare un protocollo di micropagamento (ad es. pagando 1 szabo per 32 kilobytes) per recuperare il file; l'approccio più efficiente in termini di commissione è per il pagante quella di non rendere pubblica la transazione fino alla fine, ma di sostituire la transazione con una più lucrativa con lo stesso nonce dopo ogni 32 kilobytes. - -Un'importante caratteristica del protocollo è che, sebbene può sembrare che un nodo si stia affidando a diversi nodi randomici per non rischiare di dimenticare il file, uno può ridurre, quasi a zero, questo rischio attraverso la frammentazione del file in molte parti attraverso una condivisione segreta, ed osservare i contratti al fine di controllare se ogni frammento è ancora nel possesso del nodo. Se un contratto sta ancora trasmettendo del denaro, questo fornisce una prova crittografica che qualcuno al di fuori di sta ancora conservando il file. - -### Organizzazioni Autonome Decentralizzate - -Il concetto generale delle "organizzazione autonome decentralizzate" è che un'entità virtuale ha un certo numero di membri o azionisti che, probabilmente con una maggioranza del 67%, abbia il diritto di spendere i fondi dell'entità e modificare il proprio statuto. I membri potrebbero collettivamente decidere su come l'organizzazione dovrebbe allocare i propri fondi. I Metodi per allocare una i fondi di una OAD (DAO) potrebbero spaziare da premi, salari e perfino consistere in meccanismi più particolari come un una moneta interna per premiare un lavoro. Questo replica essenzialmente i crismi legali di una compagnia tradizionale o di una non profit a differenza che, per l'attuazione, si usa una sola tecnologia blockchain crittografica. Fino ad oggi gran parte del discorso circa i DAO è stato attorno il modello "capitalistico" di una "società autonoma decentralizzata" SAD (DAC) con la suddivisione dei dividendi delle azioni e azioni negoziabili; un'alternativa, probabilmente descritta come una "comunità autonoma decentralizzata", potrebbe conferire a tutti i suoi membri un'azionariato egualitario al fine di decidere di ottenere che il 67% dei membri esistenti accettino e rimuovano un membro. Il requisito che una persona possa essere solo un unico membro potrebbe quindi essere imposta collettivamente dal gruppo. - -Un profilo generale per come codificare un DAO è il seguente. Il design più semplice consiste nella parte di un codice che si auto modifica che cambia se due terzi dei membri concordano su un cambiamento. Sebbene il codice è teoricamente immutabile, un soggetto può facilmente aggirare questo ostacolo ed ottenere una mutabilità de facto avendo frammenti di codice in contratti distinti, e avendo l'indirizzo dei contratti per richiamare i dati archiviati nello storage modificabile. In una semplice implementazione di questo come un contratto DAO, ci sarebbero tre tipi di transazioni, distinte dai dati forniti nella transazione: - -* `[0,i,K,V]` per registrare una proposta con indice `i` per cambiare l'indirizzo all'indice dello storage `K` al valore `V` -* `[0,i]` per registrare un voto in favore di una proposta `i` -* `[2,i]` per finalizzare la proposta `i` se sono stati fatti sufficienti voti - -Il contratto potrebbe avere quindi clausole per ognuna di queste. Esso potrebbe mantenere una registrazione di tutti i cambiamenti aperti dello storage, insieme ad un elenco di chi ha votato per essi. Inoltre esso potrebbe avere una lista di tutti i membri. Quando qualsiasi cambiamento dello storage raggiunge due terzi dei membri che votano per esso, una transazione conclusiva potrebbe eseguire il cambiamento. Una più sofisticata intelaiatura potrebbe anche avere un'opzione di voto costruita al suo interno per caratteristiche come l'invio di una transazione, l'aggiunta o la rimozione dei membri, e potrebbe perfino essere utile per [Liquid Democracy](http://en.wikipedia.org/wiki/Delegative_democracy)-style vote delegation (ad es. ognuno può assegnare a qualcuno di votare per lui, e l'assegnazione è transitiva così se A assegna a B e B assegna a C quindi C determina il voto di A). Questo design potrebbe consentire alla DAO di svilupparsi organicamente come una comunità decentralizzata, che consenta alle persone, in caso, di delegare il compito di filtrare chi sia un membro agli specialisti, sebbene diversamente dal "sistema corrente" gli specialisti possono facilmente immettere e cancellare nel tempo come i membri individuali di una comunità cambiano i loro allineamenti. - -Un modello alternativo per una società decentralizzata, dove qualsiasi account può avere zero o più azioni, e dove due terzi delle azioni sono necessarie per prendere una decisione. Un'intelaiatura completa potrebbe coinvolgere la funzionalità della gestione degli asset, l'abilità di fare un'offerta per comprare o vendere le azioni, e l'abilità di accettare offerte (preferibilmente con un meccanismo di matching dell'ordine all'interno del contratto). La delega potrebbe anche esiste come una Democrazia di tipo liquido, estendendo il concetto della "board of directors". - -### Ulteriori Applicazioni - -**1. Portafogli di risparmio**. Si supponga che Alice vuole tenere al sicuro i suoi fondi, ma è preoccupata circa il fatto che lei li perderà o qualcuno eseguirà un hack della sua chiave privata. Lei attraverso ether stipula un contratto con Bob, una banca, come segues: - -* Alice può in maniera autonoma ritirare, ogni giorno, al massimo l'1% dei fondi. -* Bob può in maniera autonoma ritirare, ogni giorno, al massimo l'1% dei fondi, ma Alice ha la possibilità di eseguire una transazione con la sua chiave impedendo questa possibilità. -* Alice e Bob insieme possono ritirare qualsiasi quantità di fondi. - -Normalmente, l' 1% è sufficiente per Alice, e se Alice vorrà ritirare di più di quanto lei può, potrà contattare per un aiuto Bob. Se La chiave di Alice viene hackerata, lei chiede soccorso a Bob per movimentare i fondi su un nuovo contratto. Se lei perde la sua chiave, alla fine Bob avrà i fondi al di fuori. Se risulterà che Bob sarà dannoso, Alice potrà quindi disattivare l'abilità di ritirare fondi di Bob. - -**2. Assicurazione sul raccolto**. Un soggetto può facilmente creare contratti di derivati finanziari usando un data feed delle condizioni meterologiche al posto dell'indice del prezzo. Se un agricoltore in Iowa acquista un derivato che paga in maniera inversamente proporzionale alla precipitazione in Iowa, il contadino riceverà automaticamente, nel caso in cui segua una siccità, i soldi e se ci sarà pioggia a sufficienza lui sarà soddisfatto perché i suoi raccolti saranno andati bene. Questo ragionamento può essere applicato generalmente anche alle assicurazione sui disastri naturali. - -**3. Un data feed decentralizzato**. A differenza dei contratti finanziari, sarebbe possibile attualmente decentralizzare il data feed tramite un protocollo denominato "[SchellingCoin](http://blog.ethereum.org/2014/03/28/schellingcoin-a-minimal-trust-universal-data-feed/)". Sostanzialmente SchellingCoin funziona come segue: tutte le N controparti inseriscono nel sistema il valore di un dato fornito (ad es. il prezzo ETH/USD), i valori vengono scelti, e ognuno tra il 25% e il 75% ottiene un token come premio. Ciascuno ha l'incentivo di fornire una risposta che tutti gli altri forniranno, e l'unico valore su cui un vasto numero di utenti potrà realisticamente concordare è l'ovvio predefinito: la verità. Questo crea un protocollo decentralizzato che può in teoria fornire qualsiasi numero di valori, incluso il prezzo di ETH/USD, la temperatura in Berlino o perfino una calcolo particolarmente difficile. - -**4. Un escrow smart multifirma**. Bitcoin permette la multifirma nelle transazione dei contratto dove, per esempio, tre di un totale di cinque chiavi possono spendere i fondi. Ethereum permette più livello di dettaglio; per esempio, quattro di un totale di cinque chiave possono spendere qualsiasi quantità di fondi, tre di cinque possono spendere fino ad un totale del 10% al giorno, e due di cinque possono spendere fino al 0.5% al giorno. In più, la multifirima in Ethereum è asincrona - due soggetti possono registrare, in tempi differenti, le loro firme sulla blockchain e l'ultima firma invierà automaticamente la transazione. - -**5. Cloud computing**. La tecnologia EVM può essere inoltre usata per creare una sistema di computing verificabile, permettendo agli utenti di chiedere agli altri di effettuare le computazioni e, nel caso, di chiedere, a certi checkpoints scelti randomicamente, le prove che queste computazioni siano avvenute correttamente. Questo consente la creazione di un mercato di cloud computing dove ogni utente può partecipare con il suo desktop, laptop o server specializzato, e dove controlli spot con depositi cauzionali possono essere usati per assicurare che il sistema sia meritevole di fiducia (ad es. i nodi non possono imbrogliare in maniera profittevole). Tuttavia questo tipo di sistema può non essere utile per tutti i compiti; per es. quelli che richiedono un alto livello di computazione tra processi non possono facilmente essere fatti su un grande cloud di nodi. Ciononostante le altre richieste sono più facili da essere messe in parallelo; progetti come SETI@home, folding@home e algoritmi generici possono essere facilmente implementati all'apice di queste piattaforme. - -**6. Gioco peer-to-peer**. Qualsiasi numero di protocolli di gioco peer-to-peer, come quelli di Frank Stajano e Richard Clayton [Cyberdice](http://www.cl.cam.ac.uk/~fms27/papers/2008-StajanoCla-cyberdice.pdf), possono essere implementati sulla blockchain di Ethereum. Il protocollo di gioco più semplice è ad oggi un semplice contratto per la differenza sul prossimo hash di blocco, e dei più avanzati protocolli che possono essere costruiti da lì, creando servizi di gioco, con commissioni vicine allo zero, che non hanno la possibilità di imbrogliare. - -**7. Mercati predittivi**. Fornito un oracolo o SchellingCoin, i mercati predittivi sono anch'essi semplici da implementare, ed essi insieme a SchellingCoin possono dimostrare di essere la prima applicazione su larga scala della [futarchy](http://hanson.gmu.edu/futarchy.html) come un protocollo per l'amministrazione delle organizzazioni decentrallizzate. - -**8. Mercati decentralizzati sulla blockchain**, che usano il sistema basato sull'identità e sulla reputazione. - -## Altre questioni - -### Implementazione GHOST modificata - -Il protocollo "Greedy Heavist Observed Subtree" (GHOST) è un'innovazione introdotta per la prima volta da Yonatan Sompolinsky e Aviv Zohar nel [Dicembre 2013](http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf). La motivazione dietro il GHOST è che le blockchain con tempi di conferma veloci soffrono, allo stato attuale, di una sicurezza ridotta dovuta ad un elevato tasso di latenza- perchè i blocchi impiegano determinati tempi per propagarsi attraverso il network, se il miner A elabora un blocco e successivamente il miner B elabora un altro blocco prima che il blocco del miner A sia propagato a B, il blocco del miner B andrà sprecato e non contribuirà alla sicurezza della rete. Inoltre, esiste un problema di centralizzazione: se il miner A è una pool di mining con una potenza di hash del 30% ed il miner B ne ha una del 10%, A avrà un rischio di produrre un blocco latente pari al 70% delle volte (visto che, nell'altro 30% dei casi, A ha prodotto l'ultimo blocco e quindi otterrà i dati di mining immediatamente) mentre B correrà il rischio di produrre un blocco latente il 90% dei casi. Quindi l'intervallo del blocco è abbastanza breve affinchè il grado di latenza sia alto e A sarà sostanzialmente più efficiente semplicemente in virtù delle sue dimensioni. Con il combinato di questi due effetti, le blockchains che producono blocchi velocemente corrono fortemente il rischio di convogliare verso una mining pool, che ha una percentuale di potenza di hash sul network abbastanza elevata, arrivando in tal modo al controllo del processo di mining. - -Come descritto da Sompolinsky e Zohar, GHOST risolve il primo problema della perdita di sicurezza della rete attraverso l'inclusione dei blocchi latenti nel computo di quale "chain" sia la "più lunga"; vale a dire, non solo il blocco precedente, o quelli ancora più vecchi, rispetto ad un blocco, ma anche quelli latenti e discendenti da un blocco più vecchio (nel gergo Ethereum "zii") sono aggiunti nel computo di quale blocco ha il più grande proof of work che lo sostiene. Per risolvere la seconda questione della faziosità della centralizzazione, noi andiamo al di là del protocollo descritto da Sompolinsky e Zohar, e forniamo i premi del blocco ai blocchi latenti: un blocco latente riceve lo 87.5% del proprio premio base, e il "nipote" che include il blocco latente riceve il restante 12.5%. Tuttavia, le commissioni di transazione, non vengono assegnate agli "zii". - -Ethereum implementa una versione semplificata del GHOST che va in profondità nel limite di soli sette livelli. In particolare, esso è definito come segue: - -* Il blocco A deve specificare un genitore, e specificare 0 o più zii -* Uno zio, incluso nel blocco B, deve avere le seguenti proprietà: - * Deve essere un figlio diretto della k generazione antenata di B, dove 2 <= k <= 7. - * Esso non può essere un antenato di B - * Uno zio deve essere un valido header del blocco, ma non necessita di essere verificato in precedenza o perfino un blocco valido - * Uno zio deve essere diverso da tutti gli zii inclusi nei blocchi precedenti e da tutti gli altri zii inclusi nello stesso blocco (inclusione non doppia) -* Per ogni zio U nel blocco B, il miner di B riceve un addizionale 3.125% aggiunto al premio della propria coinbase e il miner di U riceve il 93.75% come premio standard della coinbase. - -Questa versione limitata di GHOST, con gli "zii" che possono essere inclusi fino a 7 generazioni, è stata impiegata per due ragioni. La prima, un GHOST illimitato potrebbe includere troppe complicazioni nel computo di quali "zii", per un certo blocco, siano validi. Il secondo, un GHOST illimitato, con il compromesso raggiunto in Ethereum, elimina l'incentivo per un miner di effettuare operazioni di mining su una "chain" di un attaccante, ma, al contrario, di effettuarle sulla "chain" principale. - -### Commissioni - -Poiché ogni transazione pubblicata nella blockchain impone al network il costo del download e la verifica della stessa, c'è il bisogno, al fine di prevenire un abuso, di qualche meccanismo di regolazione, che solitamente coinvolge le commissioni di transazione. L'approccio standard, usato in Bitcoin, consiste in quello di avere commissioni prettamente volontarie, contando sul fatto che i miners agiscono come custodi ed impostano minimi dinamici. Questo approccio è stato recepito in maniera molto favorevole nella community Bitcoin poichè, in particolare, è "basato sul mercato", permettendo, tra i miners, domanda e offerta e che i mittenti della transazione possano determinare il prezzo. Il problema con questa impostazione di ragionamento è, tuttavia, che il processo di transazione non è un mercato; anche se è intuitivamente interessante interpretare l'elaborazione delle transazioni come un servizio che il miner sta offrendo al mittente, in realtà ogni transazione che un miner include necessiterà di essere processata da ogni nodo del network, così che la maggior parte del costo del processo di una transazione è a carico di terzi e non del miner che sta prendendo una decisione se includere o meno questa. Quindi, è molto probabile che si verifichi la Tragedia-dei-beni-comuni. - -Tuttavia, come si scopre questo difetto nel meccanismo di mercato, quando viene fornita, per semplificazione, una premessa particolarmente inaccurata, magicamente si elimina da sola. L'argomento è il seguente. Supponiamo che: - -1. Una transazione comporta `k` operazioni, offrendo un premio `kR` a qualsiasi miner che la includa dove `R` è impostato dal mittente e `k` e `R` sono (approssimativamente) visibili in anticipo dal minatore. -2. Un'operazione ha un costo di processo di `C` verso qualsiasi nodo (ad es. tutti i nodi hanno la stessa efficienza) -3. Ci sono `N` nodi di mining, ognuno dei quali con una potenza di processamento uguale (ad es. `1/N` del totale) -4. Non esistono nodi pieni che non eseguono operazioni di mining. - -Un miner potrebbe desiderare di processare una transazione nella prospettiva che il possibile premio sia superiore al costo. Quindi, la ricompensa prevista è `kR/N` visto che il miner ha `1/N` chance di processare il blocco successivo, ed il costo di processamento per il miner è semplicemente `kC`. Quindi, i miners includeranno le transazioni dove `kR/N > kC`, e il costo di processamento o `R > NC`. Si noti che `R` è la commissione dovuta dal mittente ad ogni operazione, ed è perciò inferiore della soglia minina di vantaggio che il mittente ha dall'operazione, e `NC` è tutto il costo dell'intero network per il processamento di un operazione. Quindi, i miners hanno l'incentivo di includere solo quelle transazioni per cui il vantaggio complessivo è maggiore del costo. - -Tuttavia, in realtà, ci sono importanti deroghe da questi presupposti: - -1. Il miner paga un costo più alto per processare la transazione rispetto ad un altro che verifica i nodi, visto che il tempo di verifica in più ritarda la propagazione del blocco e quindi aumenta la chance che il blocco diventi latente. -2. Esistono nodi pieni che non processano operazioni di mining. -3. La distribuzione del potere di mining potrebbe generare in concreto una ineguaglianza. -4. Gli speculatori, i nemici politici ed i soggetti insensati la cui funzione di utilità incorpora causando un danneggiamento al network dove essi esistono, e possono abilmente creare contratti il ​​cui costo è molto inferiore al costo pagato dagli altri nodi di verifica. - -(1) sia fornita una predisposizione per il miner ad includere meno transazioni, e (2) si incrementi `NC`; quindi, questi due effetti si elidono, almeno parzialmente, a vicenda. (3) e (4) sono i maggiori problemi; per risolverli istituiamo semplicemente un tetto limite: nessun blocco può avere più operazioni che `BLK_LIMIT_FACTOR` rispetto la media esponenziale a lungo termine. Nello specifico: - - blk.oplimit = floor((blk.parent.oplimit * (EMAFACTOR - 1) + floor(parent.opcount * BLK_LIMIT_FACTOR)) / EMA_FACTOR) - -`BLK_LIMIT_FACTOR` e `EMA_FACTOR` sono costanti che saranno impostate a 65536 e 1.5 per il momento, ma probabilmente saranno oggetto di cambiamenti dopo un'ulteriore analisi. - -C'è un altro fattore che si pone come disincentivo alla grandezza dei grandi blocchi in Bitcoin: i blocchi che sono grandi impiegheranno più tempo a propagarsi, e quindi avranno una maggiore probabilità di diventare latenti. In Ethereum, i blocchi che consumano una larga quantità di gas possono anche impiegare più tempo a propagarsi sia perchè essi sono fisicamente più grandi e sia perchè impiegano più tempo affinché la transizione della transazione di stato sia validata. Il disincentivo del ritardo è un'importante considerazione in Bitcoin, ma di meno in Ethereum a causa del protocollo GHOST; perciò, si produce uno standard più stabile bansandosi su limiti di blocco regolati. - -### Computazione e completezza di Turing - -Un'importante osservazione è che Ethereum virtual machine è Turing-complete; questo significa che il codice EVM può codificare qualsiasi computazione, compresi loops infiniti, che possa essere teoricamente adempiuta. Il codice EVM permette il loop in due modi. Per primo, c'è un'istruzione `JUMP` che consente al programma di tornare indietro a un punto precedente nel codice, ed un'istruzione `JUMPI` per eseguire, a certe condizioni, dei salti, permettendo asserzioni come `while x < 27: x = x * 2`. In seconda istanza, i contratti possono, permettendo potenzialmente loops tramite ricorsione, chiamare altri contratti. Naturalmente da ciò può derivare un problema: possono, nella pratica, utenti malevoli far spegnere i miners e i nodi completi, fornzandoli ad entrare in un loop infinito? La problematica nasce a causa di un problema noto nella computer science come quello della terminazione: in generale non c'è modo di chiedere se un programma terminerà mai. - -La nostra soluzione, come è stato illustrato nella sezione della transizione di stato, funziona attraverso la richiesta ad una transazione di impostare un numero massimo di fasi di computazione impiegabili, e se un'esecuzione impiega una computazione più lunga, essa viene fatta tornare indietro, mentre le commissioni dovranno essere lo stesso pagate. I messaggi funzionano allo stesso modo. Per mostrare la motivazione che sta dietro la nostra soluzione, si considerino i seguenti esempi: -* Un attaccante crea un contratto che esegue un loop infinito, e quindi invia una transazione che attiva questo loop presso il miner. Quest'ultimo processerà la transazione, eseguendo il loop infinito, aspettando che questo esaurisca il gas. Perfino se l'esecuzione termina il gas e si ferma a metà, la transazione sarà ancora valida ed il miner potrà ancora richiedere dall'attaccante la commissione per ogni fase computazionale. -* Un attaccante crea un loop infinito molto lungo al fine di forzare il miner di eseguire una computazione per il tempo sufficientemente lungo affichè la computazione, nel termine dell'uscita di pochi blocchi, termini e non sarà possibile per il miner includere la transazione per richiedere la commissione. Tuttavia, l'attaccante potrà domandare di sottoscrivere un valore per `STARTGAS`, limitando il numero di steps computazionali che l'esecuzione può richiedere, cosi che il miner saprà in anticipo se la computazione impiegherà un numero eccessivamente grande di fasi. -* Un attaccante esamina un contratto con un codice di qualche forma come `send(A,contract.storage[A]); contract.storage[A] = 0`, ed invia una transazione con solo gas a sufficienza per far funzionare il primo step, ma non il secondo(ad es. facendo un ritiro ma non facendo diminuire il saldo). L'autore del contratto non necessita di preoccuparsi riguardo la protezione contro questi tipi di attacchi, poichè se l'esecuzione termina a metà strada, questa viene ripristinata attraverso delle modifiche. -* Un contratto finanziario funziona prendendo la media di nove data feed al fine di minimizzare il rischio. Un attaccante sfrutta uno dei data feed, che è pensato per essere modificabile attraverso il meccanismo chiamata-indirizzo-variabile descritto nella sezione dei DAO, e lo converte per eseguire un loop infinito, cercando di forzare con ciò ogni tentativo di richiedere i fondi dal contratto finanziario per far terminare il gas. Comunque, il contratto finanziario può impostare un limite di gas sul messaggio per prevenire questo problema. -L'alternativa alla completezza di Turing è l'incompletezza di Turing, dove `JUMP` e `JUMPI` non esistono e solo dove ad una sola copia di ogni contratto è permesso di esistere nella chiamata nel mucchio in un dato tempo. Con questo sistema, il sistema di commissione descritto e le incertezze attorno l'efficacia della nostra soluzione potrebbero non essere necessarie, come il costo di esecuzione di un contratto potrebbe essere delimitato dalle sue dimensioni, l'incompletezza di Turing non è ancora un grosso limite; di tutti gli esempi di contratto che abbiamo ideato all'interno, finora solo uno richiede un loop, e perfino questo potrebbe essere rimosso eseguendo 26 ripetizioni su una parte di codice di una linea. Fornite le importanti implicazioni della completezza di Turing, e il limitato beneficio, perchè non avere semplicemente un linguaggio di Turing incompleto? In realtà, comunque, la non completezza di Turing è lontana da una soluzione nitida del problema. Per capire il motivo, si considertino i seguenti contratti: - - C0: call(C1); call(C1); - C1: call(C2); call(C2); - C2: call(C3); call(C3); - ... - C49: call(C50); call(C50); - C50: (esegue uno step di un programma e registra il cambiamento nello storage) - -Adesso, si invii una transazione ad A. Quindi, in 51 transazioni, noi abbiamo un contratto che impiega 250 steps computazionali. I Miners potrebbero tentare di scoprire, prima del tempo, tali bombe logiche, mantenendo un valore accanto ad ogni contratto, specificando il numero massimo di steps computazionali che esso può impiegare, e calcolando questo per i contratti che chiamano altri contatti in maniera ricorsiva, ma questo potrebbe richiedere ai miners di proibire i contratti che creano altri contratti (visto che la creazione e l'esecuzione di tutti i 26 contratti di cui sopra potrebbe essere facilmente convogliata in un contratto singolo). Un altro punto problematico è che il campo dell'indirizzo di un messaggio è una variabile, così in generale potrebbe non essere perfino possibile dire quali altri contratti, un certo contratto, avrà chiamato anzitempo. Quindi, complessivamente, noi giungiamo ad una sorprendente conclusione: la completezza di Turing è sorprendentemente facile da gestire, e l'assenza di questa è allo stesso modo difficile da amministrare a meno che siano assegnati gli stessi identici controlli - ma in questo caso perché non permettere al protocollo di essere Turing-complete? - -### Valuta ed Emissione - -Il network di Ethereum include una valuta costruita al suo interno, ether, che ha il duplice scopo di fornire uno strato di primario di liquidità per permettere un exchange efficiente tra due tipi di assets digitali e, principalmente, di fornire un meccanismo per pagare le commissioni di transazione. Per comodità e per evitare possibili futuri frantendimenti (si veda il presente dibattito mBTC/uBTC/satoshi in Bitcoin), le denominazioni vengono assegnate prima: - -* 1: wei -* 1012: szabo -* 1015: finney -* 1018: ether - -Ciò dovrebbe essere considerato come un'analogia con il concetto di "dollari" e "centesimi" o "BTC" e "satoshi". Nel futuro prossimo, ci aspettiamo che "ether" sia impiegato per le transazioni ordinarie, "finney" per le microtransazioni e "szabo" e "wei" per discussioni tecniche riguardo l'implementazione del protocollo; le rimanenti denominazioni potrebbe diventare utili più avanti e non dovrebbero essere, al momento, incluse nei clients. - -Il modello di emissione sarà come segue: - -* Ether sarà rilasciato in una vendita di moneta al prezzo di 1000-2000 ether per BTC, un meccanismo che intende finanziare l'organizzazione Ethereum e pagare per lo sviluppo come è successo in altre piattaforme come Mastercoin e NXT. I primi compratori beneficeranno di grandi sconti. I BTC raccolti dalla vendita saranno interamente usati per pagari i salari per i premi agli sviluppatori e investiti per vari progetti profit e non profit in Ethereum e nell'ecosistema delle criptomonete. -* 0.099x del totale dell'ammontare venduto (60102216 ETH) sarà allocato all'organizzazione per compensare i primi contributori e pagare le spese denominate in ETH prima del blocco di genesi. -* 0.099x del totale dell'ammontare venduto sarà conservato come una riserva a lungo termine. -* 0.26x del totale dell'ammontare venduto sarà conferito ai miners ogni anno dopo questo momento. - -| Group | Al lancio | Dopo 1 anno | Dopo 5 anni -| ------------- | ------------- |-------------| ----------- | -| Unità di moneta | 1.198X | 1.458X | 2.498X | -| Compratori | 83.5% | 68.6% | 40.0% | -| Riserva spesa prima della vendita | 8.26% | 6.79% | 3.96% | -| Riserva usata dopo la vendita | 8.26% | 6.79% | 3.96% | -| Miners | 0% | 17.8% | 52.0% | - -**Tasso di Crescita a Lungo-Termine (in percentuale)** - -![SPV in bitcoin](https://blog.ethereum.org/wp-content/uploads/2013/12/issuance-model.jpg) - -_Tuttavia, nonostante l'emissione di valuta lineare, il tasso di crescita dell'offerta, proprio come avviene nel Bitcoin, tende, con il passare del tempo, a zero_ - -Le due principali scelte nel suddetto modello sono (1) l'esistenza e i limiti dell'emissione monetaria, e (2) l'esistenza di un'offerta che cresce costantemente in maniera lineare, al contrario di una fornitura limitata come in Bitcoin. La giustificazione della limitatezza dell'emissione monetaria è la seguente. Se quest'ultima non esistesse, e l'emissione lineare si riducesse a 0.217x per fornire lo stesso tasso di inflazione, quindi la quantità totale di ether potrebbe essere 16.5% di meno e così ogni unità il 19.8% più costosa. Quindi, con l'equilibrio del 19.8% sarebbero acquistati più ether nella vendita, così ogni unità avrebbe di nuovo lo stesso valore di prima. L'organizzazione potrebbe poi avere anche 1.198x di BTC, che potrebbe considerare di dividere in due parti: i BTC originali, e l'addizionale 0.198x. Perciò, questa situazione è esattamente equivalente all'emissione monetaria limitata, ma con un'importante differenza: l'organizzazione conserva soltanto i BTC, e non è incentivata a sostenere il valore di ogni singola unità ether. - -La modello di crescita, che si sviluppa in modo lineare, riduce il rischio di quello che qualcuno vede come un eccessiva concentrazione di ricchezza in Bitcoin, e garantisce agli individui di oggi e di domani una giusta chance di acquistare unità di valuta, mentre allo stesso tempo fornisce un grande incentivo ad ottenere e conservare ether a causa della tasso di crescita della domanda come una percentuale che tende, nel tempo, comunque a zero. Noi anche teoirizziamo ciò perché le monete vengono sempre perse, nel corso del tempo, a causa di incuria, morte, etc, e i soldi persi possono essere immaginati come una percentuale della fornitura totale per un anno, di quella totale quantità di moneta in circolazione, che infine sarà, nei fatti, stabilizzata al valore uguale all'emissione annua diviso il tasso di perdita (ad es. al tasso di perdita dell' 1%, una volta che la fornitura raggiunge il 26X poi 0.26X sarà minata e il 0.26X persa ogni anno, creando un equilibrio). - -Si osservi che nel futuro, è probabile che Ethereum convergerà sul modello del proof-of-stake per la sicurezza, riducendo i requisiti di emissione verso qualcosa tra lo zero e il 0.05X per anno. Lasciamo aperto un "contratto sociale", nel caso in cui l'organizzazione di Ethereum perda i fondi o per qualsiasi altra ragione questi spariscano: chiunque ha il diritto di creare una possibile versione futura di Ethereum, con l'unica sola condizione che la quantità di ether debba essere al massimo pari a `60102216 * (1.198 + 0.26 * n)` dove `n` è il numero di anni dopo dopo il blocco di genesi. I creatori sono liberi, per pagare lo sviluppo, di vendere ad una moltitudine o altrimenti assegnare, qualche parte o tutta la differenza tra la maggior fornitura derivante dal PoS e quella massima possibile. Gli aggiornamenti presentati, che non sono conformi con il contratto sociale, potrebbero giustificamente essere deviati in versioni compatibili. - -### Centralizzazione del Mining - -L'algoritmo di minining del Bitcoin funziona attraverso l'elaborazione da parte dei miner, che si ripete milioni di volte, dello SHA256 su versioni leggermente modificate del'intestazione del blocco, fino a che emerge un nodo la cui versione ha un hash inferiore a quello del bersaglio (attualmente circa 2192). Comunque, questo algoritmo di mining è vulnerabile a due forme di centralizzazione. La prima: l'ecosistema di mining ha finito per essere dominato da ASIC (application-specific integrated circuits), chips per computer disegnati per questo scopo, e quindi migliaia di volte più efficienti per il compito specifico del mining del Bitcoin. Questo significa che il mining del Bitcoin non ha più un alto livello di decentralizzazione ed un fine egualitario, poiché richiede milioni di dollari di capitale per parteciparvi concretamente. In seconda istanza: attualmente la maggior parte dei miners di Bitcoin non eseguono la validazione del blocco in locale; invece, essi fanno conto su una mining pool centralizzata che fornisce le intestazioni di blocco. Questo problema è forse il peggiore: al tempo di questo scritto, le principali tre mining pools controllano indirettamente circa il 50% della potenza di calcolo nel network del Bitcoin, sebbene questo sia mitigato dal fatto che i miners possono migrare verso altre mining pools se una, o un gruppo, di queste tentano un attacco al 51%. - -Lo scopo attuale di Ethereum è quello di impiegare un algoritmo di mining dove i miners sono tenuti a recuperare dati randomici dallo stato, elaborare qualche transazione selezionata a caso dagli ultimi N blocchi nella blockchain, e fornire come risultato un hash. Questo ha due importanti benefici. Il primo, i contratti Ethereum, possono includere qualsiasi tipo di computazione cosi che un ASIC in Ethereum potrebbe essenzialmente essere uno valido per una computazione generica - ad es. una migliore CPU. Secondariamente, il mining richiede accesso all'intera blockchain, forzando i miners a conservare l'intera blockchain e ad almeno essere in grado di verificare ogni transazione. Questo elimina la necessità della centralizzazione delle mining pools; sebbene le mining pools possono sempre essere utili per il legittimo ruolo per livellare la casualità della distribuzione del premio; comunque questa funzione può essere svolta altrettanto bene dalle pools peer-to-peer pools con nessun controllo centrale. - -Questo modello non è testato, e ci potrebbero essere delle difficoltà lungo il cammino nell'evitare certe ingegnose ottimizzazioni quando si usa un'esecuzione del contratto come algoritmo di mining. Comunque, una funzione particolarmente interessante di questo algoritmo è che permette a chiunque di "screditare", attraverso l'introduzione di un vasto numero di contratti progettati per ostacolare certi ASIC, nella blockchain. Gli incentivi economici sussistono per i produttori di ASIC al fine di impiegare questo tipo trick per attaccarsi tra di loro. Perciò, la soluzione che stiamo sviluppando è in definitiva una economia che si adatta all'essere umano piuttosto che una puramente tecnica. - -### Scalabilità - -Una problematica comune su Ethereum è quella della scalabilità. Come Bitcoin, Ethereum soffre del difetto che ogni transazione necessiti di essere processata da ogni nodo della rete. Con Bitcoin, la grandezza dell'attuale blockchain è all'incirca di 15 GB, crescendo di un 1 MB all'ora. Se il network Bitcoin dovesse processare le 2000 transazioni al secondo di quello di Visa, esso crescerebbe di un 1 MB ogni tre secondi (1 GB per ora, 8 TB all'anno). Ethereum rischia di soffrire di un simile modello di crescita, e, per di più, con l'aggravio che ci saranno molte applicazioni che funzioneranno, invece che solo una moneta come nel caso di Bitcoin, sull'apice della blockchain di Ethereum. Tuttavia, in Ethereum vi è la miglioria derivante dal fatto che i pieni nodi di questo necessitano di conservare, piuttosto che l'intera cronistoria della blockchain, solamente lo stato. - -Il problema sottostante ad una blockchain così grande è il rischio di centralizzazione. Se la grandezza di questa aumenta di, ad es., 100 TB, lo scenario che si prospetterebbe sarebbe quello che solo un limitato numero di business di grandi dimensioni potrebbero elaborare nodi pieni, con tutti gli utenti normali che usano i nodi SPV. In questo tipo di situazione, crescerebbe la potenziale preoccupazione che i nodi pieni potrebbero lavorare nella stessa direzione e concordare tutti per imbrogliare al fine di avere una serie di vantaggi ( ad es. cambiare il premio del blocco, e dare a loro stessi BTC). I nodi leggeri non avrebbero nessun modo di accorgersi, nell'immediato, di ciò. Naturalmente ci sarebbe, nel caso, almeno un nodo pieno che continuerebbe a fare legittimamente il suo lavoro e solamente dopo poche ore sarebbe scoperta la frode attraverso canali come Reddit, ma a quel punto potrebbe essere troppo tardi: spetterebbe agli utenti ordinari di organizzarsi per creare una lista nero dei blocchi forniti, uno sforzo di coordinazione enorme e probabilmente irrealizzabile sima massive and likely infeasible coordination problem sulla stessa scala di quella di ottenere un attacco al 51% di successo. Nel caso di Bitcoin, questo è attualmente un problema, ma esiste una modifica alla blockchain [suggested by Peter Todd](http://sourceforge.net/p/bitcoin/mailman/message/31709140/) che mitigherà questo problema. - -Nel breve termine, Ethereum impiegherà due strategie addizionali per far fronte a questa questione. La prima consiste nel fatto che, gli algoritmi di minining basati sulla blockchain forzeranno ogni miner a creare almeno un nodo pieno, creando un limite inferiore al numero di nodi pieni. Tuttavia, in seconda istanza ed in maniera più importante, noi includeremo una tree root intermedia nello stato della blockchain dopo il processamento di ogni transazione. Perfino se la validazione del blocco è centralizzata, finché esiste un nodo di verifica onesto, il problema della centralizzazione può essere eluso tramite un protocollo di verificazione. Se un miner pubblica un blocco invalido, quel blocco deve essere mal formattato, o lo stato `S[n]` deve essere non corretto. Dato che`S[0]` è noto per essere corretto, ci deve essere qualche primo stato `S[i]` che è corretto dove `S[i-1]` è corretto. Il nodo di verifica fornirebbe l'indice `i`, insieme a una "prova di invalidità" consistente nel sottoinsieme dei nodi del Patricia tree che necessitano di essere processati `APPLY(S[i-1],TX[i]) -> S[i]`. I nodi sarebbero in grado di usare quei nodi per eseguire quella parte della computazione, ed osservare che `S[i]` generato non corrisponde al `S[i]` fornito. - -Un ulteriore, e più sofisticato, attacco coinvolgerebbe i miners malevoli che pubblicano i blocchi incompleti, in modo tale che non sia necessaria tutta l'informazione per determinare quali blocchi siano validi e quali invalidi. La soluzione a questo è un protocollo che risponde-ad-una-sfida: i nodi di verificazione emettono "sfide" con l'obiettivo di andare a colpire gli indici delle transazioni, e fino alla ricezione di un nodo pieno, uno non completo considera il blocco come non attendibile finché un altro nodo pieno, sia del miner che di un altro verificatore, fornisce un sottoinsieme di nodi Patricia come prova di validità. - -## Conclusioni - -Il protocollo Ethereum è stato originariamente concepito come una versione aggiornata di una criptomoneta, che fornisce caratteristiche avanzate come un escrow sulla blockchain, limiti ai prelievi, contratti finanziari, mercati del gioco e simili attraverso un linguaggio di programmazione gambling markets and the like via a tutto raggio. Il protocollo Ethereum non "supporterà" direttamente alcun tipo di applicazione, ma l'esistenza di un linguaggio di programmazione Turing-complete significa che possono teoricamente essere creati dei contratti arbitrari per qualsiasi tipo di transazione o applicazione. Tuttavia, la cosa più interessante in Ethereum, è che il suo protocollo comprende molto di più che una valuta. I protocolli sullo storage decentralizzato di file, computazione decentralizzata e mercati predittivi decentralizzati, ed altre decine di concetti di questo tipo, hanno il potenziale di aumentare sensibilmente l'efficienza dell'industria relativa al calcolo computazionale, e firnire una spinta enorme agli altri protocolli peer-to-peer aggiungendo per la prima volta un protocollo economico. Infine, c'è anche una consistente gamma di applicazione che non hanno nulla a che vedere con i soldi. - -Il concetto di una funzione arbitraria di transizione di stato come implementata nel procollo di Ethereum con una piattaforma dal potenziale unico; piuttosto che essere una del tipo chiuso, con un protocollo che ha un solo fine inteso per un'unica speficica gamma di applicazioni nello storage dei dati, gioco o finanza, Ethereum ha un design aperto a tutti, e noi crediamo che sia molto adatta per servire, negli anni che verranno, da protocollo fondante per un grande numero di protocolli sia finanziari che non finanziari. - -## Note e Approfondimenti - -#### Note - -1. Un lettore più esperto potrebbe notare che, in effetti, un indirizzo Bitcoin è l' hash di una chiave pubblica dalla curva ellettica, e non la stessa chiave pubblica. Tuttavia, nella practica, è perfettamente legittimo, in termini di terminologia crittografica, riferirsi alla chiave pubblica dell'hash come la stessa chiave pubblica. Questo poiché la crittografia del Bitcoin può essere considerata come un algoritmo di firma digitale personalizzata, dove la chiave pubblica consiste nell' hash della ECC pubkey, la firma consiste nell' ECC pubkey concatenata con la firma ECC, e l'algoritmo di verificazione coinvolge il controllo della ECC pubkey nella firma sull'hash della ECC pubkey fornita come chiave pubblica e quindi verificando la firma dell'ECC sulla pubkey ECC. -2. Tecnicamente, la media degli 11 blocchi precedenti. -3. Internamente, 2 e "CHARLIE" sono entrambi numeri, mentre quest'ultimo è una rappresentazione big-endian base 256. I numeri possono almeno essere 0 o al massimo 2256-1. - -#### Approfindimenti - -1. Intrinsic value: http://bitcoinmagazine.com/8640/an-exploration-of-intrinsic-value-what-it-is-why-bitcoin-doesnt-have-it-and-why-bitcoin-does-have-it/ -2. Smart property: https://en.bitcoin.it/wiki/Smart_Property -3. Smart contracts: https://en.bitcoin.it/wiki/Contracts -4. B-money: http://www.weidai.com/bmoney.txt -5. Reusable proofs of work: http://www.finney.org/~hal/rpow/ -6. Secure property titles with owner authority: http://szabo.best.vwh.net/securetitle.html -7. Bitcoin whitepaper: http://bitcoin.org/bitcoin.pdf -8. Namecoin: https://namecoin.org/ -9. Zooko's triangle: http://en.wikipedia.org/wiki/Zooko's_triangle -10. Colored coins whitepaper: https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit -11. Mastercoin whitepaper: https://github.com/mastercoin-MSC/spec -12. Decentralized autonomous corporations, Bitcoin Magazine: http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/ -13. Simplified payment verification: https://en.bitcoin.it/wiki/Scalability#Simplifiedpaymentverification -14. Merkle trees: http://en.wikipedia.org/wiki/Merkle_tree -15. Patricia trees: http://en.wikipedia.org/wiki/Patricia_tree -16. GHOST: http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf -17. StorJ and Autonomous Agents, Jeff Garzik: http://garzikrants.blogspot.ca/2013/01/storj-and-bitcoin-autonomous-agents.html -18. Mike Hearn on Smart Property at Turing Festival: http://www.youtube.com/watch?v=Pu4PAMFPo5Y -19. Ethereum RLP: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP -20. Ethereum Merkle Patricia trees: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree -21. Peter Todd on Merkle sum trees: http://sourceforge.net/p/bitcoin/mailman/message/31709140/ \ No newline at end of file diff --git a/[Japanese]-Cryptocurrency-Current-Problems.md b/[Japanese]-Cryptocurrency-Current-Problems.md deleted file mode 100644 index c99a19859..000000000 --- a/[Japanese]-Cryptocurrency-Current-Problems.md +++ /dev/null @@ -1,512 +0,0 @@ ---- -name: Cryptocurrency Current Problems -category: ---- - -暗号学において、形式であり、かつシステマティックなThe science of cryptography, which has existed to some degree for millennia but in a formal and systematized form for less than fifty years, can be most simply defined as the study of communication in an adversarial environment. In a similar vein, we can define cryptoeconomics as a field that goes one step further: the study of economic interaction in an adversarial environment. To distinguish itself from traditional economics, which certainly studies both economic interaction and adversaries, cryptoeconomics generally focuses on interactions that take place over network protocols. Particular domains of cryptoeconomics include: - -1. オンライン上の信頼と評価のシステム - -2. 暗号化されたトークンと暗号通貨と、より一般的なデジタルのアセット - -3. 自動執行されるスマートコントラクト - -4. コンセンサスアルゴリズム - -5. アンチスパム・アンチ市民アタックのアルゴリズム - -6. コンピューターのリソース売買のための利益が循環するマーケットプレイス - -7. 分散形の社会福祉システム、互助システム - -8. 分散形の政府(営利または非営利) -* Online trust and reputation systems -* Cryptographic tokens / cryptocurrencies, and more generally digital assets -* Self-executing "smart" contracts -* Consensus algorithms -* Anti-spam and anti-sybil attack algorithms -* Incentivized marketplaces for computational resources -* Decentralized systems for social welfare / mutual aid / basic income -* Decentralized governance (for both for-profit and non-profit entities) - -The increasing prominence of cryptoeconomics in the last five years is to a large extent the result of the growth of cryptocurrencies and digital tokens, and brings a new, and interesting, dimension to cryptography. While before cryptography was, by and large, a purely computational and information-theoretic science, with strong guarantees built on security assumptions that are close to absolute, once money enters the picture the perfect world of mathematics must interact with a much more messy reality of human social structures, economic incentives, partial guarantees and known vulnerabilities that can only be mitigated, and not outright removed. While a cryptographer is used to assumptions of the form "this algorithm is guaranteed to be unbreakable provided that these underlying math problems remain hard", the world of cryptoeconomics must contend with fuzzy empirical factors such as the difficulty of collusion attacks, the relative quantity of altruistic, profit-seeking and anti-altruistic parties, the level of concentration of different kinds of resources, and in some cases even sociocultural circumstances. - -In traditional applied cryptography, security assumptions tend to look something like this: - -伝統的な暗号学では、セキュリティでは、これらのことを考えている。 -1. 誰も 2^79移譲のコンピューターステップを行うことが出来ない。 - -2. - -3. nをルートとして持つモジュロのコンポジットを取ることは困難であること。 - -4. 楕円曲線暗号のアルゴリズムの問題を2n/2 時間以上より速く解くことが出来ないこと。 - -1. No one can do more than 279 computational steps -2. Factoring is hard (ie. superpolynomial) -3. Taking nth roots modulo composites is hard -4. The elliptic curve discrete logarithm problem cannot be solved faster than in 2n/2 time - -暗号学に基づく経済では、一方で基本的なセキュリティに対しての要件に加えて: -1. どの個人も、全てのコンピュータリソースの25%以上を持って、システムを壊すことが出来ない -2. どの個人も、全ての資産の25%以上を持ってシステムを壊すことが出来ないこと。(Proof of stake) -3. ある種の保証を行うためのコンピュータリソースの総量に対して支払われるべき費用の総額が、納得できる額を遥かに超えてしまわないこと - -4. 互助主義者や、間抜けものや、政治的、個人的にシステムに反対するものがいることは否定できないが、大多数のユーザーは、論理的に経済的な合理性を中心として行動するであろうこと。l -5. The number of users of a system is large, and users can appear or disappear at any time, although at least some users are persistent -6. Censorship is impossible, and any two nodes can send messages to each other relatively quickly. -7. It is trivial to generate a very large number of IP addresses, and one can purchase an unlimited amount of network bandwidth -8. Many users are anonymous, so negative reputations and debts are close to unenforceable - -There will also be additional security assumptions specific to certain problems. Thus, quite often it will not even be possible to definitively say that a certain protocol is secure or insecure or that a certain problem has been solved. Rather, it will be necessary to create solutions that are optimized for particular empirical and social realities, and continue further and further optimizing them over time. - - -## 技術面について -## Technology - -The decentralized consensus technology used in Bitcoin is impressive to a very large extent because of its simplicity. A 30-year-old problem in computer science was solved via a mechanism which is simple to implement, and so simple to understand that even some semi-technical teenagers can describe the entirety of how it works. However, at the same time the technology in its current form is very limited. The scalability in Bitcoin is very crude; the fact that every full node needs to process every transaction is a large roadblock to the future success of the platform, and a factor preventing its effective use in micropayments (arguably the one place where it is the most useful). Timestamping is flawed, and proof-of-computation algorithms are very limited in the types of computation that they can support. The fact that the original solution was so "easy", however, suggests that there is still a large opportunity to improve, and there are a number of directions in which improvement could be directed. - -### 1. Blockchain Scalability -### 1. ブロックチェーンのスケーラビリティ - -現在最も大きなブロックチェーンの問題は、 -One of the largest problems facing the cryptocurrency space today is the issue of scalability. It is an often repeated claim that, while mainstream payment networks process something like 2000 transactions per second, in its current form the Bitcoin network can only process seven. On a fundamental level, this is not strictly true; simply by changing the block size limit parameter, Bitcoin can easily be made to support 70 or even 7000 transactions per second. However, if Bitcoin does get to that scale, we run into a problem: it becomes impossible for the average user to run a full node, and full nodes become relegated only to that small collection of businesses that can afford the resources. Because mining only requires the block header, even miners can (and in practice most do) mine without downloading the blockchain. - -The main concern with this is trust: if there are only a few entities capable of running full nodes, then those entities can conspire and agree to give themselves a large number of additional bitcoins, and there would be no way for other users to see for themselves that a block is invalid without processing an entire block themselves. Although such a fraud may potentially be discovered after the fact, power dynamics may create a situation where the default action is to simply go along with the fraudulent chain (and authorities can create a climate of fear to support such an action) and there is a coordination problem in switching back. Thus, at the extreme, Bitcoin with 7000 transactions per second has security properties that are essentially similar to a centralized system like Paypal, whereas what we want is a system that handles 7000 TPS with the same levels of decentralization that cryptocurrency originally promised to offer. - -Ideally, a blockchain design should exist that works, and has similar security properties to Bitcoin with regard to 51% attacks, that functions even if no single node processes more than `1/n` of all transactions where `n` can be scaled up to be as high as necessary, although perhaps at the cost of linearly or quadratically growing secondary inefficiencies and convergence concerns. This would allow the blockchain architecture to process an arbitrarily high number of TPS but at the same time retain the same level of decentralization that Satoshi envisioned. - -**Problem**: create a blockchain design that maintains Bitcoin-like security guarantees, but where the maximum size of the most powerful node that needs to exist for the network to keep functioning is substantially sublinear in the number of transactions. - -**Additional Assumptions and Requirements**: - -* There exist a large number of miners in the network -* Miners may be using specialized hardware or unspecialized hardware. Specialized hardware should be assumed to be more powerful than unspecialized hardware by a large (eg. 10000) constant factor at specific tasks. -* Ordinary users will be using unspecialized hardware -* Ideally, after some number of blocks (perhaps logarithmic in the total size of the network) every transaction should require 51% of network hashpower to reverse. However, solutions where transactions can pay very small fees for a lower "level" of security are acceptable, though one should take care to avoid situations where an attacker can profit by performing one attack to reverse very many small transactions at the same time -* Ideally, the solution should work for and maintain as many properties as possible of a generalized account-based blockchain (eg. Ethereum), though solutions specific to currency, domain registrations or other specialized use caes are acceptable - -### 2. Timestamping -### 2. タイムスタンプ - - -An important property that Bitcoin needs to keep is that there should be roughly one block generated every ten minutes; if a block is generated every day, the payment system becomes too slow, and if a block is generated every second there are serious centralization and network efficiency concerns that would make the consensus system essentially nonviable even assuming the absence of any attackers. To ensure this, the Bitcoin network adjusts difficulty so that if blocks are produced too quickly it becomes harder to mine a new block, and if blocks are produced too slowly it becomes easier. - -However, this solution requires an important ingredient: the blockchain must be aware of time. In order to solve this problem, Bitcoin requires miners to submit a timestamp in each block, and nodes reject a block if the block's timestamp is either (i) behind the median timestamp of the previous eleven blocks, or (ii) more than 2 hours into the future, from the point of view of the node's own internal clock. This algorithm is good enough for Bitcoin, because time serves only the very limited function of regulating the block creation rate over the long term, but there are potential vulnerabilities in this approach, issues which may compound in blockchains where time plays a more important role. - -**Problem**: create a distributed incentive-compatible system, whether it is an overlay on top of a blockchain or its own blockchain, which maintains the current time to high accuracy. - -**Additional Assumptions and Requirements** - -* All legitimate users have clocks in a normal distribution around some "real" time with standard deviation 20 seconds. -* No two nodes are more than 20 seconds apart in terms of the amount of time it takes for a message originating from one node to reach any other node. -* The solution is allowed to rely on an existing concept of "N nodes"; this would in practice be enforced with proof-of-stake or non-sybil tokens (see #9). -* The system should continuously provide a time which is within 120s (or less if possible) of the internal clock of >99% of honestly participating nodes. Note that this also implies that the system should be self-consistent to within about 190s. -* The system should exist without relying on any kind of proof-of-work. -* External systems may end up relying on this system; hence, it should remain secure against attackers controlling < 25% of nodes regardless of incentives. - -### 3. Arbitrary Proof of Computation -### 3. 人為的なコンピュテーションの証拠 -Perhaps the holy grail of the study zero-knowledge proofs is the concept of an arbitrary proof of computation: given a program P with input I, the challenge is to create a zero-knowledge proof that you ran P with input I and received output O, such that the proof can be verified quickly (ie. in polylogarithmic or ideally constant time) even if the original computation took a very large number of steps to complete. In an ideal setup, the proof would even hide the value of I, just proving that you ran P with some output with result O, and if I needs to be made public it can be embedded into the program. Such a primitive, if possible, would have massive implications for cryptocurrency: - -1. ブロックチェーンのスケーラビリティは、マイナーが一連のトランザクションを含めねければ、一層簡単に解くことが出来る。 -このようにして、コンピュテーションを行っているあらゆるノードにおいて、承認されなければならない。 -コンピュテーションを証明するだけでなく、その証拠が新しい状態で合ったとして受け入れなければならない。 -これは完全な解決策ではない、何故なら、それでもなお、データを出力する必要があるが、問題は強力な構成されたブロックよりも簡単に解決される。 - -1. The blockchain scalability problem would be much easier to solve. Instead of miners publishing blocks containing a list of transactions, they would be publishing a proof that they ran the blockchain state updater with some list of transactions and produced a certain output; thus, instead of transactions needing to be verified by every node in the network, they could be processed by one miner and then every other miner and user could quickly verify the proof of computation and if the proof turns out correct they would accept the new state. This is not a complete solution, because there would still be a need to transmit data, but the problem would be much easier with this powerful building block. -2. The blockchain privacy problem would be much easier to solve. The blockchain scalability solution above would hide the details behind individual transactions; it would only reveal the fact that all of them are legitimate, so transactions would be hidden from everyone but the sender and the receiver. -3. It would become computationally viable to use a Turing-complete consensus network as a generic distributed cloud computing system; if you have any computation you wanted done, you would be able to publish the program for miners and miners would be able to run the program for you and deliver the result alongside a proof of its validity. - -There is a large amount of existing research on this topic, including a protocol known as "SCIP" (Succinct Computational Integrity and Privacy) that is already working in test environments, although with the limitation that a trusted third party is required to initially set up the keys; use of this prior work by both its original developers and others is encouraged. - -**Problem**: create programs `POC_PROVE(P,I) -> (O,Q)` and `POC_VERIFY(P,O,Q) -> { 0, 1 }` such that `POC_PROVE` runs program `P` on input `I` and returns the program output `O` and a proof-of-computation `Q` and `POC_VERIFY` takes `P`, `O` and `Q` and outputs whether or not `Q` and `O` were legitimately produced by the `POC_PROVE` algorithm using `P`. - -**Requirements And Additional Assumptions** - -* The runtime of `POC_PROVE` should be in `O(n*polylog(n))` where `n` is the number of steps required to run the program. -* The runtime of `POC_VERIFY` should be either constant or logarithmic in the number of steps, and at most linear in the maximum memory usage of the program. -* The protocol should require no trusted third parties. If TTPs are required, the protocol should include a mechanism for simulating one efficiently using secure multiparty computation. - -### 4. Code Obfuscation -### 4. コードの不明瞭さ -どのようにシンプルに冗長に、双方のキーの暗号化のために、よくテストされたアルゴリズムに暗号化するかについては、 -古くから我々は良く知ってきた。同じキーは暗号化と復号化に必要とされる場所で、そして、公開鍵暗号では、 -同じ鍵は -しかしながら、他の種類の暗号化が潜在的にとても有用になりうる、しかし、現在我々は伝わる形のアルゴリズム、暗号化のためのプログラムだ。 - -2007年には、完璧なブラックボックスとなる暗号化が不可能であることが証明された。 -ブラックボックス化されたアクセスをプログラムに対して持つことと、ブラックボックス化されたコードをプログラムに対してもつことには、違いがある。どれだけコードを難読化しようとも、難読化に対して抵抗のあるプログラムを創りあげることは出来る。 -しかしながら、それは弱いレベルの難読化であり、難読化に対して区別ができるかどうか0としてを定義するのであれば、 -もし同じインプットとアウトプットを持つプログラムが有るならば、0(A) = P と O(B)= Q であり、何もコンピューターリソースとして、 -外部の世界のでのアクセスなしに -PがAから来たのかBから北のかを分かることは出来ない。 - -このような難読化の形式はより一層制限されているように見えるかもしれない、しかしながら多くのアプリケーションにとっては十分である。 -発見的な引数について、 - -**問題**: 合理的に十分である難読化のアルゴリズムを作成することが難しいこと -**追加の前提と必要条件** -* 2^80以上のランタイムが必要とされる -* アルゴリズムは、標準的な楕円曲線暗号化、もしくは10^8のコンピュテーションパワーに耐えうるAESの暗号化 - - -For many years now we have known how to encrypt data. Simple, robust and well-tested algorithms exist for both symmetric key encryption, where the same key is needed to encrypt and decrypt, and public key encryption, where the encryption key and decryption key are different and one cannot be derived from the other. However, there is another kind of encryption that can potentially be very useful, but for which we currently have no viable algorithm: the encryption of programs. The holy grail is to create an obfuscator `O`, such that given any program P the obfuscator can produce a second program `O(P) = Q` such that `P` and `Q` return the same output if given the same input and, importantly, `Q` reveals no information whatsoever about the internals of `P`. One can hide inside of `Q` a password, a secret encryption key, or one can simply use `Q` to hide the proprietary workings of the algorithm itself. - -## 5 Hash-Based Cryptography -暗号通貨の境界線にみ -量子コンピューターの問題である。現在、量子コンピュータは余りにも実現困難であるようにも見えなくなってきている。 -全ての量子コンピューターもしくは"断熱型の量子コンピューター",は、 -極端に限られたプログラムを極めて速い速度で解くことを得意としている。 -しかしながら、起こりにくいこととはいえ、米軍は既に量子コンピューターを手に入れているかもしれない。 -耐量子暗号化を目指す事が幾分高い優先度を持つと考えられる。 - -これまでは、全ての格子上の構造を必要とする有るごリムは、 -個々のメンバーの長さよりも、合計がとても短く -しかしながら、その他のアルゴリズムは耐量子性がある、ハッシュのアルゴリズムだ -古典的なLANポート署名では164 nodes のマークルツリーを作成し、ルートを出版する。そしてハッシュの文書に基づいて選ばれた匿名の82 nodes のマークルツリーの証明を結合させる。 -この署名は、一回の処理でmバルク処理である。 - -ここでの疑問は、より良い方法はないだろうかということだ。 -ハッシュのはしごのように知られている、420バイトまでの署名のサイズを許容するアプローチや、 -他の海藻でのマークルツリーを用いることに依って、署名の数を増やすアルゴリズム、 -そして、 - -しかしながら、これらの方法は不完全であり、もしハッシュに基づく暗号化が、競争力があるアルゴリズムのプロパティであるならば、より良いプロパティを得るために多大に改善する必要がある。 - -**問題** 署名のアルゴリズムは、セキュリティにおいての前提ではなく、ランダムな信頼出来るオラクルのプロパティに依拠している。 -それは、古典的なコンピューター引退しての160bitsのセキュリティを維持しているプロパティである。 -(例えば 80 vs 量子 Groverのアルゴリズムによって)最適化されたサイズと、他のプロパティとである。 - -**前提条件と、付加される前提** -* 224以下に違いない署名を作り出すコンピューターパワーの努力、ハッシュが28 -* 署名のアルゴリズムがスケーラブルであるべきであり、ユーザー数の最大の増加で2xの増加ごとに定数のバイトを署名毎に追加することを犠牲に、もし可能であるならば、そのセットアップに掛かる時間は使用回数に対して直線的であるべきだ。 - -### 6. ASIC-Resistant Proof of Work -問題を解決するための一つの方法は、 -特定化するのがとても困難であるコンピュテーションのタイプに基づいたProof of work のアルゴリズムを作成するということだ -あるアイディアでは、ハッシュのファンクションを"メモリー上に"生成し、より一層ASICが並行稼動することを難しくすることがある。 -このアイディアはとてもシンプルだが、根本的に限られている。もし、関数がメモリー上でのみ動くのであれば、それはメモリーでしか承認出来ない。加えて、平行化を超えたアルゴリズムには -他のアプローチとしては、ランダムで、マニングのファンクションをブロックごとに生成いs,特定性を -ASICが理想的には、任意のコンピュテーションをシンプルなCPUである -**問題** 2つの `PoWProduce(data, diff) - > nonce` and `PoWVerify(datam nonce, diff) - > {0, 1}` をハッシュキャッシュの代わりとなるように提供することによって、経済的にメリットのない`PoWを作り出す`ためのASICを生み出すことに繋がってしまった。 - -**追加の前提条件と必要条件** : -* `PoWの生成` `diff`に対してランタイムで直線的で無ければならない。 -* `PoWの承認` `diff`に対して出来る限り多態的に対数的なランタイムを持たなければならない。 -* `PoWの生成`を走らせることは`1`を返す値を生成し、それを`PoWの承認`を行う際に -最も効率的でなければならない、もしくは、最も効率的である状態に近くなければならない。 -+ - - -### 8. Proof of Stake -マイニングの中央集権化の解決策の他のアプローチには、マイニングを一切行わないことがある、そしてそれぞれのノードの重さを図る他のメカニズムによってコンセンサスに至る。 -現在最も有名な代替案はProof of Stake である。即ち、"CPUパワーの1つのユニット"としてのコンセンサスのモデルを扱う代わりに、 -1つの投票が、1津の通貨のユニットとしての1つのボートとなる。 - -とてもシンプルなProof of Stakeのアルゴリズムは、マイナーがマイニングする際に、 -コインを持っているアドレスの秘密鍵を使って署名を行うことをマイナーに求める。ブロックが有効であったならば`sha256(PREVHAS + ADDRESS + TIMESTAMP) < = 2^256 * BALANCE / DIFFICULTY ` where Prevhashがハッシュの前のブロックにある。`Address`は、BalanceとTime stampを持つ署名者のアドレスであり、それは、秒単位での現在のunixtime を表示する。そして`DIfficulty`は署名が成功する度合いを規定するための調整可能なパラメーターである。 - -1見すると、このアルゴリズムは、基本的に全てのマイナーが秒単位でランダムな成功の機会をもっている、そして、あなたのアドレスはが2倍の金額を持っていれば、2倍の成功の確率を得ることが出来る。 - -しかしながらこのアルゴリズムには、1つの大きな欠点がある。: -それが`Nothing At Stake`問題だ。このフォークのイベントの後に、フォークが偶然であれ、悪意を持って過去の歴史に書き加えようとしたのであれ、そしてトランザクションをリバースさせようとしたのであれ、 -全てのマイナーにとって最適化された戦略は、全てのチェーンをマインすることになる。すると、マイナーはどのフォークがブロックチェーンとして勝ったとしても、報酬を得ることが出来る。 -このようにして、経済的に興味のあるマイナーの大多数がいたとしても、攻撃者はなにかの電子的な商品と引き換えにしてトランザクションを送ることが出来る。(通例は他の暗号通貨).そして商品を受け取ると、 -その商品の売買のトランザクションの1つ前に有るブロックからフォークを始める。 -誰もが全てのブロックを採掘しているが故に、全体のStakeの1%を所持している攻撃者であったとしても、攻撃が成功するかもしれない。 - -他にはLong-range attacksと呼ばれる問題が上がっている。 -マイナーがメインチェーンの先頭の5つか10つ前のブロックをフォークを始めようとしているところ、よく起こることだ、しかし何百何千ものブロックを遡る。 -もしアルゴリズムが不適切であるならば、攻撃者がとても前のブロックから始めることが出来るかもしれない。そして何十億ものブロックを将来のブロックとして彫り、(何故ならばProof of Workは必要ないため) - - -In 2007, it was proven that perfect "black box" encryption is impossible; essentially, the argument is that there is a difference between having black-box access to a program and having the code to that program, no matter how obfuscated, and one can construct certain classes of programs that resist obfuscation. However, there is also a weaker notion of obfuscation, known as indistinguishability obfuscation, that appears to be quite possible. The definition of an indistinguishability obfuscator `O` is that if you take two equivalent (ie. same inputs -> same outputs) programs `A` and `B` and calculate `O(A) = P` and `O(B) = Q`, then there is no computationally feasible way for an outsider without access to `A` or `B` to tell whether `P` came from `A` or `B`. - -This type of obfuscation may seem more limited, but it is nevertheless sufficient for many applications. For a heuristic argument why, consider two programs `F` and `G` where `F` internally contains and simply prints out that 32-byte string which is the hash of "12345", whereas G actually computes the hash of "12345" and prints it out. By the indistinguishability obfuscation definition, there is no computationally feasible way to tell `O(F)` from `O(G)` apart. Hence, if one can feasibly recover "12345" from `O(G)`, then for `O(G)` and `O(F)` to be indistinguishable one would also need to be able to feasibly recover "12345" from `O(F)` - a feat which essentially entails breaking the preimage resistance of a cryptographic hash function. - -Recently, a discovery was made by Craig Gentry, Amit Sahai et al on an algorithm which uses a construction known as "multilinear jugsaw puzzles" in order to accomplish this. Their algorithm, described here, claims to satisfy the indistinguishability obfuscation property, although at a high cost: the algorithm requires the use of fully homomorphic encryption, a highly inefficient construction that incurs roughly a one-billion-fold computational overhead. - -If this construction can be made better, the potential benefits are massive. The most interesting possibility in the world of cryptocurrency is the idea of an on-blockchain contract containing private information. This basically allows for the scripting properties of Turing-complete blockchain technologies, such as Ethereum, to be exported into any other financial or non-financial system on the internet; for example, one can imagine an Ethereum contract which contains a user's online banking password, and if certain conditions of the contract are satisfied the contract would initiate an HTTPS session with the bank, using some node as an intermediary, and log into the bank account with the user's password and make a specified withdrawal. Because the contract would be obfuscated, there would be no way for the intermediary node, or any other player in the blockchain, to modify the request in-transit or determine the user's password. The same trick can be done with any other website, or much more easily with a "dumb" blockchain such as Bitcoin. - -**Problem**: create a reasonably efficient indistinguishability obfuscation algorithm. - -**Additional Assumptions and Requirements** - -* Successful attacks must have an expected runtime above 2^80 -* The algorithm should be sufficiently fast that a standard ECDSA signature or an AES encryption should be feasible within 108 computational steps (more specifically, 108 gas in the Ethereum VM) - -### 5. Hash-Based Cryptography - -One of the looming threats on the horizon to cryptocurrency, and cryptography in general, is the issue of quantum computers. Currently, the problem does not seem too severe; all quantum computers are either "adiabatic quantum computers", effective at only an extremely limited set of problems and perhaps not even better than classical computers at all, or machines with a very small number of qubits not capable of factoring numbers higher than 35. In the future, however, quantum computers may become much more powerful, and the recent revelations around the activities of government agencies such as the NSA have sparked fears, however unlikely, that the US military may control a quantum computer already. With this in mind, the movement toward quantum-proof cryptography has become a somewhat higher priority. - -To date, all quantum-proof schemes fall into one of two categories. First, there are algorithms involving lattice-based constructions, relying on the hardness of the problem of finding a linear combination of vectors whose sum is much shorter than the length of any individual member. These algorithms appear to be powerful, and relatively efficient, but many distrust them because they rely on complicated mathematical objects and relatively unproven assumptions. However, there is also another class of algorithms that are quantum-proof: hash-based algorithms. One example of this is the classic Lamport signature: create a Merkle tree of 164 nodes (a figure chosen specifically to match 160 bits of security), publish the root, and then have the signature of a document be the combined Merkle tree proof of a subset of 82 nodes pseudorandomly chosen based on the hash of the document. This signature is one-time, and bulky (~3000 bytes), but fulfils the purpose. - -The question is, can we do better? There is an approach known as hash ladders, allowing the size of a signature to be brought down to 420 bytes, and one can use Merkle trees on another level to increase the number of signatures possible, although at the cost of adding 100-300 bytes to the signature. However, even still these approaches are imperfect, and if hash-based cryptography is to be competitive the properties of the algorithms will need to be substantially improved in order to have nicer properties. - -**Problem**: create a signature algorithm relying on no security assumption but the random oracle property of hashes that maintains 160 bits of security against classical computers (ie. 80 vs. quantum due to Grover's algorithm) with optimal size and other properties. - -**Requirements And Additional Assumptions** - -* The computational effort of producing a signature should be less than 224 computational steps, assuming a hash takes 28 steps (a reasonable assumption due to hardware optimizations and in the future hashing ASICs built into chips) -* The size of a signature should be as small as possible -* The size of a public key should be as small as possible -* The signature algorithm should be scalable to add any number of uses, although likely at the cost of adding a constant number of bytes per signature for every 2x increase in the maximum number of uses, and if possible the setup time should be sublinear in the number of uses. - -## Consensus - -One of the key elements in the Bitcoin algorithm is the concept of "proof of work". In any Byzantine-fault-tolerant system, the security level is often defined as the minimum percentage of hostile nodes - for example, in the context of secret sharing, the Berlekamp-Welch algorithm with 2x redundancy is guaranteed to provide the correct output assuming that the total number of hostile nodes does not exceed 25% of the network, and in the context of Bitcoin mining the requirement is that the size of the set of honest nodes exceeds the size of any individual hostile coalition. However, all of these security guarantees have one important qualification: there must be some way to define what an individual node is. Before Bitcoin, most fault-tolerant algorithms had high computational complexity and assumed that the size of the network would be small, and so each node would be run by a known individual or organization and so it is possible to count each node individually. - -With Bitcoin, however, nodes are numerous, mostly anonymous, and can enter or leave the system at any time. Unless one puts in careful thought, such a system would quickly run into what is known as a Sybil attack, where a hostile attacks simply creates five times as many nodes as the rest of the network combined, whether by running them all on the same machine or rented virtual private server or on a botnet, and uses this supermajority to subvert the network. In order to prevent this kind of attack, the only known solution is to use a resource-based counting mechanism. For this purpose, Bitcoin uses a scheme known as proof-of-work, which consists of solving problems that are difficult to solve, but easy to verify. The weight of a node in the consensus is based on the number of problem solutions that the node presents, and the Bitcoin system rewards nodes that present such solutions ("miners") with new bitcoins and transaction fees. - -Bitcoin's proof of work algorithm is a simple design known as Hashcash, invented by Adam Back in 1995. The hashcash function works as follows: - - def hashcash_produce(data, difficulty): - nonce = random.randrange(2**256) - while sha256(data + str(nonce)) > 2**256 / difficulty: - nonce += 1 - return nonce - - def hashcash_verify(data, nonce, difficulty): - return sha256(data + str(nonce)) <= 2**256 / difficulty - -Note that in the actual Bitcoin protocol nonces are limited to 32 bits; at higher difficulty levels, one is required to also manipulate transaction data in the block as a sort of "extranonce". - -Originally, the intent behind the Bitcoin design was very egalitarian in nature. Every individual would mine on their own desktop computer, producing a highly decentralized network without any point of control and a distribution mechanism that spread the initial supply a BTC across a wide number of users. And for the first 18 months of Bitcoin's existence, the system worked. In the summer of 2010, however, developers released a Bitcoin miner that took advantage of the massive parallelization offered by the graphics processing unit (GPU) of powerful computers, mining about 10-50 times more efficiently than CPUs. In 2013, specialization took a further turn, with the introduction of devices called "application-sepcific integrated circuits" - chips designed in silicon with the sole purpose of Bitcoin mining in mind, providing another 10-50x rise in efficiency. CPU and GPU mining are now completely unprofitable, and the only way to mine is to either start a multimillion-dollar ASIC manufacturing company or purchase an ASIC from one that already exists. - -Another related issue is mining pool centralization. Theoretically, the legitimate function of a mining pool is simple: instead of mining on their own and receiving a small chance of earning the block reward of 25 BTC, miners mine for a pool, and the pool sends them a proportionate constant payout (eg. 0.002 BTC per block). There are centralized mining pools, but there are also P2P pools which serve the same function. However, P2P pools require miners to validate the entire blockchain, something which general-purpose computers can easily do but ASICs are not capable of; as a result, ASIC miners nearly all opt for centralized mining pools. The result of these trends is grim. Right now, nearly 25% of all new ASIC hashpower is produced in a single factory in Shenzhen, and nearly 50% of the network is controlled by a single mining pool. - -The second problem is easy to alleviate; one simply creates a mining algorithm that forces every mining node to store the entire blockchain. The first problem, that of mining centralization, is much harder. There is the possibility that the problem will solve itself over time, and as the Bitcoin mining industry grows it will naturally become more decentralized as room emerges for more firms to participate. However, that is an empirical claim that may or may not come to pass, and we need to be prepared for the eventuality that it does not. Furthermore, the wasted energy and computation costs of proof of work as they stand today may prove to be entirely avoidable, and it is worth looking to see if that aspect of consensus algorithms can be alleviated. - -### 6. ASIC-Resistant Proof of Work - -One approach at solving the problem is creating a proof-of-work algorithm based on a type of computation that is very difficult to specialize. One specific ideas involves creating a hash function that is "memory-hard", making it much more difficult to create an ASIC that achieves massive gains through parallelization. This idea is simple, but fundamentally limited - if a function is memory-hard to compute, it is also generally memory-hard to verify. Additionally, there may be ways to specialize hardware for an algorithm that have nothing to do with hyperparallelizing it. Another approach involves randomly generating new mining functions per block, trying to make specialization gains impossible because the ASIC ideally suited for performing arbitrary computations is by definition simply a CPU. There may also be other strategies aside from these two. - -Ultimately, perfect ASIC resistance is impossible; there are always portions of circuits that are going to be unused by any specific algorithm and that can be trimmed to cut costs in a specialized device. However, what we are looking for is not perfect ASIC resistance but rather economic ASIC resistance. Economic ASIC resistance can be defined as follows. First of all, we note that in a non-specialized environment mining returns are sublinear - everyone owns one computer, say with N units of unused computational power, so up to N units of mining cost only the additional electricity cost, whereas mining beyond N units costs both electricity and hardware. If the cost of mining with specialized hardware, including the cost of research and development, is higher per unit hashpower than the cost of those first N units of mining per user then one can call an algorithm economically ASIC resistant. - -For a more in-depth discussion on ASIC-resistant hardware, see [https://blog.ethereum.org/2014/06/19/mining/](https://blog.ethereum.org/2014/06/19/mining/) - -**Problem**: Create two functions, `PoWProduce(data,diff) -> nonce` and `PoWVerify(data,nonce,diff) -> { 0, 1 }`, to serve as alternatives to Hashcash such that it is economically unattractive to produce an ASIC for `PoWProduce` - -**Additional Assumptions And Requirements**: - -* `PoWProduce` must have expected runtime linear in `diff` -* `PoWVerify` must have runtime at most polylogarithmic in `diff` -* Running `PoWProduce` should be the most efficient, or very close to the most efficient, way to produce values that return `1` when checked with `PoWVerify` (ie. no software optimization) -* `PoWProduce` must not be superlinear in computational power or time; that is to say, the expected number of successful `PoWProduce` computations for a node with `N` dollars worth of hardware after `t` seconds should be bounded by `kNt` for some `k`. Furthermore, the linearity should kick in quickly; ie. $1000 worth of mining hardware should function with over 90% efficiency. -* It should be shown with reasonably rigorous technological and economic analysis that the algorithm is economically ASIC resistant. - -### 7. Useful Proof of Work - -Another related economic issue, often pointed out by detractors of Bitcoin, is that the proof of work done in the Bitcoin network is essentially wasted effort. Miners spend 24 hours a day cranking out SHA256 (or in more advanced implementations Scrypt) computations with the hopes of producing a block that has a very low hash value, and ultimately all of this work has no value to society. Traditional centralized networks, like Paypal and the credit card network, manage to get by without performing any proof of work computations at all, whereas in the Bitcoin ecosystem about a million US dollars of electricity and manufacturing effort is essentially wasted every day to prop up the network. - -One way of solving the problem that many have proposed is making the proof of work function something which is simultaneously useful; a common candidate is something like Folding@home, an existing program where users can download software onto their computers to simulate protein folding and provide researchers with a large supply of data to help them cure diseases. The problem is, however, that Folding@home is not "easy to verify"; verifying the someone did a Folding@home computation correctly, and did not cut corners to maximize their rounds-per-second at the cost of making the result useless in actual research, takes as long as doing the computation oneself. If either an efficiently verifiable proof-of-computation for Folding@home can be produced, or if we can find some other useful computation which is easy to verify, then cryptocurrency mining could actually become a huge boon to society, not only removing the objection that Bitcoin wastes "energy", but even being socially beneficial by providing a public good. - -Note that there is one major concern with this approach that has been identified: if the useful PoW is implemented incorrectly, it can potentially reduce the cost of an attack on the network. If the useful PoW is useful in such a way that it is sometimes economically viable for certain very large entities to perform the computation even without the currency incentive, then those entities have an incentive to launch attacks against the network at no cost, since they would be performing the computations anyway. One simple, though crude and imperfect, way of addressing this problem is to make the PoW a half-and-half mix between useful and useless, making the cost of an attack at least 50% of what it would be in a useless-PoW environemnt. In practice, the overhead of making PoW verifiable may well introduce over 2x inefficiency unintentionally. Another economic solution is to make the computation a "pure" public good such that no individual entity derives a significant benefit from it. Proposed solutions to this problem should include a rigorous analysis of this issue. - -**Problem**: Create two functions, `PoWProduce(data,diff) -> nonce` and `PoWVerify(data,nonce,diff) -> { 0, 1 }`, to serve as alternatives to Hashcash such that the outputs of `PoWProduce` are independently useful. - -**Requirements** - -* `PoWProduce` must have expected runtime linear in `diff` -* `PoWVerify` must have expected runtime at most polylogarithmic in `diff` -* Running `PoWProduce` should be the most efficient way to produce values that return `1` when checked with `PoWVerify` -* `PoWProduce` must not be superlinear in computational power or time; that is to say, the expected number of successful `PoWProduce` computations for a node with `N` dollars worth of hardware after `t` seconds should be bounded by `kNt` for some `k`. Furthermore, the linearity should kick in quickly; ie. $1000 worth of mining hardware should function with over 90% efficiency. -* `PoWProduce` must produce a public good, such that the total value to everyone of the public good produced is greater than the cost of all resources invested into the mining process. -* The system must be able to exist without a trusted third party, but it is reasonable to allow a trusted third party to serve as a data source for useful computations. If the trusted third party acts maliciously in any way, the public good may be negated but the blockchain mining should not be compromised. - -### 8. Proof of Stake - -Another approach to solving the mining centralization problem is to abolish mining entirely, and move to some other mechanism for counting the weight of each node in the consensus. The most popular alternative under discussion to date is "proof of stake" - that is to say, instead of treating the consensus model as "one unit of CPU power, one vote" it becomes "one currency unit, one vote". - -A very simple proof of stake algorithm requires the miner mining the block to sign it with the private key to the address holding their coins, where the block is valid if `sha256(PREVHASH + ADDRESS + TIMESTAMP) <= 2^256 * BALANCE / DIFFICULTY` where `PREVHASH` is the hash of the previous block, `ADDRESS` is the signer's address with balance `BALANCE`, `TIMESTAMP` is the current Unix time in seconds and `DIFFICULTY` is an adjustable parameter to regulate the frequency of successful signatures. At first glance, this algorithm has the basic required properties: every miner has some random chance per second of succeeding, and if your address has twice as much money in it then you have double the chance of success. - -However, this algorithm has one important flaw: there is "nothing at stake". In the event of a fork, whether the fork is accidental or a malicious attempt to rewrite history and reverse a transaction, the optimal strategy for any miner is to mine on every chain, so that the miner gets their reward no matter which fork wins. Thus, assuming a large number of economically interested miners, an attacker may be able to send a transaction in exchange for some digital good (usually another cryptocurrency), receive the good, then start a fork of the blockchain from one block behind the transaction and send the money to themselves instead, and even with 1% of the total stake the attacker's fork would win because everyone else is mining on both. - -Another problem to keep in mind is the issue of so-called "long-range attacks" - attacks where the miner attempts to start a fork not five or ten blocks behind the head of the main chain, as happens normally, but hundreds of thousands of blocks back. If an algorithm is designed incorrectly, it may be possible for an attacker to start from that far back, and then mine billions of blocks into the future (since no proof of work is required), and new users would not be able to tell that the blockchain with billions of blocks more is illegitimate. This can generally be solved with timestamping, but special corner cases do tend to appear in overcomplicated designs. - -The Slasher algorithm, described [here](http://blog.ethereum.org/2014/01/15/slasher-a-punitive-proof-of-stake-algorithm/) and implemented by Zack Hess as a proof-of-concept [here](https://github.com/zack-bitcoin/slasher), represents my own attempt at fixing the nothing-at-stake problem. The core idea is that (1) the miners for each block are determined ahead of time, so in the event of a fork a miner will either have an opportunity to mine a given block on all chains or no chains, and (2) if a miner is caught signing two distinct blocks with the same block number they can be deprived of their reward. The algorithm is viable and effective, but it suffers from two flaws of unknown significance. First, if all of the miners for a given block learn each other's identities beforehand, they can meet up and collude to shut down the network. Second, the nothing-at-stake problem remaing for attacks going back more than 3000 blocks, although this is a smaller issue because such attacks would be very obvious and can automatically trigger warnings. - -For a more in-depth discussion on proof of stake, see [https://blog.ethereum.org/2014/07/05/stake/](https://blog.ethereum.org/2014/07/05/stake/) - -**Problem**: create a proof-of-stake algorithm that solves the nothing-at-stake problem and long-range attack problems, without introducing new collusion risks that require less than 25% of stakeholders to succeed. - -**Additional Requirements And Assumptions** - -* The expected return from mining should be bounded by `k` times the miner's stake for some `k`, and assuming $1 billion total participating stake a stake of $1000 should be able to reach 90% of this maximum efficiency. -* The algorithm should be fully incentive-compatible, addressing the double-voting issue defined above and the collusion issue defined above at both short and long range. - -### 9. Proof of Storage - -A third approach to the problem is to use a scarce computational resource other than computational power or currency. In this regard, the two main alternatives that have been proposed are storage and bandwidth. There is no way in principle to provide an after-the-fact cryptographic proof that bandwidth was given or used, so proof of bandwidth should most accurately be considered a subset of social proof, discussed in later problems, but proof of storage is something that certainly can be done computationally. An advantage of proof-of-storage is that it is completely ASIC-resistant; the kind of storage that we have in hard drives is already close to optimal. - -The most simple algorithm for proving that you own a file with `N` blocks is to build a Merkle tree out of it, publish the root, and every `k` blocks publish a Merkle tree proof of the `i`th block where `i` is the previous block hash mod `N`. However, this algorithm is limited because it is only a simple building block, not a complete solution. In order to turn this into a currency, one would need to determine which files are being stored, who stores whose files, to what extent and how the system should enforce redundancy, and if the files come from the users themselves how to prevent compression optimizations and long-range attacks. - -Currently, the latest work in this area are two projects called Permacoin and Torcoin, which solve some of the problems in proof of storage with two insights. First, users should not be able to choose which files they store. Instead, files should be randomly selected based on their public key and users should be required to store ALL of the work assigned or else face a zero reward. This idea, provided in the context of proof of bandwidth in the case of Torcoin, prevents attacks involving users only storing their own data. Second, a Lamport-like signature algorithm can be used that requires users to have their private key and store their file locally; as a result; uploading all of one's files to the cloud is no longer a viable strategy. This, to some degree, forces redundancy. - -However, the problem with Permacoin is that it leaves unclear what files should be stored; cryptocurrency issuance can theoretically pay for billions of dollars of work per year, but there is no single static archive whose storage is worth billions. Ideally, the system would allow for new files to be added, and perhaps even allow users to upload their own files, but without introducing new vulnerabilities. - -**Problem**: create a currency that uses proof-of-storage as its consensus and distribution algorithm. - -**Additional Assumptions And Requirements** - -* The currency must be future-proof, being able to expand the amount of data stored over time; the system should not eventually fall into some failure state if hard disk space continues to get cheaper and more efficient. -* The currency should ideally be maximally useful. At the least, the currency should allow people to upload their own files and have them stored, providing an uploading network with minimal cryptographic overhead, although ideally the currency should select for files that are public goods, providing net total value to society in excess of the number of currency units issued. -* The expected return from mining should be at most slightly superlinear, ie. it must be bounded by `ks/(1-s)` for some `k`, where `s` is the miner's share of the total network, although perfect linearity is ideal. -* The system should be maximally resistant against mining pool centralization as a result of any small degree of superlinearity. -* The system should be secure against nothing-at-stake and long-range attacks. -* The system should be secure against attacker involving users uploading specially formatted files or storing their own data. - -## Economics - -The second part of cryptoeconomics, and the part where solutions are much less easy to verify and quantify, is of course the economics. Cryptocurrencies are not just cryptographic systems, they are also economic systems, and both kinds of security need to be taken into account. Sometimes, cryptographic security may even be slightly compromised in favor of an economic approach - if a signature algorithm takes more effort to crack than one could gain from cracking it, that is often a reasonable substitute for true security. At the same time, economic problems are also much more difficult to define. One cannot usually definitively know whether or not a problem has been solved without extensive experimentation, and the result will often depend on cultural factors or the other organizational and social structures used by the individuals involved. However, if the economic problems can be solved, the solutions may often have reach far beyond just cryptocurrency. - -### 10. Stable-value cryptoassets - -One of the main problems with Bitcoin is the issue of price volatility. The value of a bitcoin often experiences very large fluctuations, rising or falling by as much as 25% in a single day and 3x in a month. The main economic reason behind this is that the supply of bitcoins is fixed, so its price is directly proportional to demand (and therefore, by efficient market hypothesis, the expected discounted future demand), and demand is very unpredictable. It is not known if Bitcoin will be simply a niche payment method for transcations requiring a high degree of privacy, a replacement for Western Union, a mainstream consumer payment system or the reserve currency of the world, and the expected value of a bitcoin differs over a thousandfold between these various levels of adoption. Furthermore, the utility of the Bitcoin protocol is heavily dependent on the movements of the Bitcoin price (ie. people are interested in Bitcoin more if the price is going up), creating a positive feedback loop, which has arguably been responsible for both Bitcoin's great meteoric rises and its many-month-long periods of rapid decline. - -To solve this problem, there are generally two paths that can be taken. The first is to have the network somehow detect its current level of economic usage, and have a supply function that automatically increases supply when usage increases. This reduces uncertainty; even though the expected future level of adoption of the protocol may have a variance of 10-100x, the circumstance where adoption increases 100x will also have 100x more supply and so the value of the currency will remain the same. There is a problem that if usage decreases there is no way to remove units from circulation, but even still the lack of upward uncertainty should reduce upward volatility, and downward volatility would also naturally reduce because it is no longer bad news for the value of the currency when an opportunity for increased usage is suddenly removed. Furthermore, in the long term the economy can be expected to grow, so the zero-supply-growth floor may not even ever be reached in practice. - -The problem is that measuring an economy in a secure way is a difficult problem. The most obvious metric that the system has access to is mining difficulty, but mining difficulty also goes up with Moore's law and in the short term with ASIC development, and there is no known way to estimate the impact of Moore's law alone and so the currency cannot know if its difficulty increased by 10x due to better hardware, a larger user volume or a combination of both. Other metrics, such as transaction count, are potentially gameable by entities that want the supply to change in a particular direction (generally, holders want a lower supply, miners want a higher supply). - -Another approach is to attempt to create a currency which tracks a specific asset, using some kind of incentive-compatible scheme likely based on the game-theoretic concept of Schelling points, to feed price information about the asset into the system in a decentralized way. This could then be combined with a supply function mechanism as above, or it can be incorporated into a zero-total-supply currency system which uses debts collateralized with other cryptographic assets to offset its positive supply and thus gain the ability to grow and shrink with changes to usage in either direction. The problem here is constructing the scheme in such a way that there is no incentive for entities to feed in false price information in order to increase or decrease the supply of the asset in their favor. - -**Problem**: construct a cryptographic asset with a stable price. - -**Requirements** - -* The expected root-mean-square daily change in the logarithm of the price of the asset should be less than 25% of that of Bitcoin under similar conditions. Ideally, the asset should be guaranteed to almost always maintain a value within 10% of an arbitrary cryptographic or real-world asset for which price information is easily accessible -* The expectation analysis should take into account black swan risks (ie. systems where the variance is 0% 99% of the time but 10x in a day the other 1% of the time are unacceptable) -* The solution must come with a model, including parameters such as short-term-consumption purchases, medium-term purchases, speculative purchases, positive and negative media, adoption and regulatory events, irrational actors and actors with political motives, show that their model well fits the history of Bitcoin and potentially major altcoins without overfitting, and show that under the model the other two requirements hold -* Zero-total-supply assets, ie. assets where each unit is balanced by a collateralized debt of a unit, are allowed, although such systems must include a robust margin-calling mechanism because it is assumed that most users are anonymous and can therefore trivially run away from debts - -### 11. Decentralized Public Goods Incentivization - -One of the challenges in economic systems in general is the problem of "public goods". For example, suppose that there is a scientific research project which will cost $1 million to complete, and it is known that if it is completed the resulting research will save one million people $5 each. In total, the social benefit is clear: if everyone contributes $1, then each individual person will see a benefit of $5 - $1 = $4 for $4 million total. However, the problem is that from the point of view of each individual person contributing does not make sense - whether or not you contribute has close to zero bearing on whether enough money will be collected, so everyone has the incentive to sit out and let everyone else throw their money in, with the result that no one does. - -So far, most problems to public goods have involved centralization; some large organization, whether a big company or a government, agrees to offer some of its private services only to those individuals who participate in paying for the public good. Often this is done implicitly: for example, some of the money from each purchase of an iPad goes toward research and development (some of which is a public good, and some of which is an excludable "club good"). At other times, it's more explicit, as in the case of taxation. In order for decentralized economic systems (we'll refer to decentralized economic systems that somehow rely on cryptography and/or cryptocurrency as "cryptoeconomic systems") to be effective, ways of incentivizing production of public goods relevant to that system are required. A few possible approaches include: - -* **Assurance contracts** - the idea behind an assurance contract is that `N` people may or may not put their funds into a pool, where that pool pays to produce a public good if and only if at least $X in total is contributed. Otherwise, the pool pays everyone back. If the pool creator acts optimally, the tipping point will be right at the top of the bell curve that is the probability distribution for how much other people might contribute, meaning that the chance that one user with their contribution of `X/N` will be pivotal should, by central limit theorem, approach `~1/sqrt(N)`, creating a `sqrt(N)`-sized amplifying effect on their donation. -* **Dominant assurance contracts** - a special type of assurance contract, called a dominant assurance contract, involves an entrepreneur that pays all contributors back slightly more than 100% of what they put in if the fund fails to reach its target (and takes profits if the fund succeeds); this provides an incentive for someone to create optimally targeted assurance contracts. -* **Currency issuance** - a cryptoeconomic system can contain its own currency or token system which is somehow necessary or useful in some part of the system. These currency units can then either be generated by the system and then sold or directly assigned to reward contribution. This approach gets around the free-rider problem because no one needs to pay the $1 explicitly; the value arises out of the emergent value of the network which is does not cost people to support. -* **Status goods issuance** - a status good can be defined as a good that confers only relative benefit to its holder and not absolute benefit to society; for example, you may stand out in the public if you wear an expensive diamond necklace, but if everyone could trivially obtain such a necklace the situation would be very similar to a world with no diamond necklaces at all. A cryptoeconomic system can release its own status goods, and then sell or award them. One example of a status good is a "badge"; some online forums, for example, show a special badge beside users that have contributed funds to support the forum's development and maintenance. Another important example of a status good is a namespace; for example, a decentralized messaging protocol may be able to fund itself by selling off all of the 1-4 letter usernames. -* **Recursive rewarding** - this is in some ways a mirror image of the concept of "recursive punishment" that arguably underlies a large number of social protocols. For example, consider the case of tax-funded police forces. In natural circumstances, there often arise opportunities to take actions which are beneficial to the perpetrator, but ultimately harmful to society as a whole (eg. theft). The most common solution to this problem is punishment - an act which is harmful in itself, but which shifts the incentives so that attacking is no longer beneficial to the perpetrator. However, there is a problem: there is no incentive to participate in the punishment process. This is solved by making punishment obligatory, with non-participation (in modern society by paying taxes) itself punishable by the same mechanism. Recursive rewarding is a mirror image of this strategy: here, we reward a desirable action, and people who partivipate in the rewarding mechanism (eg. by giving reward recipients a discount in shops) are themselves to be rewarded. - -Many of these approached can arguably be done in concert, or even simultaneously within one mechanism. - -**Problem**: come up with and implement methods for incentivizing public goods production in a decentralized environment. - -**Additional Assumptions And Requirements** - -* A fully trustworthy oracle exists for determining whether or not a certain public good task has been completed (in reality this is false, but this is the domain of another problem) -* The agents involved can be a combination of individual humans, teams of humans, AIs, simple software programs and decentralized cryptographic entities -* A certain degree of cultural filtering or conditioning may be required for the mechanism to work, but this should be as small as possible -* No reliance on trusted parties or centralized parties should be required. Where some kind of "supernode" role does exist, the protocol should provide a way for anyone to participate in that function with a mechanism for rewarding those who do it well -* The mechanism should ideally be able to handle both public goods which everyone values and public goods which are only valued by a small portion of the population (eg. the production of a freely available book or video on a specific topic) - -### 12. Reputation systems - -A concept which can arguably be considered to be a mirror image of currency is a reputation system. A reputation system serves three functions. First of all, it provides a mechanism for filtering honest people from dishonest people. Different people have different moral preference profiles, and so individuals who cheat less in one context are less likely to cheat in another context. Second, it provides an incentive not to cheat. If an individual can be said to possess a reputation of value `R`, and he enters a business deal where he is receiving payment `V` in exchange for a product with cost-of-production `C`, then as long as `R > C` the reputation system removes the incentive to run away with the money because doing so would sacrifice the reputation. Finally, reputation can be thought of as a kind of point system that people value intrinsically, both in a private context and as a status good in comparison with others. - -Money serves functions that are very similar. People who are willing to spend more money on something tend to want it more, creating a filtering function ensuring efficient resource consumption on the demand side. It provides an incentive not to cheat by consuming and not producing, because if you do so your remaining currency units and thus ability to consume in the future will go down. And finally, it is also very much an intrinsically valued point system; in fact, some argue that among very wealthy individuals this function of money is dominant. - -However, there are also differences. First, money is an absolute score - I have X units of currency C from the point of view of everyone in the world - but reputation is a relative measure, depending on both the owner of the reputation and the observer. I may have a high reputation in North America, a near-zero reputation in Africa, and a negative reputation among certain kinds of antitechnologist and ultranationalist groups. Second, reputation is free to give; it does not cost me anything to praise you, except potentially moral liability that I may incur if you turn out to act immorally in some way. This is in contrast with money, where adding X units to A means subtracting X units from B. - -However, up until very recently, reputation has been a very informal concept, having no concept of score and instead relying entirely on individual opinion. Because opinion is relatively easy to manipulate, this means that reputation as a concept has been highly suboptimal in its implementation, and has been quite vulnerable to informational and psychological attacks. Some specific problems are: - -1. How do we know how what the value of someone's reputation with someone else is after a particular number of interactions? A common attack on informal reputation systems is the "long con" - act honestly but passively and cheaply for a very long time, accumulate trust, and then suddenly go all out and destructively capitalize on one's reputation as much as possible. The initial dormant phase is cheap for the attacker, but ends up resulting in the attacker accumulating a disproportionately large amount of trust for the community and thereby ultimately causing much more damange than good. Overcompensate for this too much, however, and there ends up being no opportunity to gain trust. -2. How do we incorporate secondary trust? In general, when `A` is deciding whether or not to trust `B`, `A` has not had any prior dealings with `B`, and therefore has no way of knowing whether or not `B` is trustworthy. One approach is to just look at all ratings for `B`, but then we run into the issue of Sybil attacks: what if `B` creates 50000 fake users, all of whom rate each other highly, to give good ratings to him? To solve this problem, reputation systems rely on a fallback known as a web of trust: find some chain of people `P[1] ... P[k]` such that `A` trusts `P[1]`, `P[i]` trusts `P[i+1]` for all `i`, and `P[k]` trusts `B`. Under the "six degrees of separation hypothesis", any two people in the world except those completely disconnected from society have such a chain of maximum length `k = 5` (so at most six hops total). However, the question arises, if `A` has a certain rating for `P[1]` and `P[1]` has a certain rating for `B`, what should the reputation system recommend to `B`? -3. If a reputation system becomes more formalized, are there market attacks that reduce its effectiveness to simply being just another form of money? Specifically, how would a reputation system where giving reputation is free handle users multiplying their reputation with millions of "I praise you if you praise me" trades? Will such trades need to be explicitly banned, punishable by loss of reputation, or is there a better solution? -4. How do we deal with double use attacks? Specifically, suppose that `A` has a reputation with value `R = $1000`. Using this reputation, `A` has a business dealing where `P[1]` trusts her for $600. Then, she simultaneously engages in such a dealing with `P[2], P[3] ... P[10]`, each of whom individually believe that `A` will not betray them since $600 < $1000, and then runs away with $6000 taking the $1000 hit from the value of her reputation. How do we prevent such fractional reserve-like scenarios? - -**Problem**: design a formalized reputation system, including a score `rep(A,B) -> V` where `V` is the reputation of `B` from the point of view of `A`, a mechanism for determining the probability that one party can be trusted by another, and a mechanism for updating the reputation given a record of a particular open or finalized interaction. - -Note that for the purpose of this use case we are targeting specifically the "can I trust you" use case of reputation, and not the social-incentivizing "[whuffie](https://en.wikipedia.org/wiki/Whuffie)"-esque currency-like aspect. - -**Additional Assumptions and Requirements** - -* The system has access to a record of all finalized transactions inside the system and all transactions in progress, although entities are of course able to choose to make deals outside the system -* It is allowed to introduce mechanisms like charity donations, public goods provision and sacrifices as a way of increasing one's reputation. However, if non-monetary contributions are allowed, there needs to be some mechanism for measuring their value -* For simplicity, we can assume that interactions between two people are of the form "A pays, then B sends the product and A receives", with no possibility for loss beyond the principal (eg. food poisoning) or ambiguous quality. Ideally, however, the system should account for such possibilities. -* The system should continue to be reasonably accurate whether the parties involved are simple programs (eg. micropayment software protocols), more complicated AIs, DAOs, individual humans or human centralized or decentralized organizations -* If a mechanism is provided for determining the probability of a successful interaction, a success metric for the system can be defined as the sum over all transactions of `V * (S * log(p) - (1-S) * log(1-p))`, where `S = 1` if the transaction succeeded and `S = 0` if there was a registered complaint, `p` is the assigned probability and `V` is the value of the transaction. The objective is to maximize this metric. - -## Metrics - -In the world of cryptoeconomics, in order for something to be rewarded it must be measured. Some things are easy to measure; for example, just by looking at the string "dog5356356" and its SHA256 hash, `0000390f327fefc900...`, one can clearly see that around 216 SHA256 computations were done to produce it. Other computational results that cannot be verified so quickly can be easily measured competitively using challenge-response protocols, where different parties are incentivized to find errors in each other's proofs. Results to mathematical problems are also usually easy to computationally verify. Other things, however, cannot be verified just by looking them; in that case, in both the real world and the cryptographic world, there is only one solution: social proof. - -To some extent, proof of work consensus is itself a form of social proof. Transaction A happened before transaction B because the majority of users say it did, and there is an economic incentive to go with the majority opinion (specifically, if you generate a block on the incorrect chain, that block will get discarded and the miner will receive no reward). Assuming that most participants act truthfully, the incentive is to go along with the projected majority and tell the truth as well. This insight can be extended into [SchellingCoin](http://blog.ethereum.org/2014/03/28/schellingcoin-a-minimal-trust-universal-data-feed/), a generalized data feed protocol, protocols for proof of bandwidth, and anything else that can be quickly verified. The challenge is, however, what if verification has a cost? What if it takes some effort to determine whether or not a certain thing has happened, or what if the information is in principle only available to a few people? If there is too much gathering cost or secrecy, then centralization becomes necessary; the question is, how high can we go? How much can we measure without any social proof at all, and how much can we measure without a centralized verifier? - -### 13. Proof of excellence - -One interesting, and largely unexplored, solution to the problem of distribution specifically (there are reasons why it cannot be so easily used for mining) is using tasks that are socially useful but require original human-driven creative effort and talent. For example, one can come up with a "proof of proof" currency that rewards players for coming up with mathematical proofs of certain theorems. There is no generic algorithm, aside from brute force, for proving theorems, and yet proofs of theorems are theoretically computationally easy to verify: one simply needs to write every step of the proof in a formal language, allowing the use of only one inference rule (eg. `a + b = b + a` or `a * (b + c) = a * b + a * c` but not `a * (b + c) = a * c + b * a`) between each step, and having a program verify the correctness of the inferences at each step. - -For example, a proof of a common algebraic factorization problem appears as follows: - - a^2 - b^2 - = a^2 - a*b + a*b - b^2 - = a*a - a*b + a*b - b^2 - = a*(a - b) + a*b - b^2 - = a*(a - b) + a*b - b*b - = a*(a - b) + b*a - b*b - = a*(a - b) + b*(a - b) - = (a + b)*(a - b) - -Each step of the proof can be verified using pattern matching algorithms, but it is much harder for a computer to figure out that the trick is to add and subtract `a*b` into the expression (technically, in this case specialized algorithms can do it, but in more general cases especially involving second-order logic it becomes intractable). Note that for computers the proof must be written down in excruciating detail; blockchain-based algorithms specifically heavily benefit from simplicity. To alleviate this problem, compilers can likely be made that can make small two and three-step inferences and expand shorter proofs into more complete ones. - -Alternatives to proof-of-proof include proof-of-optimization, finding optimal inputs to some function to maximize a particular output (eg. the ability of a radio antenna to receive signals), algorithms involving playing strategy games or multiplayer AI challenges (one can even require users to submit programs to the blockchain that play against each other), and solving a specific math problem at greater and greater difficulty (eg. factoring). Note that because success in these problems is very sporadic, and highly inegalitarian, one cannot use most of these algorithms for consensus; rather, it makes sense to focus on distribution. - -**Problem**: create a proof-of-excellence distribution mechanism that rewards solving problems that are both dominated by human effort and whose solutions provide some benefit to humanity. - -**Additional Assumptions and Requirements** - -* Given a well-justified extrapolation of the global levels of human and computer competence at the underlying problem, over 75% of the rewards from the system should be provided by human labor, although software aids are allowed. -* The algorithm must ideally be future-proof; that is to say, it must continue rewarding value production in the long term and should not be an area that will eventually be "solved" completely. -* The distribution should be maximally egalitarian, though this is a secondary concern. -* The system should be secure against front-running attacks, ie. if an individual submits a solution, then it should not be practical for even a moderately powerful attacker to look at the solution and then resubmit his own transaction containing the same solution and thereby steal the reward. - -### 15. Anti-Sybil systems - -A problem that is somewhat related to the issue of a reputation system is the challenge of creating a "unique identity system" - a system for generating tokens that prove that an identity is not part of a Sybil attack. The naive form of anti-Sybil token is simple: a sacrifice or proof of deposit. In a sacrifice setup, such identities simply cost $X, and in a PoD system identities require a deposit of $Y in order to be active, where perhaps the deposit can be taken away or destroyed under certain circumstances. However, we would like to have a system that has nicer and more egalitarian features than "one-dollar-one-vote"; arguably, one-person-one-vote would be ideal. - -To date, we have seen two major strategies for trying to solve this problem. One potential solution is to come up with a proof-of-work algorithm which is dominated by human labor, and not computers. This is not as difficult as it may seem; although computers get more and more powerful every year, there are a number of problems that have remained out of computers' reach for decades, and it may even be possible to identify a class of problems that are the artificial-intelligence-theoretic equivalent of "NP-complete" - problems such that, if they can be solved, it with high probability implies that AI can essentially replicate human activity in its entirety, in which case we are essentially in a post-scarcity utopia and money and incentivization may not even be necessary. These problems may be non-interactive challenges like CAPTCHAs, although all existing CAPTCHAs are far from adequate for the task, or they may be interactive strategy games like Go. - -The second strategy is to use social proof, turning the muscle of decentralized information gathering toward a simple problem: are these two identities the same person? If they are not, then they receive two anti-Sybil tokens, and if they are they receive one token. In general, we can separately define two concepts of identity: voluntary identity and involuntary identity. A voluntary identity can be seen as a cluster of interactions which are in some fashion correlated with each other; for example, a cryptographic identity consists of the set of interactions signed by a particular public key. An involuntary identity is a cluster of interactions which are correlated with each other, but where the entity producing the interactions does not want the correlations to be visible. A simple unique identity system would rely on voluntary identities embedded in social networks, with the understanding that creating separate identities with reputations is an expensive task and so most people would not want to do it, but a more advanced system may try to detect involuntary slipups like writing style patterns or IP addresses. - -The question is, can we use these mechanisms, either separately or together, and perhaps in combination with cryptoeconomic protocols and sacrifices as a fallback in order to create an anti-Sybil system which is highly egalitarian? We will accept that any scheme can be cracked at some cost; however, what we want is for it to be much more efficient for individuals to obtain _one_ anti-Sybil token "the proper way" rather than purchasing one off the grey/black market. The challenge is to push the grey/black market cost as high as possible, as much as possible without making the first token difficult. - -**Problem** - create a mechanism for distributing anti-Sybil tokens - -**Additional Assumptions and Requirements**: - -* Everyone is part of a social network with similar characteristics to social networks now found in the real world, and social data can be provably provided to cryptoeconomic systems (eg. blockchains, Ethereum contracts) -* The cost of obtaining one anti-Sybil token for a human should be as low as possible -* The cost of obtaining multiple anti-Sybil tokens for a human should be as high as possible -* The cost of obtaining anti-Sybil tokens for an automated system should be as high as possible (this is a more important criterion than high cost for multi-obtainment for humans) -* The system should not create dependency on centralized parties (eg. government passport offices) that have the power to cheat the system - -### 14. Decentralized contribution metrics - -Incentivizing the production of public goods is, unfortunately, not the only problem that centralization solves. The other problem is determining, first, which public goods are worth producing in the first place and, second, determining to what extent a particular effort actually accomplished the production of the public good. This challenge deals with the latter issue. Although in the case of computational tasks it's easy to come up with a proof of solution, for non-computational tasks the situation is much more difficult. If a cryptoeconomic system wants to incentivize users to build better graphical user interfaces to its own system, how would it rate people's contributions? [Even more problematically](http://en.wikipedia.org/wiki/Underhanded_C_Contest), what about potentially quasi-adversarial tasks like incentivizing updates to its own code? What about a DAO that funds healthcare, or tries to incentivize adopting renewable energy? - -This is a subclass of the general "social proof" problem; here, the particular challenge is that each individual datum in question is something that very few people are interested in, and data gathering costs are often high. Sometimes, there is not even a concept of a single "correct" value with respect to the particular metric; in the case of quality measurement for an interface, a solution like A/B testing may be required. In adversarial cases, there may need to be an opportunity for incentivized opponents to look at a solution and attempt to pick it apart. - -**Problem**: come up with and implement a decentralized method for determining whether or not a particular task was performed by a specific person, and for estimating the quality of the work - -**Additional Assumptions and Requirements** - -* The agents involved can be a combination of individual humans, teams of humans, AIs, simple software programs and other DAOs -* There is no cryptographically verifiable information about the completion of any task; the system must rely entirely on some form of social proof - -### 16. Decentralized success metrics - -Another, related, problem to the problem of decentralized contribution metrics is the problem of decentralized success metrics. On the macroscopic scale, how do we know if, and to what extent, an organization has succeeded in accomplishing its objectives? In the case of something like Bitcoin, there is a simple, but imperfect, answer: success can be measured by the hashpower of the network. This setup is reasonably effective, but is flawed in two ways: first, hashpower is an imperfect proxy for price, because the development or nondevelopment of ASICs may skew the results, and second, price is an imperfect proxy for success, because the currency may have greater success as something with a lower market capitalization if it is more used in other ways. In the case of a DAO funding healthcare or anti-climate-change efforts, however, no such heuristic exists at all. Once again, some concept of social proof is the only option. - -Here, information gathering costs are low, and information is accessible to everyone in the public, so a higher level of accuracy is possible, hopefully even enough for financial contracts based off of the metric to be possible. However, in order to maintain that higher level of accuracy, and in the presence of such financial derivatives, new problems arise. Can one moderately powerful entity manipulate the metric for their own benefit? If information gathering costs do exist, is the system vulnerable to falling into a centralized equilibrium, where everyone is incentivized to simply follow along with the actions of some specific party? - -**Problem**: come up with and implement a decentralized method for measuring numerical real-world variables - -**Additional Assumptions and Requirements** - -* The agents involved can be a combination of individual humans, teams of humans, AIs, simple software programs and other DAOs -* The system should be able to measure anything that humans can currently reach a rough consensus on (eg. price of an asset, temperature, global CO2 concentration \ No newline at end of file diff --git a/[Japanese]-Ethereum-Development-Tutorial.md b/[Japanese]-Ethereum-Development-Tutorial.md deleted file mode 100644 index 3d0c3f5c7..000000000 --- a/[Japanese]-Ethereum-Development-Tutorial.md +++ /dev/null @@ -1,249 +0,0 @@ ---- -name: Ethereum Development Tutorial -category: ---- - - このページの目的はコントラクトや分散アプリケーションを作成するために、開発の観点から理解する必要があるEthereumの基礎を紹介することです。Ethereumの全般的なイントロダクションについてはホワイトペーパー、完全な技術仕様についてはイエローペーパーが参考になりますが、このページを読むのに必須ではありません。アプリケーション開発者にとって、このページがそれらに代わるEthereumへの導入となり得ます。 - -### Introduction - - Ethereumは、ブロックチェーンを利用した分散型アプリケーション(DApps)を簡単にプログラムすることを目的としたプラットフォームです。DAppsとは、ユーザーに対し特定の目的のためを果たすアプリケーションですが、アプリケーション自体は既存の特定の管理者に依存しないという重要な特性を持っています。DAppsは、特定の管理者のサービスを提供するためのフロントエンドとして機能するのではなく、仲介業者なしで人や組織がやり取りするのためのツールです。 - - このDAppsというものは、特定のプラットフォームを提供し売り込むための開発環境というよりかはむしろ、(売り手と買い手などといった)違った立場にいる人間や機関が、中央集約型の媒介を無しにして取引、契約等(相互利用)をするための道具である。フィルタリングや第三者認証、紛争解決、個人認証業務のような典型的な「中央集約型の媒介」の業務でさえ、分散型ネットワークで扱うことが可能であり、参加者全員にオープンとなっており、内部トークンシステムとして評判の高いシステムをツールとして採用し、利用者に高品質なサービスを提供する。初期のDAppsの例としては、ファイルシェアアプリとしてBitTorrentが、通貨アプリとしてビットコインが含まれる。Ethereumは BittorentやBitcoinで使われたものや、P2Pネットワークやブロックチェーン技術を含む最初の進化版開発物(web3.0)といえよう。そして、開発者がこれらの技術を使いやすいように一般化したものだ。 - - Ethereumのブロックチェーンは(ビットコインに見られる単なる金銭記録データではなく)プログラミング言語が組み込まれたブロックチェーンというふうに説明できる。あるいは、大衆の思惑による決定(コンセンサス)を基板とした地球規模の仮想マシンとも言える。Ethereum仮想マシン(EVM)を参照してえられる部分的なプロトコルは、内部状態と計算を実際に処理する。実用的な観点からして、EVMは膨大な量のアカウント(というオブジェクト)を内部に保持する分散型コンピュータと考えることができ、このコンピュータでは各々のオブジェクトがそれぞれ内部コードとストレージという名前の32バイトのkey/valueデータベースを保持し、オブジェクトは他のオブジェクトを意のままに呼び出すことができる。 - 〜アカウントには2つのタイプがある〜 - オブジェクトの外側の世界からEVMを使用してアクセスすることができるアカウント(オブジェクト)として「外部所有アカウント(EOA,EOアカウント)」という名の特別なタイプがある。あるEOアカウントから他のどんなアカウントに対する「メッセージ」も、そのEOアカウントの秘密鍵で署名されたトランザクションを送ることが引き金となり、送ることが可能だ。EOアカウントでないものは「 契約、contract 」と呼ばれ、「メッセージ」の受け取り、自動的に内部コードを実行し、(自身のもつ内部ストレージに読み書きする能力を持つ。)受け取った「メッセージ」のストレージを読み取り、そして他の契約アカウントにメッセージを送る。(自分自身にも送ることができる。) ひとつの捉え方として、contract とは、契約を遂行するためのプログラミングコードだ。 - - contract はふつう、4つの目的 に分類できる。 - -1. データを維持する。 -他の契約アカウントや外の世界のアカウントにとって役立つ何かを表すデータ貯蔵を維持する。一例として、通貨をシミュレートした「 contract 」がある。他の例としては、ある特定の機関の構成員を記録する「 contract 」がある。 - -2. 「 EOアカウント 」に保持される。 -「 contract 」よりも複雑なアクセス制御がなされる「 EOアカウント 」に保持される。このコントラクトは「 先渡契約 forwarding contract 」と呼ばれる。これの典型的なものとして、「ある条件が整えば受信した「メッセージ」を送りたい場所へただ単に転送する」というものがある。例として「3つある秘密鍵のうち2つが、ある今送りたいメッセージが確約(コンファーム)するのを待ってから、メッセージを転送する」といった先渡契約をもつものが考えられる(「 multisig 」)。より複雑な先渡契約は送られたメッセージの形態に基づいて違った状態を取るというもので、この機能の最もシンプルな例として、より複雑なアクセス手順によって上書きされうる「引き出し制限」がある。(つまり複雑な手順の親クラス・あるいはインターフェースとしてEOアカウントに保持される) - -3. ユーザー間の契約内容や関係性を管理する。 - 金融契約における「第3者認証」が例としてわかりやすい。 - -4. ライブラリとして機能する。 - 他の契約によって呼び出される関数を格納しておく。 - - contract は、互いに「 呼出(calling)」や「 送信(sending message)」などと呼ばれる動作を通じて作用しあう。一通の「メッセージ」は、1.ある量のether 2.どんなサイズのデータを格納したバイト型配列 3.送受信者双方のアドレス を保持する。契約アカウントが、返り値としてあるデータを返す「メッセージ」を受信し、その返り値をメッセージの送り手がすぐに使用できるようなときは、「送信」とは、まさに、プログラミングにおける関数の履行である。 - - 以上に示したように、契約アカウントは異なる働きをし、それら同士が互いに作用しあうことが期待できる。例をあげよう。次のような状況を考えてみよう。 - アリスとボブが、「来年サンフランシスコの気温が35度を超えることはない」ということに100Gavcoin(開発者の名前が付けられた仮想通貨)の賭けをしたとしよう。しかし、アリスは危険回避思考の持ち主で、アリスの第一アカウントは、マルチシグをかけた「前進型契約」を保持している。ボブは量子暗号に猜疑的で(疑い深く)、伝統的な楕円曲線アルゴリズムに沿ったランポート署名を施したメッセージを転送する「前進型契約」を保持している(訳略)。この賭博を管理する契約アカウントはそれ自身サンフランシスコの気象データをあるコントラクトから呼び出してこないといけない。(以後、契約アカウントの呼び名として、プログラマであるわれわれがmethodのことをメソッドと呼ぶように、コントラクトと呼ぶことにする。コンストラクタ等と混同しないように別名がほしいところだが。)またGavCoinコントラクトともやりとりしなくてはならない。・・・ - 以下に図を示す。 - -![img](https://github.com/ethereumbuilders/GitBook/blob/master/en/vitalik-diagrams/contract_relationship.png) - - スタック上に積み上がっていくメソッドの呼び出し(コールスタック)を頭に思い描くことができれば、 -ここでの説明は容易であろう。 - -ボブが賭けを終了させたいと思った時、次のことが起こる: - -1. トランザクションが送信され、それが有効になると、ボブの EOA からボブの「 forwading contract 」へ message が送信される -2. ボブの「 forwading contract 」は message を受け取り、hash と ランポート署名 を「 ランポート署名検証 Library contract 」へ送信する -3. 「 ランポート署名検証 Library contract 」はボブがSHA256のランポート署名が欲しいことをみて、 SHA256 のライブラリを検証に必要な回数にわたって呼び続ける。 -4. 「 ランポート署名検証 Library contract 」が 1 を返すと、署名が有効であると署名し、message を「 bet contract 」に送信する -5. 「 bet contract 」は 「 サンフランシスコの気温を提供する Library contract 」 に値を要求する -6. 「 bet contract 」は返事をみて、値が 35 度以上であることを確認する。そこで「 Gavcoin contract 」に、Gavcoin を その account から ボブの「 forwarding contract 」に移動するよう message を送信する。 - -GavCoin はすべて Gavcion contract データベースの項目として "貯蔵" されていることに注意して欲しい。 -ステップ 6 の内容にある単語 "account" が意味するところは単に Gavcoin cocntract の中に、bet contract の address のための key と 残高 とともに、データ項目 があるということだ。 -この message を受信したあと、Gavcoin contract は自身の残高からある量の値を減らし、同じ分だけボブの forwarding contract への送信項目の値を増やす。以下のdiagramにこれらのステップを示した: - -![img](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/contract_relationship2.png?1) - -### State Machine - - Ethereum仮想マシンの計算処理は、ビットコインスクリプトと伝統的アセンブラやLispといったものの架け橋である、スタックベースのバイトコード言語を使用する。(Lispは再帰的コントラクト呼出の機能の役割を担う。)仮想マシン上のプログラムは以下のようなopcodesのシーケンスである。 - - PUSH1 0 CALLDATALOAD SLOAD NOT PUSH1 9 JUMPI STOP PUSH1 32 CALLDATALOAD PUSH1 0 CALLDATALOAD SSTORE - - この例が示すコントラクトの目的は、レジストリという名前をもつ contract として振る舞うことにある。誰でも64バイトのデータを含む「メッセージ」送付することができる。 32バイトは鍵keyに 32バイトは値valueにわり振られる。このレジストリcontractは、鍵がすでにストレージ内に登録されているかをチェックし、もし登録されていなければ、その鍵と共に値を登録する。 - - 実行中は、「メモリ」と呼ばれる無限拡張可能なバイト型配列、現在の指令の位置を指し示す「program counter」、および32バイトの値を格納したスタックが維持されている。実行の開始時、メモリとスタックは空で、PCは0である。さて、それでは、一番最初にアクセスされるこのコードと、123weiと、(値54,鍵2020202020) の64バイトのデータともに、contract についてみていこう。 - - -初期状態は: - - PC: 0 STACK: [] MEM: [], STORAGE: {} - -最初の命令は`PUSH1`で次の値である0をスタックにpushする。`PUSH1`は1バイトの値を扱う。よって以下のような状態に変わる: - - PC: 2 STACK: [0] MEM: [], STORAGE: {} - -2番目の命令である`CALLDATALOAD`では、スタックから値を一つ取り出し、そのアドレス先のデータの先頭32バイトのメッセージを取得し、その値をスタックに保存する(ここでは先頭の32ビットが54である)。よって以下のような状態に変わる: - - PC: 3 STACK: [54] MEM: [], STORAGE: {} - -次の命令の`SLOAD`はスタックから値を一つ取り出し、contractのstorageの参照先の値をスタックに保存する。今回初めてcontractは使用するため値が入っておらず、値は0が埋められる: - - PC: 4 STACK: [0] MEM: [], STORAGE: {} - -`NOT`スタックから値を取り出し、0であれば1を、それ以外は0をスタックに入れる: - - PC: 5 STACK: [1] MEM: [], STORAGE: {} - -次は`PUSH1`であるため、9をスタックに保存する: - - PC: 7 STACK: [1, 9] MEM: [], STORAGE: {} - -次の`JUMPI`命令では、スタックから2つの値を取り出し、二つ目の値が0でなければ、一つ目の値によって指定された命令へジャンプする。ここでは0でないのでジャンプする。もしストレージ内の54番目の値が0でなかったならば、スタックの二つ目の値が0になっているだろう。よって、この場合ジャンプできずに動作がここで終了する: - -次は`PUSH1`であるため、32をスタックに保存する. - - PC: 11 STACK: [32] MEM: [], STORAGE: {} - -次は再び`CALLDATALOAD`である。 スタックの32バイト目から63バイトまで値を取得しスタックに保存する: - - PC: 13 STACK: [2020202020] MEM: [], STORAGE: {} - -次は`PUSH1`で0をスタックに保存する: - - PC: 14 STACK: [2020202020, 0] MEM: [], STORAGE: {} - -そして再び0-31バイト目のデータを取得してスタックに保存する (なぜメモリに保存させて再利用しないかって?それはメモリからロードをする方が安上がりだからさ): - - PC: 16 STACK: [2020202020, 54] MEM: [], STORAGE: {} - -最後は`SSTORE`で、スタックから取り出した1番目の値を、ストレージ内の参照値とした場所へ、二つ目の値を格納する。よって以下の通りになる: - - PC: 17 STACK: [] MEM: [], STORAGE: {54: 2020202020} - - 17番目の指令は何も書かれていないので、ここでストップとなり、もし、スタックやメモリ上に何か残っていれば、消えてしまう。しかし、ストレージ内のデータは次回誰かが呼び出すときまで保存される。これと同じようにして、同じ送信者が同じメッセージを再び呼び出したとすると(あるいは別の誰かが、54番目に3030303030を登録しようと試みたとすると)これは、8番目の指令のところで動作が終了する。 - - 幸運なことに、低級アセンブラを君が扱う必要はない。 -LLLやSerpent、Mutanなどと言った数々の高級言語が存在し、コントラクトをもっと簡単に記述してくれる。これらの言語で書かれたどんな言語もEthereum仮想マシンにコンパイルされ、あなたがEVMバイトコードを含むトランザクション上で呼び出すコントラクトを作成する。 - - トランザクションには二つのタイプがある。 -「Ether送信トランザクション」と「コントラクト生成トランザクション」だ。 -Ether送信トランザクションとは標準的なトランザクションのことで、受信用アドレス、etherの額、バイト型配列のデータと他のパラメータを含み、秘密鍵による署名は送信者のアカウントに関連づけられている。「コントラクト生成トランザクション」は、受信用アドレスが空である点を除いて標準的なトランザクションと似ている。コントラクト生成トランザクションがブロックチェーンに自身を組み込むとき、トランザクションのバイト型配列のデータはEVMコードとして解釈され、EVMの実行による返り値が新しいコントラクトのコードとなる。このように、初期化の間中、ひとつのトランザクションにあることをやってもらうことができる。新しいコントラクトのアドレスは送信アドレスとそのアカウントが以前トランザクションを作成した回数に基づいて決定論的に計算される。(nonceと呼ばれるこの値もまた別のセキュリティの観点から保存される。)このように、上記のnameレジストリを生成するためにブロックチェーン上に載せる必要があるフルコードは以下のとおり: - - PUSH1 16 DUP PUSH1 12 PUSH1 0 CODECOPY PUSH1 0 RETURN STOP PUSH1 0 CALLDATALOAD SLOAD NOT PUSH1 9 JUMPI STOP PUSH1 32 CALLDATALOAD PUSH1 0 CALLDATALOAD SSTORE - - このopcodesを読み解く上での鍵はCODECOPYだ。今スタック上には[16,12,0]の順に積まれていて、コード配列の要素12(13番目)からスタートして、16バイト分をコピーしたものをメモリの0番地を起点としたところに貼り付け、今貼り付けられたメモリ上の0番目から16番目の値を返す。 -結果として、12(含まず)〜28番目のコードがこの一つのコードにより実行される。 - -### Gas - - 仮想マシンを動かす上で重要な側面がある。それは「仮想マシン内部で処理されるあらゆる単一操作は、実際はすべてのノード上で同時に実行される」ということだ。Ethereum1.0の必要なコンポーネントであり、「仮想マシン上のどんなコントラクトもほぼコスト0で他のあらゆるコントラクトを呼び出すことができる」といった恩恵をもたしてくれる。しかしながら、Ethereum仮想マシン上での計算処理のステップはとても高価なもとなる。Ethereum仮想マシンの使用方法の概要は、「1999年代以降のスマホでできないことは、ここでもできない。」とでもとらえておけばだいたい正しい。 -ビジネスロジックを走らせたり、署名やその他の暗号オブジェクトの有効化をしているEVMの正しい使用法として;EVMの使用法の上限としてあるのが、他のブロックチェーンの部分集合を有効化するアプリケーションだ。(例:分散型ether - bitcoin 両替所) 受け入れがたい使い道としては、ファイルストレージやEmailテキスト、メールシステム、画像処理インターフェースを用いて行うプログラムや遺伝的アルゴリズムや機械学習、グラフ探索などのcloud computingにベストマッチするアプリケーションなどだ。 - - 故意による攻撃や破壊を予防するため、Ethereumプロトコルは、一計算ステップあたりの使用料を徴収する。料金は市場に基づくものの、いざ動かしてみると強制力をともわすような設計がなされている。;ブロックひとつあたりに蓄えられるオペレーション数の流動的上限があることによって、ほぼコストなしでトランザクションをインクルードすることのできる(ブロックを生成することのできる)マイナー(採掘者)でさえネットワーク全体へのトランザクションのコストと同額の使用料が課せられる。手数料とブロックのオペレーション上限のシステムの経済基礎知識についての詳細は、Ethereum白書の「fee」の項目を参照。 - - 手数料が実際にどう動くかをいかに述べる。あらゆるトランザクションは、他のデータとともに、ガス価格とガス開始値を含む。ガス開始値とはガスの量であり、トランザクション自身がそれを確約する。ガス価格とはトランザクションが支払うことになる単位ガス料金だ。;このようにして、トランサクションが送られると、ガスがあるとき最初に行われるのが、送信者のアカウントのバランスから、トランザクションの値と、(ガス価格☓ガス開始値)[wei]を足したものを差し引く。ガス価格は送信者によりセットされるが、低すぎるガス価格のトランザクションの処理は、採掘者が拒否をする可能性が高いだろう。 - - ガスはざっくりといえば、計算ステップのカウンターとして考えることができ、トランザクションの実行中存在するもので、実行が終われば消えてなくなる。トランザクションの実行が始まった時、今あるガスは(ガス開始値 - 500 - 5 ☓ トランザクションデータ長※)としてセットされる。全計算ステップにおいて、あるガス量(ふつう1で、時々オペレーションに依存して値が大きくなる)が全体から差し引かれていく。もしガスが0に達すれば、すべての実行は元に戻るがトランザクションは有効で送信者はガスの料金を支払わなければならない。もし、トランザクションの実行が無事終了し、Nだけガスがのこっていたら、N×ガス価格が払い戻されるというわけだ。 - - - -ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー - -※ トランザクションデータ長 トランザクションのデータにあるバイトの数のこと。 - - コントラクトによるコントラクト呼び出しという場合にも同様のことが起こる。 -(つまりトランザクションと送信作業、コントラクト呼び出しは同義で、それが人の手書きによるものなのか、コントラクトによる自動実行なのかという違いに尽きる。) - コントラクト呼び出しの際、途中でガスが尽きると、処理は元に戻るだけで、処理が遂行すれば返り値を返し、このどちらかの状態しかありえないので、完全に安全に呼び出し処理ができるのである。 -サブのコントラクトが余力を残していれば、親の実行まで戻る。 - -### Virtual machine opcodes - -The opcodes in the EVM are as follows: - -* `0x00`: `STOP`, stops execution -* `0x01`: `ADD`, pops 2 values `a`, `b` from the top of the stack and pushes `a+b` to the top of the stack (all arithmetic is modulo 2256) -* `0x02`: `MUL`, pops 2 values `a`, `b`, pushes `a*b` -* `0x03`: `SUB`, pops 2 values `a`, `b`, pushes `a-b` (`a` is the value immediately at the top of the stack before execution, `b` is second from top) -* `0x04`: `DIV`, pops 2 values `a`, `b`, pushes `a/b` if `b != 0` else 0 -* `0x05`: `SDIV`, pops 2 values `a`, `b`, pushes `a/b` if `b != 0` else 0, except where `a` and `b` are treated as signed integers, ie. if `a >= 2^255` then it's treated as the negative value `a - 2^256`. Division with negative numbers is done as in Python, ie. `25 / 3 = 8`, `25 / -3 = -9`, `-25 / 3 = -9`, `-25 / -3 = 8` -* `0x06`: `MOD`, pops 2 values `a`, `b`, pushes `a%b` if `b != 0` else 0 -* `0x07`: `SMOD`, pops 2 values `a`, `b`, pushes `a%b` if `b != 0` else 0, treating `a`, `b` as signed values. Modulo with negative numbers is done as in Python, ie. `25 % 3 = 1`, `25 % -3 = -2`, `-25 % 3 = 2`, `-25 % -3 = -1` -* `0x08`: `EXP`, pops 2 values `a`, `b`, pushes `a^b` -* `0x09`: `NEG`, pops 1 value `a`, pushes `-a` (ie. `2^256 - a`) -* `0x0a`: `LT`, pops 2 values `a`, `b`, pushes 1 if `a < b` else 0 -* `0x0b`: `GT`, pops 2 values `a`, `b`, pushes 1 if `a > b` else 0 -* `0x0c`: `SLT`, pops 2 values `a`, `b`, pushes 1 if `a < b` else 0, doing a signed comparison -* `0x0d`: `SGT`, pops 2 values `a`, `b`, pushes 1 if `a > b` else 0, doing a signed comparison -* `0x0e`: `EQ`, pops 2 values `a`, `b`, pushes 1 if `a == b` else 0 -* `0x0f`: `NOT`, pops 1 value `a`, pushes 1 if `a = 0` else 0 -* `0x10`: `AND`, pops 2 values `a`, `b`, pushes the bitwise and of `a` and `b` -* `0x11`: `OR`, pops 2 values `a`, `b`, pushes the bitwise or of `a` and `b` -* `0x12`: `XOR`, pops 2 values `a`, `b`, pushes the bitwise xor of `a` and `b` -* `0x13`: `BYTE`, pops 2 values `a`, `b`, pushes the `a`th byte of `b` (zero if `a >= 32`) -* `0x20`: `SHA3`, pops 2 values `a`, `b`, pushes `SHA3(memory[a: a+b])` -* `0x30`: `ADDRESS`, pushes the contract address -* `0x31`: `BALANCE`, pushes the contract balance -* `0x32`: `ORIGIN`, pushes the original sending account of the transaction that led to the current message (ie. the account that pays for the gas) -* `0x33`: `CALLER`, pushes the sender of the current message -* `0x34`: `CALLVALUE`, pushes the ether value sent with the current message -* `0x35`: `CALLDATALOAD`, pops 1 value `a`, pushes `msgdata[a: a + 32]` where `msgdata` is the message data. All out-of-bounds bytes are assumed to be zero -* `0x36`: `CALLDATASIZE`, pushes `len(msgdata)` -* `0x37`: `CALLDATACOPY`, pops 3 values `a`, `b`, `c`, copies `msgdata[b: b+c]` to `memory[a: a+c]` -* `0x38`: `CODESIZE`, pushes `len(code)` where `code` is the contract's code -* `0x39`: `CODECOPY`, pops 3 values `a`, `b`, `c`, copies `code[b: b+c]` to `memory[a: a+c]` -* `0x3a`: `GASPRICE`, pushes the `GASPRICE` of the current transaction -* `0x40`: `PREVHASH`, pushes the hash of the previous block -* `0x41`: `COINBASE`, pushes the coinbase (ie. miner's address) of the current block -* `0x42`: `TIMESTAMP`, pushes the timestamp of the current block -* `0x43`: `NUMBER`, pushes the number of the current block -* `0x44`: `DIFFICULTY`, pushes the difficulty of the current block -* `0x45`: `GASLIMIT`, pushes the gas limit of the current block -* `0x50`: `POP`, pops one value from the stack -* `0x51`: `DUP`, pops one value `a` from the stack and pushes `a` twice -* `0x52`: `SWAP`, pops two values `a` and `b` and pushes them in reverse order -* `0x53`: `MLOAD`, pops one value `a` and pushes `memory[a: a + 32]` -* `0x54`: `MSTORE`, pops two values `a`, `b` and sets `memory[a: a + 32] = b` -* `0x55`: `MSTORE8`, pops two values `a`, `b` and sets `memory[a] = b % 256` -* `0x56`: `SLOAD`, pops one value `a` and pushes `storage[a]` -* `0x57`: `SSTORE`, pops two values `a`, `b` and sets `storage[a] = b` -* `0x58`: `JUMP`, pops one values `a`, and sets `PC = a` where `PC` is the program counter -* `0x59`: `JUMPI`, pops two values `a`, `b` and sets `PC = a` if `b != 0` -* `0x5a`: `PC`, pushes the program counter -* `0x5b`: `MSIZE`, pushes `len(memory)` -* `0x5c`: `GAS`, pushes the amount of gas remaining (before executing this operation) -* `0x60` - `0x7f`: `PUSH1` - `PUSH32`, `PUSH_k` pushes a value corresponding to the next `k` bytes in the code, and sets `PC += k + 1` (ie. to the byte immediately after the `k` bytes pushed) -* `0xf0`: `CREATE`, pops three values `a`, `b`, `c`, creates a new contract with initialization code `memory[b: b+c]` and endowment (ie. initial ether sent) `a`, and pushes the value of the contract -* `0xf1`: `CALL`, pops seven values `a`, `b`, `c`, `d`, `e`, `f`, `g`, and sends a message to address `b` with `a` gas and `c` ether and data `memory[d: d+e]`. Output is saved to `memory[f: f+g]`, right-padding with zero bytes if the output length is less than `g` bytes. If execution did not run out of gas pushes 1, otherwise pushes 0. -* `0xf2`: `RETURN`, pops two values `a`, `b`, and stops execution, returning `memory[a: a + b]` -* `0xff`: `SUICIDE`, pops one value `a`, sends all remaining ether to that address, returns and flags the contract for deletion as soon as transaction execution ends - -Note that high-level languages will often have their own wrappers for these opcodes, sometimes with very different interfaces. - -### Ethereum ブロックチェーンの基本 - - Ethereum・ブロックチェーン(あるいは「帳簿」)は分散型で(中央集約型ではなく)、全アカウントのカレントステイト(現在の状態)を保持し、大規模に複製されたデータベースである。このブロックチェーンは全アカウントの状態を貯蔵するのに、[「パトリシア木」](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree) というデータ構造を採用している。この「パトリシア木」は本質的に、一般的なKey/value貯蔵時にふるまう「マークル木」の特殊型である。標準のマークル木のように、パトリシア木はルートハッシュを保持している。ルートハッシュは、木構造全体を参照するために使用可能で、木のコンテンツはルートハッシュの変更なしに修正不可能である。それぞれのアカウントのために、木は、[ account_nonce, ether_balance, code_hash, storage_root ] をふくんだ、4つの構成要素からなるタップル(4-tuple)を貯蔵している。ここで、このタップルの要素の定義は以下の通りである。 - -* account_nonce:アカウントから送られたトランザクション数 -* ether_balance :アカウントの残金 -* code_hash  :アカウントの種類がコントラクト->コードのハッシュ値 -        アカウントの種類がEOアカウント->"" -* storage_root  :アカウントの保持するストレージ内を格納した -        新たなパトリシア木データ構造のルート - -![img](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/chaindiag.png) - - 毎分、マイナーは新しいブロックを生成し、(Ethereumのマイニングの概念はビットコインにおける概念と全く同じである。より情報が必要ならばそこらのビットコインのチュートリアルを見るとよい。)新しいブロックは、「一番最近生成されたブロック以降に生成され、かつパトリシア木が、これらのトランザクションを一つのブロックとして適用しマイナーに報酬を与えたのち、そのルートのハッシュ値を新しい状態(状態木)にしてから、新たに生成されたトランザクションのリスト」を含んでいる。 - - パトリシア木の仕組みのおかげで、もし少ししかない変更がなされれば、木の大部分は変更前の最後の状態と全く同じになるだろう。このように、新しいパトリシア木のノードが単に、古いパトリシア木と新しいパトリシア木が全く同じである空間における古い方のノードを貯蔵する同じメモリアドレスを指し戻すことができるだろうような場合には、同じデータを二度蓄える必要はない。N番目のブロックとN+1番目のブロックの間に(N+1番目のブロックに取り込まれるべき)、千箇所の変更があったとして、たとえ全パトリシア木のデータサイズが何ギガバイトに及ぼうとも、N+1番目のブロックに貯蔵されるのに必要な新しいデータ量はたかだか数百キロバイトであり、基本的にもっと少ない(同じコントラクト内で変化が生じたときは特に)。全てのブロックは、ブロック数、タイムスタンプ、マイナーのアドレス、ガスの上限のような他のデータと同様にして、一つ前のブロックのハッシュ値を含んでいる。 - -### Graphical Interfaces - - コントラクトはそれ自身とてもパワフルなものだが、Dアプリを完全にするものとは言えない。Dアプリはむしろ、コントラクトとそのコントラクトを使用するグラフィカルインターフェースの融合によるものである。(これは、現バージョンのEthereumのことを述べており、Ethereumの未来バージョンでは、whisperといった、Dアプリ内のノードに対して、ブロックチェーンなしで互いにp2pメッセージを送らせることのできるプロトコルを含むだろう。)いまちょうど、そのインターフェイスは、HTML/CSS/JSのウェブページとして実装され、特別な javascript API がEthereumブロックチェーンと一緒に動作する eth オブジェクト形式の中にある。javascript APIのキーとなる部分は以下の通りである。 - -* `eth.transact(from, ethervalue, to, data, gaslimit, gasprice)` - sends a transaction to the desired address from the desired address (note: `from` must be a private key and `to` must be an address in hex form) with the desired parameters -* `(string).pad(n)` - converts a number, encoded as a string, to binary form `n` bytes long -* `eth.gasPrice` - returns the current gas price -* `eth.secretToAddress(key)` - converts a private key into an address -* `eth.storageAt(acct, index)` - returns the desired account's storage entry at the desired index -* `eth.key` - the user's private key -* `eth.watch(acct, index, f)` - calls `f` when the given storage entry of the given account changes - - ethオブジェクトを利用するのに、特別なソースファイルやライブラリは全く要らない。 -しかしながら、そうして作られたDアプリはEthereumクライアントの中で開いたときのみ動作するようになり、一般的なwebブラウザ上では動かない。Javascript APIの実践的使用例として[the source code of this webpage](http://gavwood.com/gavcoin.html)を訪れるとよい。 -. - -### Fine Points To Keep Track Of - -See [https://github.com/ethereum/wiki/wiki/Subtleties](https://github.com/ethereum/wiki/wiki/Subtleties) diff --git a/[Japanese]-Ethereum-TOC.md b/[Japanese]-Ethereum-TOC.md deleted file mode 100644 index 1d6f401bd..000000000 --- a/[Japanese]-Ethereum-TOC.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -name: Ethereum TOC -category: ---- - -###Ethereum 次世代スマートコントラクトとディセントラルアプリケーションレイヤー へようこそ。 - -[Ethereum White Paper](https://github.com/ethereum/wiki/wiki/White-Paper) ( 英語版 ) -[Ethereum 白書](https://github.com/ethereum/wiki/wiki/%5BJapanese%5D-White-Paper) ( 要改訳 ) - - - -[RLP](https://github.com/ethereum/wiki/wiki/%5BJapanese%5D-RLP), Ethereumのデータエンコードに使用される再帰的リニアプレフィックス仕様 - -[パトリシアツリー](https://github.com/ethereum/wiki/wiki/%5BJapanese%5D-Patricia-Tree) 別名Trieとしても知られるマークルパトリシアツリー仕様 Ethereumにおいてブロックチェインのステートのハッシュを記憶するために使用される構造 - -[ワイヤプロトコル](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Wire-Protocol) 仕様 - -[Serpent](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Serpent-programming-language-operations), コントラクトを書くための高水準言語. チュートリアルは [こちら](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Serpent-programming-language-operations). - -[LLL](https://github.com/ethereum/cpp-ethereum/wiki/LLL), Lispに似た低水準言語 "Lisp-like Language" の仕様, PoC-3以降のPoCシリーズでコントラクトを書くために使用される。 - -[用語集](https://github.com/ethereum/wiki/wiki/Glossary) - -[暗号通貨における困難な問題 (取組中)](https://github.com/ethereum/wiki/wiki/Problems) \ No newline at end of file diff --git a/[Japanese]-HPOC_2015.md b/[Japanese]-HPOC_2015.md deleted file mode 100644 index 8e57f07b6..000000000 --- a/[Japanese]-HPOC_2015.md +++ /dev/null @@ -1,201 +0,0 @@ ---- -name: HPOC 2015 -category: ---- - -HPoC 2015 - -昨年私達は、暗号通貨とCryptoeconomic のテクノロジーが主流のものとなるのを妨げています。 -幾つかの技術的、経済的な難しい問題を叙述し、"Hard Problems of Cryptocurrency"の文書を出しました。 - -そのリストには、幾つもの他の困難とともに例えばスケーラビリティや、より効率的なコンセンサスのアルゴリズム、公益となるインセンティブの仕組みを叙述しました。 - -昨年に渡って多くの問題が解決されました、少なくとも追加された更新はもはや、0から1への解決が必要な根本的な問題ではなくなり、 -むしろ現実世界への確かな実装の問題となりました。 -そして、同時に、かなりの数の試練が未だに残っている。それにもかかわらずここにある問題はかなり限定的で、 -過去のものよりも広域に渡るものではありません。 - -メタコンセンサス(コンセンサスのためのコンセンサス) - -技術的な視野が急速に広がることに関連し続けるために、ソフトウェアは更新されなければならず、 -更新しないソフトウェアは代替手段が無いものの、ゆっくりとより優れた技術へと取って代わられて死に絶えます。 -このことは何故この問題が分散形の暗号プロトコルの同様に当てはまるべきでないのかの理由とはなりません。 -しかしながら分散形の暗号システムは自然な疑問へと結びつく。誰が更新のプロセスをコントロールするのでしょうか? -このことを書いている間に、Bitcoinのコミュニティはブロックサイズを1MBから20MBに増やすかどうかを決定するプロセスを辿っていて、 -これは、意図を明確化し、新しく機関を設立して意思決定をするというプロセスを得ずして、 -既定路線による意思決定のプロセスがなされる状況へと結びつくこととなっていて、 -政治的な議論が、小数のコア開発者の中で行われる、という状況を生み出しています。 - -meta-consensus(大衆による合意形成を形作っていくもの)となる intra-protocol(内部プロトコル)は有るのでしょうか、 -ー 即ち、プロトコルの更新に対しての合意形成を円滑化する、 -例えば consensus 決定に関する投票 のような、プロトコルの内部にあるメカニズムはあるでしょうか? -あるいは、何故この理論は分散形の暗号プロトコルに同様に当てはめられるべきではないのでしょうか。 -そんなシステムがあったとすれば、 -恩恵は計り知れず、 -柔軟性が格段と広がり、 -中央集約型のリスクとなる政治的な癒着に頼らずにすみ、 -かつ、参加者に対して大きな発言権を得ることができ、 -社会的に "well-connected" であるような人々のみならず、あらゆる人にその恩恵が行き渡るでしょう。 - (see Jo Freeman's The Tyranny of Structurelessness for more on this). - - - -In order to remain relevant in a rapidly evolving technological landscape, software must update, and software that does not update has no alternative but to slowly fade away and die as it is replaced by superior technology. There is no reason why this principle should not apply to decentralized crypto-protocols as well. However, the need to make upgrades to decentralized crypto-systems leads to a natural question: who controls the updating process? As of the time of this writing, the Bitcoin community is going through the process of deciding whether or not to increase the maximum block size from 1 MB to 20 MB, and the lack of a deliberately instituted decision-making process has lead to the situation where the de-facto decision-making process essentially amounts to political debate among a small number of core developers. - -Is there a way of building intra-protocol meta-consensus - that is, a mechanism inside the protocol that facilitates agreement on upgrades to the protocol, perhaps using some kind of consensus voting? Such a system would have a number of benefits, including greater flexibility, less reliance on political processes that end up being centralization risks, and can arguably ensure a greater voice to all participants in the protocol, not just those that are socially well-connected (see Jo Freeman's The Tyranny of Structurelessness for more on this). - -望ましいメタコンセンサスのプロトコルは下記を含みます: -Desirable properties of meta-consensus include: - -* 利益となるプロトコルの変更に対しての合意のインセンティブ -* ある種の古いプロトコルのもとに作られるアプリケーションが新しいプロトコルのもとでも最大限効果的であること。 -* ある種のオブジェクト指向のカプセル化のメカニズムのように、開発者があるプロトコル特有の機能を使わなければならないようにすることから離れるようにする。(interface の実装) -* メカニズムが壊れないように抗うということは、望ましくないプロトコルの変更をしなければならないことに繋がっていきます。 -* ユーザーが自動的に新しく選ばれたプロトコルへと、新しいクライアントをダウンロードせずに更新することが出来るようにすること。 -* 現時点でこのメタプロトコルに対する取り組みは、Arthur Bretman's Tezos を含む、Bitsharesの delegated proof of stake そして未だリリースされていない Ethereum 2.0 の提案があります。 - -Some kind of guarantee that applications built under the old protocol will remain maximally effective under the new protocol. Note that a part of this will likely be some kind of object-oriented encapsulation mechanisms in order to steer developers away from using features which are highly protocol-specific -Resistance against the mechanism being corrupted in some sense and forced to lead to an undesirable protocol change -The ability for users to automatically upgrade to a newly chosen protocol without having to download a new client -Existing work on this includes Arthur Breitman's Tezos, Bitshares' delegated proof of stake, and the not-yet-released Ethereum 2.0 proposal. - -公共益の設定による解放と、インセンティブの仕組み - -暗号プロトコルの開発における他の大きな問題は、類似しているファンディングの問題です。どのようにしてプロトコルが更新され、そしてより多くの一般的で公共益に繋がるミドルウェアとが結びつくか、という問題です。 -最初の開発フェイズにおいては、Crowdsaleのコンセプトは絶対的に欠かせないものです。何百万ドルの努力に対してのファンディング -そうでなければ・・・以下略 -The other major problem in crypto-protocol development is the analogous funding problem: how will protocol upgrades, and more generally public-good ecosystem middleware, be paid for? In the initial phase of development, the concept of "crowdsales" has proven to be absolutely invaluable, providing millions of dollars of funding for efforts which would have otherwise been relegated to being little more than volunteer side projects. However, crowdsales by themselves have a fundamental problem: they are front-loaded, creating heavy incentives for short-term marketing but less so for long-term performance, and they are limited one-time events from which the funds received eventually run out. And even if the funds could somehow be managed so as not to run out, crypto-protocol development would be permanently centralized in a single organization. What would be ideal is, once again, some kind of intra-protocol mechanism for incentivizing the development of public goods. - -公共益に対するインセンティブ化(動機付け)の仕組みは、長い文章を確立するというものを含んでいます。 -その文章は、 -メカニズムの仕様の設計から生まれる数多くのことと、そしてどのようにして公共益の開発に投資し、どの公共益が第一に投資されるに値するか、を決めるということを含んでいます。 -Blockchainの文脈では、 -個人的なマーケットの文脈よりもファンディングの問題は幾分簡単です。 -なぜなら我々には全ての通貨の保持者に -インフレーションによる課税をし、トランザクションフィーからコンセンサスのコストを引いた超過分を得ることが出来るからです。 -しかし、preferece revelation の問題はいっそう困難なものです。というのは、人間の政府は非公式な決定を用いようとし、サポートに値する公共益が何かを判断するための非公式な判断を用いようとしますが、しかし、Blockchainは文脈的に信頼に足るファンドと、信頼に足らないファンドの違いを知ることが出来ません。例えば、とあるタバコ会社は、そのスキャムであり、使用不可能な "zero address" かどうか判断することができません。 -それ故に、完全にある種の明白なコミュニティからもたらされる情報に対して設計されたメカニズムに頼らなければなりません。 - -Public goods incentivization has a long and established literature, including numerous results from mechanism design and assurance contract theory on the topic of both how to fund the development of public goods and on the equally important question of deciding which public goods are worth funding in the first place. -In a blockchain context, -the funding problem is somewhat easier than in a private-market context, -because we have the ability to "tax" all currency holders via inflation and taking the excess of transaction fees minus consensus costs, -but the preference revelation problem is much harder; -a human government can try to use informal judgement to figure out which public goods are worth supporting and which ones are not, -but a blockchain literally cannot tell the difference between a trustworthy development fund, -an untrustworthy development fund, -a tobacco lobbying company, -the "zero address" from which coins can never be spent and a scammer. Hence, it must rely entirely on some kind of mechanism design to elicit this information from the community. - -この困難は、Blockchainの文脈に対してのこれらの保証について当てはめます。 -この困難に対する特定の挑戦は下記の内容を含みます: -The challenge here is applying these guarantees to a blockchain context. Particular challenges include: - -* インセンティブと結びついたシステムの設計は、ユーザーが安全で信頼をおかずにお互いに贈り合うことさえ出来ます -* 例えばコントラクトを通じて(Game theoryでの協調ゲームはこの点にある) -* インセンティブと結びついたシステムの設計は、攻撃者が(P+ epsilon攻撃のように、協調ゲーム理論が不十分かもしれない、何故なら全体的にユーザーの集合は、完全に強調するか、それとも一切協調しないかのどちらかであることが期待されるからだ。) -* Caplanianの"理性的な非理性 (rational irrationality"の批判には、例えば十分に大きな報酬をユーザーに対して与えることで、どのファンドがサポートに値するかを知り、そして単純にすぐにどのようにみえるのがより良いかをすぐに単純にクリックしない。 - -一般的なモデルは下記のように考えられる。: -* Nの公共益が存在し、それらのファンドが有る公共益に対して使うと約束しているアドレスによって表されているとする。誰でもそのアドレスをこのセットに登録することは出来る、ユーザーが必要とする幾らかの手数料を支払った後かも知れない。、どのようにfunding pool Dを分割するかを選択し、(Dは最大の大きさかもしれない、そのメカニズムは、幾らかのDを燃やすかもしれない。) -* 攻撃者は、そこにただお金を送って欲しいだけの偽物の公共益を作り、公共液として、1が分配される和ありアイが完全に一つのプレイヤーに対していくように見えるかもしれない。 -* 攻撃者がどうして攻撃に成功することが社会的に悪である理由は、他の"公式な”公共益が、より高い支払いの割合を持っているかもしれないからだ - -Being incentive-compatible even given the assumption that users can securely and trustlessly bribe each other, eg. via contracts (cooperative game theory can help here) -Being incentive-compatible even given the assumption that the attacker may have a superior ability to coordinate versus the individual participants (cf. P + epsilon attacks; cooperative game theory may be insufficient here as it generally assumes that collections of users can either coordinate totally or not coordinate at all) -Avoiding Caplanian "rational irrationality" critiques, ie. providing sufficiently large incentives for users to learn about which funds are worth supporting and not simply immediately click on what looks nicer -The general model can be thought of as follows: -もし必要であるならば、我々はユーザーがセキュリティのデポジットを持っていることに頼る事が出来る。例 承認者であること、脅されていないことが証明できる投票) -There exist N public goods, represented by addresses owned by funds that promise to spend the money on particular public goods (eg. development). Anyone can register an address in this set, perhaps after paying some fee -Users need to, using some mechanism, select how to split up funding pool D between these goods (D may be a maximum size; the mechanism may end up "burning" some of D) -Attackers creating fake "public goods" that really just send money to themselves can be seen simply as being public goods with a payoff ratio of 1 that happens to be concentrated entirely in a single player. The reason why attackers winning is socially bad is that other "legitimate" public goods will have much higher payoff ratios -If necessary, we can rely on the users having security deposits, eg. being validators -Coercion-proof Voting - -2001年のAri Juel は、"脅迫耐性のある電子投票システム" のプロトコル を考えついた。 それは投票をオンラインで、ユーザーが他者に誰に投票したくぉ公表すること無く投票が出来るだけでなく、さらには実際に、望むのでさえあれば他の誰かに投票することを証明することが出来ないようになっている。ー脅迫したり賄賂を投票する人に対して送ることが不可能となる。 -投票問題と同様には全般的に、revelation問題の設定を解決する有る一つの可能性のある方法であうr. -このようなスキームを実装することが出来る。それによって協調することが更に困難となる。 -ユーザーが2つのIDをコントロール出来るために、2つのIDが安全に腐敗した取引を互いに行うことは出来、完全な解決策は決してないが、 -富の集中を防ぐことの思い込みはシステムをかなる頑強なものとする。 -Ari Juels in 2001 came up with a protocol for "coercion-resistant electronic elections" - a way of doing voting online such that not only is it possible for users to vote without revealing to others who they voted for, but it is in fact not possible to prove to anyone else who you voted for even if you wanted to - making it impossible to coerce or bribe people to vote. One possible route to solving the preference revelation problem, as well as voting games in general, is to implement this kind of scheme, making it much harder to coordinate. It is by no means a complete solution, since a user that controls two identities can still have those two identities securely collude with each other, but combined with a wealth deconcentration assumption it would make systems substantially more robust. - -試練は、どのようにしてある種の脅迫耐性のある電子投票システムをDecenralizedな公共のblockchainの文脈に実装するかということだ。その最大の問題は、完全に特定の秘密鍵を持っている当事者がおらず、互いに不正をしない信頼される事ができ、システムは完全に公共であることが必要だろう。 - -注意: 暗号学的に脅迫耐性のある投票システムを作る大体の手段は、暗号経済学的に脅迫耐性のある電子投票のシステムを制作することだ。ある種のメカニズムを思いつき、もし投票者が他の当事者に対して証明することが出来たのであれば、ゼロでないクオリティの誰が投票したかに対しての情報を得ることが出来る。 -Note: an alternative to making cryptographically coercion-resistant electronic elections is making cryptoeconomically coercion-resistant electronic elections: come up with some kind of mechanism such that if a voter proves to another party any nonzero quantity of information about who they voted for, that party can exploit them for an expected nonzero return at their expense (if this exploitation can be made to be unprovable, then even better, as it reduces the possibility of effective circumvention through reputation). - -事前に解放されることに反対すること - -Schellingcoinのように沢山のプロトコルがある、AugurではN-of-Nのプロトコルを乱数生成において使用し、ユーザーが最初に暗号的に -ある値xを"コミット”したことに気付き、例えば、H(x)をあるハッシュの関数に対してサブミットすること、そして後になってサブミットされた値xを公表する段階となって、何もrevelationや、誤りとなる解放は無く、セキュリティのデポジットの負担によって罰することが出来る。 -しかしながら、これらの多くのプロトコルは、もしユーザーの答えが最初のフレーズの間はプライベートであるのであれば効果的に機能する。 -そして、取り分け情報を共有した事が証明できるために、不正が簡単になるに連れて、このメカニズムの効率性は、減少していくこととなる。 -There are many protocols such as Schellingcoin, Augur, N-of-N protocols in random number generation, etc, that rely on some notion of users first cryptographically "committing" to some value x, eg. by submitting H(x) for some hash function, and then in a later stage "revealing" the value for x that they submitted - with non-revelation or incorrect revelation being punishable by security deposit loss. However, many of these protocols only work effectively if users' answers during the first phase are private; if users can collude to share information, and particularly if they can provably share information, then the mechanism's effectiveness decreases as collusion becomes easier. - -あらゆるユーザーが0か1かを提供するコミットが明らかにするプロトコを考えて見て欲しい、そしてランダムにこの値を選ぶことを考えてみて欲しい最初は、どちらのユーザーも関係のないsalt s を選ばなければならない、そしてH([s, v]) を提出しvが0か1かとなる。 -そして2番目のステップではユーザーはsとvの値を提出しなければならない、そしてコミットに対してチェックされなければならない。 -全てのvの値の合計をmod2で行ったものは、ランダムな出力の1つを取り上げたもので、ここにおいて - - -Suppose a commit-reveal protocol where all users must supply either 0 or 1, and they are "supposed to" randomly choose this value. In the first step, each user must pick a (irrelevant) salt s, and provide H([s, v]) where v is either 0 or 1. In the second step, the user must supply their values of s and v, and have them be checked against the commitment. The sum of all values v mod 2 is then taken as a single bit of random output. Here, hypothetically all players can talk to each other and provably coordinate on voting either 0 or 1. However, we can design an anti-pre-revelation protocol as follows: any party can choose to register a bet against any other party that they will vote on some specific value with at last a 60% probability (ie. if A bets that B will bet 0, then if B ends up betting 0 then B gets 2 units out of A's security deposit, and if B ends up betting 1 then A gets 3 units out of B's security deposit). Hence, if party P[i] reveals to party P[j] their v value, or even a zero-knowledge proof of their v value with more than 60% probability, they can be exploited. - -困難なことはこの道を選ぶことが出来るか、取りうる値が一層大きく、投票の可能性が前提条件として知られていないかもしれない、もしくは暗号学的に不可能にするか、暗号経済的に誰かの隠された値を明らかにすることをハイコストにすることによって -その他のアプローチ - -A challenge is to either take this path and try to expand it into an environment where the potential value space is much larger and probabilities of voting may not be known a priori, or find some other approach to make it cryptographically impossible or cryptoeconomically expensive to reveal one's hidden value before one is supposed to. Tailoring to specific applications (eg. linear Schellingcoin price voting) is suboptimal but acceptable. A particular problem is the existence of zero-knowledge proofs: one can use zk-SNARKs (or simply plain ZKPs) in order to reveal any information about v and prove that this information is correct by using the provided hash H([s, v]) without revealing anything about s or any information about v that is undesired; hence, a solution should be secure against all kinds of partial information revelation that may be useful, and not simply revealing the exact value of v. - -乱数の生成 -Random Number Generation - -コンセンサスのプロトコルを含む様々なプロトコルにおいてblockchain に基づいたくじ、スケーラブルなサンプル抽出のスキーム当 -ある種の乱数生成をプロトコル内に必要としている。 -Proof of workでは簡単な答えがある、何故なら結果が分かる前に誰かがその回答を計算することが出来ないからだ。そして一旦結果が見つかれば、後悔しないことは大きな機会損失となる。 -しかしながらproof of workは極端に高価であり、セキュリティを保っておくために定常的なコストを必要とする。 -A number of protocols, including consensus protocols, blockchain-based lotteries, scalable sampling schemes, etc, require some kind of random number generation in the protocol. Proof of work provides an answer easily, because one cannot compute ahead of time what the result will be, and once a result is found not revealing it carries a large opportunity cost. However, proof of work is extremely expensive, requiring constant expenditure equal to the security margin. - - -N of N のコミットが明らかにすることの代わりとしてTomilionのRANDAOのプロトコルが上げられる。 -働き方は以下となる。 - -n のPlayerが P[1] ... P[n] としてサイズDのセキュリティのデポジットをプロトコル内に持ち、ランダムな値V[1]... V[n]を -ラウンド1の間にP[i]はH(V[i])をサブミットする。 -ラウンド2では、H(V[i])を提出した全てのプレイヤーはV[i}を提出しなければならない。 -もし全てのプレイヤーがそれらの値を正しく提出したならば、(V[1] + ... + V[n]) % 2**256 はランダムなシードとして取り上げられ、そして全てのプレイヤーは自らの値を正しく公開する。 -n players P[1] ... P[n] with security deposits of size D in the protocol choose random values V[1] ... V[n] with 0 <= v[i] < 2**256, and P[i] submits H(V[i]) during round one. -In round two, every player who submitting a value H(V[i]) must submit V[i]. -If all players submit their value correctly, then (V[1] + ... + V[n]) % 2**256 is taken as a random seed, and all players are rewarded with D * i where i is an interest rate (eg. 0.0001 per period). -If not all players submitted their value correctly, then all players who participated get D * i, all players who did not participate lose their entire deposit and are kicked out, and the remaining players repeat the game until eventually all N players cooperate and reveal their values. -もし最後のプレイヤーが参加 -If you are the last player to participate, then you can manipulate the value at a very high cost, and even then only by replacing it with a random value next time around (ie. one can avoid unfavorable values, but one cannot target favorable values or even choose between two known values). However, the mechanism has the limitations that (i) it relies on a non-collusion assumption, (ii) the randomness that it provides is not nearly as fast as proof of work randomness, making it useless for some specific intra-block applications where proof of work shines, and (iii) it can lead to honest players losing large amounts of money from a network attack. Mitigating problem (iii) necessarily involves exacerbating problem (ii), and vice versa. - -The open-ended challenge is to come up with a mechanism inside of a cryptoeconomic context which provides random numbers as output with maximally relaxed security assumptions and maximal robustness and resilience to attackers - ideally, a mechanism with the same properties as proof of work but without (or with only a negligible fraction of) its cost. - -検閲耐久性 -Anti-censorship - -Public blockchains particularly have a strong need to be censorship-resistant, ie. to be able to get transactions into the chain even if powerful parties do not want them included. This is important not just for controversial Wikileaks-style applications; even ordinary financial applications, commit-reveal protocols, etc, could have their security threatened if there was a way of effectively preventing "challenge" messages from entering the blockchain. - -If the set of participants willing to collude to censor is smaller than 33%, then the problem is fairly trivial. If the set is greater than 33%, however, then we know that those participants have the power to shut down the network, albeit at very high cost to themselves. Hence, the problem becomes somewhat different: how do we make it impossible for colluding censors to censor specific transactions without censoring everything else as well? - -One possible route to take is some kind of commit-reveal protocol, where users submit a hash of a transaction plus proof that the transaction is available, and then the transaction sender is somehow bound to include the transaction itself once it is revealed (ie. blocks that do not include the transaction will be invalid). However, this has the problem that (i) proof of availability is very hard to implement, and (ii) colluding censors can simply require the submission of a transaction alongside its proof. In general, any protocol will likely be vulnerable to "colluding censors can simply require a zero-knowledge proof of X", but the challenge is making such a requirement maximally inconvenient for all parties to implement. - -プライバシー -Privacy - -Blockchains are often hailed as an alternative to centralized networks that rely on trusting specific parties. However, one of the major areas in which people actually do strongly distrust centralized parties in real life is in the area of privacy, and blockchain protocols by themsleves are even more public than centralized systems. Hence, blockchain-based solutions to privacy will likely need to go a bit beyond simply creating a decentralized database and being done with it; effort must be made into creating protocols for maximally broad categories of applications (eg. payments, financial contracts, identity and reputation info publication) that combine blockchain-based data publication with protocols that preserve individual privacy, and allow individuals maximum freedom in what facts about themselves to expose to what parties. - -この問題の副次的な問題は以下を含む -Sub-problems of this problem include: - -完全に匿名な通貨(現在はZerocashがある。Zerocashの論証可能な大きな欠点は、xkSNARKsを使っていることがら生じる90秒の間トランザクションの署名の時間を必要としていることだ。) -Privacyが担保された名声のシステムはユーザーが”Zero-knowledgeのreputationの証明"システムを作ることが出来るようにし、ターゲットの望ましい数値に応じて幾らかの名声のスコアを持つことが出来、しかし最小の他の個人的な情報を晒していることだ。 - -対象が求める基準に従ってreputation scoreを持つことが、最小の個人的な情報だけを公開する事で出来る -"zero-knowledge reputation certificates"を作ることが出来るようにしているプライバシーが担保されたreputationシステム - -A privacy-preserving reputation system that allows users to create "zero-knowledge reputation certificates" proving that they have some reputation score according to the target's desired metric but revealing minimal other personal information - -ユーザーがそのコントラクトのコードとコンテントを最大限可能な限り隠せるようにしている金融のコントラクトのシステム - -最大限プライバシーを保護している分散形の internet of thingsのプラットフォーム -A maximally privacy-preserving decentralized internet-of-things platform diff --git a/[Japanese]-Javascript-API.md b/[Japanese]-Javascript-API.md deleted file mode 100644 index 881269a78..000000000 --- a/[Japanese]-Javascript-API.md +++ /dev/null @@ -1,2040 +0,0 @@ ---- -name: Javascript API -category: ---- - -# Introduction - -Dapp を Ethereum 上でうごかすために、`web3` オブジェクトが使えます。これは [web3.js library](https://github.com/ethereum/web3.js)で提供されています。 -この、まるでパーカーのフードのように、 ethereum を包み込んだライブラリのもとでは、 -ローカルのノードと -[RPC calls](https://github.com/ethereum/wiki/wiki/JSON-RPC)を介して通信できます。 -web3.js はすべての ethereum node と通信可能で、そのノードは RPC を発信しています。 - -`web3` オブジェクトは、 -`eth` オブジェクトと - `web3.eth` ( Ethereum blockchain との通信に特化したオブジェクト) と -`shh` オブジェクト - `web3.shh` ( Whisper 上のやりとりのためのオブジェクト) を保持します。 -時間の経過とともに、web3 プロトコル上の他のオブジェクトも紹介していくつもりです。 -使用例は [こちら](https://github.com/ethereum/web3.js/tree/master/example). - -web3.js の洗練された使用例につきましては、[useful Ðapp patterns](https://github.com/ethereum/wiki/wiki/Useful-Ðapp-Patterns)をごらんください。 - -## Using callbacks - -As this API is designed to work with a local RPC node and all its functions are by default use synchronous HTTP requests.con - -If you want to make asynchronous request, you can pass an optional callback as the last parameter to most functions. -All callbacks are using an [error first callback](http://fredkschott.com/post/2014/03/understanding-error-first-callbacks-in-node-js/) style: - -```js -web3.eth.getBlock(48, function(error, result){ - if(!error) - console.log(result) - else - console.error(error); -}) -``` - -## Batch requests - -Batch requests allow queuing up requests and processing them at once. - -```js -var batch = web3.createBatch(); -batch.add(web3.eth.getBalance.request('0x0000000000000000000000000000000000000000', 'latest', callback)); -batch.add(web3.eth.contract(abi).at(address).balance.request(address, callback2)); -batch.execute(); -``` - -## A note on big numbers in web3.js - -You will always get a BigNumber object for balance values as JavaScript is not able to handle big numbers correctly. -Look at the following examples: - -```js -"101010100324325345346456456456456456456" -// "101010100324325345346456456456456456456" -101010100324325345346456456456456456456 -// 1.0101010032432535e+38 -``` - -web3.js depends on the [BigNumber Library](https://github.com/MikeMcl/bignumber.js/) and adds it automatically. - -```js -var balance = new BigNumber('131242344353464564564574574567456'); -// or var balance = web3.eth.getBalance(someAddress); - -balance.plus(21).toString(10); // toString(10) converts it to a number string -// "131242344353464564564574574567477" -``` - -The next example wouldn't work as we have more than 20 floating points, therefore it is recommended to keep you balance always in *wei* and only transform it to other units when presenting to the user: -```js -var balance = new BigNumber('13124.234435346456466666457455567456'); - -balance.plus(21).toString(10); // toString(10) converts it to a number string, but can only show max 20 floating points -// "13145.23443534645646666646" // you number would be cut after the 20 floating point -``` - -# API - -* [web3](#web3) - * [version](#web3versionapi) - * [api](#web3versionapi) - * [client](#web3versionclient) - * [network](#web3versionnetwork) - * [ethereum](#web3versionethereum) - * [whisper](#web3versionwhisper) - * [setProvider(provider)](#web3setprovider) - * [currentProvider](#web3currentprovider) - * [reset()](#web3reset) - * [sha3(string)](#web3sha3) - * [toHex(stringOrNumber)](#web3tohex) - * [toAscii(hexString)](#web3toascii) - * [fromAscii(textString, [padding])](#web3fromascii) - * [toDecimal(hexString)](#web3todecimal) - * [fromDecimal(number)](#web3fromdecimal) - * [fromWei(numberStringOrBigNumber, unit)](#web3fromwei) - * [toWei(numberStringOrBigNumber, unit)](#web3toWei) - * [toBigNumber(numberOrHexString)](#web3tobignumber) - * [isAddress(hexString)](#web3isAddress) - * [net](#web3net) - * [listening/getListening](#web3netlistening) - * [peerCount/getPeerCount](#web3ethpeercount) - * [eth](#web3eth) - * [defaultAccount](#web3ethdefaultaccount) - * [defaultBlock](#web3ethdefaultblock) - * [coinbase/getCoinbase](#web3ethcoinbase) - * [hashrate/getHashrate](#web3ethhashrate) - * [gasPrice/getGasPrice](#web3ethgasprice) - * [accounts/getAccounts](#web3ethaccounts) - * [mining/getMining](#web3ethmining) - * [blockNumber/getBlockNumber](#web3ethblocknumber) - * [register(hexString)](#web3ethregister) (Not implemented yet) - * [unRegister(hexString)](#web3ethunregister) (Not implemented yet) - * [getBalance(address)](#web3ethgetbalance) - * [getStorageAt(address, position)](#web3ethgetstorageat) - * [getCode(address)](#web3ethgetcode) - * [getBlock(hash/number)](#web3ethgetblock) - * [getBlockTransactionCount(hash/number)](#web3ethgetblocktransactioncount) - * [getUncle(hash/number)](#web3ethgetuncle) - * [getBlockUncleCount(hash/number)](#web3ethgetblockunclecount) - * [getTransaction(hash)](#web3ethgettransaction) - * [getTransactionFromBlock(hashOrNumber, indexNumber)](#web3ethgettransactionfromblock) - * [getTransactionReceipt(hash)](#web3ethgettransactionreceipt) - * [getTransactionCount(address)](#web3ethgettransactioncount) - * [sendTransaction(object)](#web3ethsendtransaction) - * [call(object)](#web3ethcall) - * [estimateGas(object)](#web3ethestimategas) - * [filter(array (, options) )](#web3ethfilter) - - [watch(callback)](#web3ethfilter) - - [stopWatching(callback)](#web3ethfilter) - - [get()](#web3ethfilter) - * [contract(abiArray)](#web3ethcontract) - * [contract.myMethod()](#contract-methods) - * [contract.myEvent()](#contract-events) - * [getCompilers()](#web3ethgetcompilers) - * [compile.lll(string)](#web3ethcompilelll) - * [compile.solidity(string)](#web3ethcompilesolidity) - * [compile.serpent(string)](#web3ethcompileserpent) - * [namereg](#web3ethnamereg) - * [db](#web3db) - * [putString(name, key, value)](#web3dbputstring) - * [getString(name, key)](#web3dbgetstring) - * [putHex(name, key, value)](#web3dbputhex) - * [getHex(name, key)](#web3dbgethex) - * [shh](#web3shh) - * [post(postObject)](#web3shhpost) - * [newIdentity()](#web3shhnewidentity) - * [hasIdentity(hexString)](#web3shhhaveidentity) - * [newGroup(_id, _who)](#web3shhnewgroup) - * [addToGroup(_id, _who)](#web3shhaddtogroup) - * [filter(object/string)](#web3shhfilter) - * [watch(callback)](#web3shhfilter) - * [stopWatching(callback)](#web3shhfilter) - * [get(callback)](#web3shhfilter) - -## Usage - -#### web3 -The `web3` object provides all methods. - -##### Example - -```js -var web3 = require('web3') -``` - -*** - -#### web3.version.api - - web3.version.api - // or async - web3.version.getApi(callback(error, result){ ... }) - -##### Returns - -`String` - The ethereum js api version. - -##### Example - -```js -var version = web3.version.api; -console.log(api); // "0.2.0" -``` - -*** - -#### web3.version.client - - web3.version.client - // or async - web3.version.getClient(callback(error, result){ ... }) - - -##### Returns - -`String` - The client/node version. - -##### Example - -```js -var version = web3.version.client; -console.log(version); // "Mist/v0.9.3/darwin/go1.4.1" -``` - -*** - -#### web3.version.network - - web3.version.network - // or async - web3.version.getNetwork(callback(error, result){ ... }) - - -##### Returns - -`String` - The network protocol version. - -##### Example - -```js -var version = web3.version.network; -console.log(version); // 54 -``` - -*** - -#### web3.version.ethereum - - web3.version.ethereum - // or async - web3.version.getEthereum(callback(error, result){ ... }) - - -##### Returns - -`String` - The ethereum protocol version. - -##### Example - -```js -var version = web3.version.ethereum; -console.log(version); // 60 -``` - -*** - -#### web3.version.whisper - - web3.version.whisper - // or async - web3.version.getWhisper(callback(error, result){ ... }) - - -##### Returns - -`String` - The whisper protocol version. - -##### Example - -```js -var version = web3.version.whisper; -console.log(version); // 20 -``` - -*** - -#### web3.setProvider - - web3.setProvider(provider) - -Should be called to set provider. - -##### Parameters -none - -##### Returns - -`undefined` - -##### Example - -```js -web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545')); // 8080 for cpp/AZ, 8545 for go/mist -``` - -*** - -#### web3.currentProvider - - web3.currentProvider - -Will contain the current provider, if one is set. This can be used to check if mist etc. set already a provider. - - -##### Returns - -`Object` - The provider set or `null`; - -##### Example - -```js -// Check if mist etc. already set a provider -if(!web3.currentProvider) - web3.setProvider(new web3.providers.HttpProvider("http://localhost:8545")); - -``` - -*** - -#### web3.reset - - web3.reset() - -Should be called to reset state of web3. Resets everything except manager. Uninstalls all filters. Stops polling. - -##### Parameters -none - -##### Returns - -`undefined` - -##### Example - -```js -web3.reset(); -``` - -*** - -#### web3.sha3 - - web3.sha3(string [, callback]) - -##### Parameters - -1. `String` - The string to hash using the SHA3 algorithm -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -`String` - The SHA3 of the given data. - -##### Example - -```js -var str = web3.sha3("Some ASCII string to be hashed"); -console.log(str); // "0x536f6d6520415343494920737472696e6720746f20626520686173686564" - -var hash = web3.sha3(str); -console.log(hash); // "0xb21dbc7a5eb6042d91f8f584af266f1a512ac89520f43562c6c1e37eab6eb0c4" -``` - -*** - -#### web3.toHex - - web3.toHex(mixed); - -Converts any value into HEX. - -##### Parameters - -1. `String|Number|Object|Array|BigNumber` - The value to parse to HEX. If its an object or array it will be `JSON.stringify` first. If its a BigNumber it will make it the HEX value of a number. - -##### Returns - -`String` - The hex string of `mixed`. - -##### Example - -```js -var str = web3.toHex({test: 'test'}); -console.log(str); // '0x7b2274657374223a2274657374227d' -``` - -*** - -#### web3.toAscii - - web3.toAscii(hexString); - -Converts a HEX string into a ASCII string. - -##### Parameters - -1. `String` - A HEX string to be converted to ascii. - -##### Returns - -`String` - An ASCII string made from the given `hexString`. - -##### Example - -```js -var str = web3.toAscii("0x657468657265756d000000000000000000000000000000000000000000000000"); -console.log(str); // "ethereum" -``` - -*** - -#### web3.fromAscii - - web3.fromAscii(string [, padding]); - -Converts any ASCII string to a HEX string. - -##### Parameters - -1. `String` - An ASCII string to be converted to HEX. -2. `Number` - The number of bytes the returned HEX string should have. - -##### Returns - -`String` - The converted HEX string. - -##### Example - -```js -var str = web3.fromAscii('ethereum'); -console.log(str); // "0x657468657265756d" - -var str2 = web3.fromAscii('ethereum', 32); -console.log(str2); // "0x657468657265756d000000000000000000000000000000000000000000000000" -``` - -*** - -#### web3.toDecimal - - web3.toDecimal(hexString); - -Converts a HEX string to its number representation. - -##### Parameters - -1. `String` - An HEX string to be converted to a number. - - -##### Returns - -`Number` - The number representing the data `hexString`. - -##### Example - -```js -var number = web3.toDecimal('0x15'); -console.log(number); // 21 -``` - -*** - -#### web3.fromDecimal - - web3.fromDecimal(number); - -Converts a number or number string to its HEX representation. - -##### Parameters - -1. `Number|String` - A number to be converted to a HEX string. - -##### Returns - -`String` - The HEX string representing of the given `number`. - -##### Example - -```js -var value = web3.fromDecimal('21'); -console.log(value); // "0x15" -``` - -*** - -#### web3.fromWei - - web3.fromWei(number, unit) - -Converts a number of wei into the following ethereum units: - -- `kwei`/`ada` -- `mwei`/`babbage` -- `gwei`/`shannon` -- `szabo` -- `finney` -- `ether` -- `kether`/`grand`/`einstein` -- `mether` -- `gether` -- `tether` - -##### Parameters - -1. `Number|String|BigNumber` - A number or BigNumber instance. -2. `String` - One of the above ether units. - - -##### Returns - -`String|BigNumber` - Either a number string, or a BigNumber instance, depending on the given `number` parameter. - -##### Example - -```js -var value = web3.fromWei('21000000000000', 'finney'); -console.log(value); // "0.021" -``` - -*** - -#### web3.toWei - - web3.toWei(number, unit) - -Converts an ethereum unit into wei. Possible units are: - -- `kwei`/`ada` -- `mwei`/`babbage` -- `gwei`/`shannon` -- `szabo` -- `finney` -- `ether` -- `kether`/`grand`/`einstein` -- `mether` -- `gether` -- `tether` - -##### Parameters - -1. `Number|String|BigNumber` - A number or BigNumber instance. -2. `String` - One of the above ether units. - -##### Returns - -`String|BigNumber` - Either a number string, or a BigNumber instance, depending on the given `number` parameter. - -##### Example - -```js -var value = web3.toWei('1', 'ether'); -console.log(value); // "1000000000000000000" -``` - -*** - -#### web3.toBigNumber - - web3.toBigNumber(numberOrHexString); - -Converts a given number into a BigNumber instance. - -See the [note on BigNumber](#a-note-on-big-numbers-in-javascript). - -##### Parameters - -1. `Number|String` - A number, number string or HEX string of a number. - - -##### Returns - -`BigNumber` - A BigNumber instance representing the given value. - - -##### Example - -```js -var value = web3.toBigNumber('200000000000000000000001'); -console.log(value); // instanceOf BigNumber -console.log(value.toNumber()); // 2.0000000000000002e+23 -console.log(value.toString(10)); // '200000000000000000000001' -``` - -*** - -### web3.net - -#### web3.net.listening - - web3.net.listening - // or async - web3.net.getListening(callback(error, result){ ... }) - -This property is read only and says whether the node is actively listening for network connections or not. - -##### Returns - -`Boolean` - `true` if the client is actively listening for network connections, otherwise `false`. - -##### Example - -```js -var listening = web3.net.listening; -console.log(listening); // true of false -``` - -*** - -#### web3.net.peerCount - - web3.net.peerCount - // or async - web3.net.getPeerCount(callback(error, result){ ... }) - -This property is read only and returns the number of connected peers. - -##### Returns - -`Number` - The number of peers currently connected to the client. - -##### Example - -```js -var peerCount = web3.net.peerCount; -console.log(peerCount); // 4 -``` - -*** - -### web3.eth - -Contains the ethereum blockchain related methods. - -##### Example - -```js -var eth = web3.eth; -``` - -*** - -#### web3.eth.defaultAccount - - web3.eth.defaultAccount - -This default address is used for the following methods (optionally you can overwrite it by specifying the `from` property): - -- [web3.eth.sendTransaction()](#web3ethsendtransaction) -- [web3.eth.call()](#web3ethcall) - -##### Values - -`String`, 20 Bytes - Any address you own, or where you have the private key for. - -*Default is* `undefined`. - -##### Returns - -`String`, 20 Bytes - The currently set default address. - -##### Example - -```js -var defaultAccount = web3.eth.defaultAccount; -console.log(defaultAccount); // '' - -// set the default block -web3.eth.defaultAccount = '0x8888f1f195afa192cfee860698584c030f4c9db1'; -``` - -*** - -#### web3.eth.defaultBlock - - web3.eth.defaultBlock - -This default block is used for the following methods (optionally you can overwrite the defaultBlock by passing it as the last parameter): - -- [web3.eth.getBalance()](#web3ethgetbalance) -- [web3.eth.getCode()](#web3ethgetcode) -- [web3.eth.getTransactionCount()](#web3ethgettransactioncount) -- [web3.eth.getStorageAt()](#web3ethgetstorageat) -- [web3.eth.call()](#web3ethcall) - -##### Values - -Default block parameters can be one of the following: - -- `Number` - a block number -- `String` - `"earliest"`, the genisis block -- `String` - `"latest"`, the latest block (current head of the blockchain) -- `String` - `"pending"`, the currently mined block (including pending transactions) - -*Default is* `latest` - -##### Returns - -`Number|String` - The default block number to use when querying a state. - -##### Example - -```js -var defaultBlock = web3.eth.defaultBlock; -console.log(defaultBlock); // 'latest' - -// set the default block -web3.eth.defaultBlock = 231; -``` - -*** - -#### web3.eth.coinbase - - web3.eth.coinbase - // or async - web3.eth.getCoinbase(callback(error, result){ ... }) - -This property is read only and returns the coinbase address were the mining rewards go to. - -##### Returns - -`String` - The coinbase address of the client. - -##### Example - -```js -var coinbase = web3.eth.coinbase; -console.log(coinbase); // "0x407d73d8a49eeb85d32cf465507dd71d507100c1" -``` - -*** - -#### web3.eth.mining - - web3.eth.mining - // or async - web3.eth.getMining(callback(error, result){ ... }) - - -This property is read only and says whether the node is mining or not. - - -##### Returns - -`Boolean` - `true` if the client is mining, otherwise `false`. - -##### Example - -```js -var mining = web3.eth.mining; -console.log(mining); // true or false -``` - -*** - -#### web3.eth.hashrate - - web3.eth.hashrate - // or async - web3.eth.getHashrate(callback(error, result){ ... }) - -This property is read only and returns the number of hashes per second that the node is mining with. - - -##### Returns - -`Number` - number of hashes per second. - -##### Example - -```js -var hashrate = web3.eth.hashrate; -console.log(hashrate); // 493736 -``` - -*** - -#### web3.eth.gasPrice - - web3.eth.gasPrice - // or async - web3.eth.getGasPrice(callback(error, result){ ... }) - - -This property is read only and returns the current gas price. -The gas price is determined by the x latest blocks median gas price. - -##### Returns - -`BigNumber` - A BigNumber instance of the current gas price in wei. - -See the [note on BigNumber](#a-note-on-big-numbers-in-javascript). - -##### Example - -```js -var gasPrice = web3.eth.gasPrice; -console.log(gasPrice.toString(10)); // "10000000000000" -``` - -*** - -#### web3.eth.accounts - - web3.eth.accounts - // or async - web3.eth.getAccounts(callback(error, result){ ... }) - -This property is read only and returns a list of accounts the node controls. - -##### Returns - -`Array` - An array of addresses controlled by client. - -##### Example - -```js -var accounts = web3.eth.accounts; -console.log(accounts); // ["0x407d73d8a49eeb85d32cf465507dd71d507100c1"] -``` - -*** - -#### web3.eth.blockNumber - - web3.eth.blockNumber - // or async - web3.eth.getBlockNumber(callback(error, result){ ... }) - -This property is read only and returns the current block number. - -##### Returns - -`Number` - The number of the most recent block. - -##### Example - -```js -var number = web3.eth.blockNumber; -console.log(number); // 2744 -``` - -*** - -#### web3.eth.register - - web3.eth.register(addressHexString [, callback]) - -(Not Implemented yet) -Registers the given address to be included in `web3.eth.accounts`. This allows non-private-key owned accounts to be associated as an owned account (e.g., contract wallets). - -##### Parameters - -1. `String` - The address to register -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -? - - -##### Example - -```js -web3.eth.register("0x407d73d8a49eeb85d32cf465507dd71d507100ca") -``` - -*** - -#### web3.eth.unRegister - - web3.eth.unRegister(addressHexString [, callback]) - - -(Not Implemented yet) -Unregisters a given address. - -##### Parameters - -1. `String` - The address to unregister. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -? - - -##### Example - -```js -web3.eth.unregister("0x407d73d8a49eeb85d32cf465507dd71d507100ca") -``` - -*** - -#### web3.eth.getBalance - - web3.eth.getBalance(addressHexString [, defaultBlock] [, callback]) - -Get the balance of an address at a given block. - -##### Parameters - -1. `String` - The address to get the balance of. -2. `Number|String` - (optional) If you pass this parameter it will not use the default block set with [web3.eth.defaultBlock](#web3ethdefaultblock). -3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - A BigNumber instance of the current balance for the given address in wei. - -See the [note on BigNumber](#a-note-on-big-numbers-in-javascript). - -##### Example - -```js -var balance = web3.eth.getBalance("0x407d73d8a49eeb85d32cf465507dd71d507100c1"); -console.log(balance); // instanceof BigNumber -console.log(balance.toString(10)); // '1000000000000' -console.log(balance.toNumber()); // 1000000000000 -``` - -*** - -#### web3.eth.getStorageAt - - web3.eth.getStorageAt(addressHexString, position [, defaultBlock] [, callback]) - -Get the storage at a specific position of an address. - -##### Parameters - -1. `String` - The address to get the storage from. -2. `Number` - The index position of the storage. -3. `Number|String` - (optional) If you pass this parameter it will not use the default block set with [web3.eth.defaultBlock](#web3ethdefaultblock). -4. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -`String` - The value in storage at the given position. - -##### Example - -```js -var state = web3.eth.getStorageAt("0x407d73d8a49eeb85d32cf465507dd71d507100c1", 0); -console.log(state); // "0x03" -``` - -*** - -#### web3.eth.getCode - - web3.eth.getCode(addressHexString [, defaultBlock] [, callback]) - -Get the code at a specific address. - -##### Parameters - -1. `String` - The address to get the code from. -2. `Number|String` - (optional) If you pass this parameter it will not use the default block set with [web3.eth.defaultBlock](#web3ethdefaultblock). -3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - The data at given address `addressHexString`. - -##### Example - -```js -var code = web3.eth.getCode("0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8"); -console.log(code); // "0x600160008035811a818181146012578301005b601b6001356025565b8060005260206000f25b600060078202905091905056" -``` - -*** - -#### web3.eth.getBlock - - web3.eth.getBlock(blockHashOrBlockNumber [, returnTransactionObjects] [, callback]) - -Returns a block matching the block number or block hash. - -##### Parameters - -1. `String|Number` - The block number or hash. Or the string `"earliest"`, `"latest"` or `"pending"` as in the [default block parameter](#web3ethdefaultblock). -2. `Boolean` - (optional, default `false`) If `true`, the returned block will contain all transactions as objects, if `false` it will only contains the transaction hashes. -3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Object` - The block object: - - - `number`: `Number` - the block number. `null` when its pending block. - - `hash`: `String`, 32 Bytes - hash of the block. `null` when its pending block. - - `parentHash`: `String`, 32 Bytes - hash of the parent block. - - `nonce`: `String`, 8 Bytes - hash of the generated proof-of-work. `null` when its pending block. - - `sha3Uncles`: `String`, 32 Bytes - SHA3 of the uncles data in the block. - - `logsBloom`: `String`, 256 Bytes - the bloom filter for the logs of the block. `null` when its pending block. - - `transactionsRoot`: `String`, 32 Bytes - the root of the transaction trie of the block - - `stateRoot`: `String`, 32 Bytes - the root of the final state trie of the block. - - `miner`: `String`, 20 Bytes - the address of the beneficiary to whom the mining rewards were given. - - `difficulty`: `BigNumber` - integer of the difficulty for this block. - - `totalDifficulty`: `BigNumber` - integer of the total difficulty of the chain until this block. - - `extraData`: `String` - the "extra data" field of this block. - - `size`: `Number` - integer the size of this block in bytes. - - `gasLimit`: `Number` - the maximum gas allowed in this block. - - `gasUsed`: `Number` - the total used gas by all transactions in this block. - - `timestamp`: `Number` - the unix timestamp for when the block was collated. - - `transactions`: `Array` - Array of transaction objects, or 32 Bytes transaction hashes depending on the last given parameter. - - `uncles`: `Array` - Array of uncle hashes. - -##### Example - -```js -var info = web3.eth.block(3150); -console.log(info); -/* -{ - "number": 3, - "hash": "0xef95f2f1ed3ca60b048b4bf67cde2195961e0bba6f70bcbea9a2c4e133e34b46", - "parentHash": "0x2302e1c0b972d00932deb5dab9eb2982f570597d9d42504c05d9c2147eaf9c88", - "nonce": "0xfb6e1a62d119228b", - "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "transactionsRoot": "0x3a1b03875115b79539e5bd33fb00d8f7b7cd61929d5a3c574f507b8acf415bee", - "stateRoot": "0xf1133199d44695dfa8fd1bcfe424d82854b5cebef75bddd7e40ea94cda515bcb", - "miner": "0x8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty": BigNumber, - "totalDifficulty": BigNumber, - "size": 616, - "extraData": "0x", - "gasLimit": 3141592, - "gasUsed": 21662, - "timestamp": 1429287689, - "transactions": [ - "0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b" - ], - "uncles": [] -} -*/ -``` - -*** - -#### web3.eth.getBlockTransactionCount - - web3.eth.getBlockTransactionCount(hashStringOrBlockNumber [, callback]) - -Returns the number of transaction in a given block. - -##### Parameters - -1. `String|Number` - The block number or hash. Or the string `"earliest"`, `"latest"` or `"pending"` as in the [default block parameter](#web3ethdefaultblock). -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Number` - The number of transactions in the given block. - -##### Example - -```js -var number = web3.eth.getBlockTransactionCount("0x407d73d8a49eeb85d32cf465507dd71d507100c1"); -console.log(number); // 1 -``` - -*** - -#### web3.eth.getUncle - - web3.eth.getUncle(blockHashStringOrNumber, uncleNumber [, returnTransactionObjects] [, callback]) - -Returns a blocks uncle by a given uncle index position. - -##### Parameters - -1. `String|Number` - The block number or hash. Or the string `"earliest"`, `"latest"` or `"pending"` as in the [default block parameter](#web3ethdefaultblock). -2. `Number` - The index position of the uncle. -3. `Boolean` - (optional, default `false`) If `true`, the returned block will contain all transactions as objects, if `false` it will only contains the transaction hashes. -4. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -`Object` - the returned uncle. For a return value see [web3.eth.getBlock()](#web3ethgetblock). - -**Note**: An uncle doesn't contain individual transactions. - -##### Example - -```js -var uncle = web3.eth.getUncle(500, 0); -console.log(uncle); // see web3.eth.getBlock - -``` - -*** - -##### web3.eth.getTransaction - - web3.eth.getTransaction(transactionHash [, callback]) - -Returns a transaction matching the given transaction hash. - -##### Parameters - -1. `String` - The transaction hash. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -`Object` - A transaction object its hash `transactionHash`: - - - `hash`: `String`, 32 Bytes - hash of the transaction. - - `nonce`: `Number` - the number of transactions made by the sender prior to this one. - - `blockHash`: `String`, 32 Bytes - hash of the block where this transaction was in. `null` when its pending. - - `blockNumber`: `Number` - block number where this transaction was in. `null` when its pending. - - `transactionIndex`: `Number` - integer of the transactions index position in the block. `null` when its pending. - - `from`: `String`, 20 Bytes - address of the sender. - - `to`: `String`, 20 Bytes - address of the receiver. `null` when its a contract creation transaction. - - `value`: `BigNumber` - value transferred in Wei. - - `gasPrice`: `BigNumber` - gas price provided by the sender in Wei. - - `gas`: `Number` - gas provided by the sender. - - `input`: `String` - the data send along with the transaction. - - -##### Example - -```js -var blockNumber = 668; -var indexOfTransaction = 0 - -var transaction = web3.eth.getTransaction(blockNumber, indexOfTransaction); -console.log(transaction); -/* -{ - "hash": "0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b", - "nonce": 2, - "blockHash": "0xef95f2f1ed3ca60b048b4bf67cde2195961e0bba6f70bcbea9a2c4e133e34b46", - "blockNumber": 3, - "transactionIndex": 0, - "from": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "to": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f", - "value": BigNumber, - "gas": 314159, - "gasPrice": BigNumber, - "input": "0x57cb2fc4" -} -*/ - -``` - -*** - -#### web3.eth.getTransactionFromBlock - - getTransactionFromBlock(hashStringOrNumber, indexNumber [, callback]) - -Returns a transaction based on a block hash or number and the transactions index position. - -##### Parameters - -1. `String` - A block number or hash. Or the string `"earliest"`, `"latest"` or `"pending"` as in the [default block parameter](#web3ethdefaultblock). -2. `Number` - The transactions index position. -3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Object` - A transaction object, see [web3.eth.getTransaction](#web3ethgettransaction): - - -##### Example - -```js -var transaction = web3.eth.getTransactionFromBlock('0x4534534534', 2); -console.log(transaction); // see web3.eth.getTransaction - -``` - -*** - -#### web3.eth.getTransactionReceipt - - web3.eth.getTransactionReceipt(hashString [, callback]) - -Returns the receipt of a transaction by transaction hash. - -**Note** That the receipt is not available for pending transactions. - - -##### Parameters - -1. `String` - The transaction hash. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Object` - A transaction receipt object, or `null` when no receipt was found: - - - `blockHash`: `String`, 32 Bytes - hash of the block where this transaction was in. - - `blockNumber`: `Number` - block number where this transaction was in. - - `transactionHash`: `String`, 32 Bytes - hash of the transaction. - - `transactionIndex`: `Number` - integer of the transactions index position in the block. - - `from`: `String`, 20 Bytes - address of the sender. - - `to`: `String`, 20 Bytes - address of the receiver. `null` when its a contract creation transaction. - - `cumulativeGasUsed `: `Number ` - The total amount of gas used when this transaction was executed in the block. - - `gasUsed `: `Number ` - The amount of gas used by this specific transaction alone. - - `contractAddress `: `String` - 20 Bytes - The contract address created, if the transaction was a contract creation, otherwise `null`. - - `logs `: `Array` - Array of log objects, which this transaction generated. - -##### Example -```js -var receipt = web3.eth.getTransactionReceipt('0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b'); -console.log(receipt); -{ - "transactionHash": "0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b", - "transactionIndex": 0, - "blockHash": "0xef95f2f1ed3ca60b048b4bf67cde2195961e0bba6f70bcbea9a2c4e133e34b46", - "blockNumber": 3, - "contractAddress": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "cumulativeGasUsed": 314159, - "gasUsed": 30234, - "logs": [{ - // logs as returned by getFilterLogs, etc. - }, ...] -} -``` - -*** - -#### web3.eth.getTransactionCount - - web3.eth.getTransactionCount(addressHexString [, defaultBlock] [, callback]) - -Get the numbers of transactions send from this address. - -##### Parameters - -1. `String` - The address to get the numbers of transactions from. -2. `Number|String` - (optional) If you pass this parameter it will not use the default block set with [web3.eth.defaultBlock](#web3ethdefaultblock). -3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Number` - The number of transactions send from the given address. - -##### Example - -```js -var number = web3.eth.getTransactionCount("0x407d73d8a49eeb85d32cf465507dd71d507100c1"); -console.log(number); // 1 -``` - -*** - -#### web3.eth.sendTransaction - - web3.eth.sendTransaction(transactionObject [, callback]) - -Sends a transaction to the network. - -##### Parameters - -1. `Object` - The transaction object to send: - - `from`: `String` - The address for the sending account. Uses the [web3.eth.defaultAccount](#web3ethdefaultaccount) property, if not specified. - - `to`: `String` - (optional) The destination address of the message, left undefined for a contract-creation transaction. - - `value`: `Number|String|BigNumber` - (optional) The value transferred for the transaction in Wei, also the endowment if it's a contract-creation transaction. - - `gas`: `Number|String|BigNumber` - (optional, default: To-Be-Determined) The amount of gas to use for the transaction (unused gas is refunded). - - `gasPrice`: `Number|String|BigNumber` - (optional, default: To-Be-Determined) The price of gas for this transaction in wei, defaults to the mean network gas price. - - `data`: `String` - (optional) Either a [byte string](https://github.com/ethereum/wiki/wiki/Solidity,-Docs-and-ABI) containing the associated data of the message, or in the case of a contract-creation transaction, the initialisation code. - - `nonce`: `Number` - (optional) Integer of a nonce. This allows to overwrite your own pending transactions that use the same nonce. -2. `Number|String` - (optional) If you pass this parameter it will not use the default block set with [web3.eth.defaultBlock](#web3ethdefaultblock). -3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - The 32 Bytes transaction hash as HEX string. - -If the transaction was a contract creation use [web3.eth.getTransactionReceipt()](#web3gettransactionreceipt) to get the contract address, after the transaction was mined. - -##### Example - -```js - -// compiled solidity source code using https://chriseth.github.io/cpp-ethereum/ -var code = "603d80600c6000396000f3007c01000000000000000000000000000000000000000000000000000000006000350463c6888fa18114602d57005b600760043502 -8060005260206000f3"; - -web3.eth.sendTransaction({data: code}, function(err, address) { - if (!err) - console.log(address); // "0x7f9fade1c0d57a7af66ab4ead7c2eb7b11a91385" -}); -``` - -*** - -#### web3.eth.call - - web3.eth.call(callObject [, defaultBlock] [, callback]) - -Executes a message call transaction, which is directly executed in the VM of the node, but never mined into the blockchain. - -##### Parameters - -1. `Object` - A transaction object see [web3.eth.sendTransaction](#web3ethsendtransaction), with the difference that for calls the `from` property is optional as well. -2. `Number|String` - (optional) If you pass this parameter it will not use the default block set with [web3.eth.defaultBlock](#web3ethdefaultblock). -3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - The returned data of the call, e.g. a codes functions return value. - -##### Example - -```js -var result = web3.eth.call({ - to: "0xc4abd0339eb8d57087278718986382264244252f", - data: "0xc6888fa10000000000000000000000000000000000000000000000000000000000000003" -}); -console.log(result); // "0x0000000000000000000000000000000000000000000000000000000000000015" -``` - -*** - -#### web3.eth.estimateGas - - web3.eth.estimateGas(callObject [, defaultBlock] [, callback]) - -Executes a message call or transaction, which is directly executed in the VM of the node, but never mined into the blockchain and returns the amount of the gas used. - -##### Parameters - -See [web3.eth.sendTransaction](#web3ethsendtransaction), expect that all properties are optional. - -##### Returns - -`Number` - the used gas for the simulated call/transaction. - -##### Example - -```js -var result = web3.eth.estimateGas({ - to: "0xc4abd0339eb8d57087278718986382264244252f", - data: "0xc6888fa10000000000000000000000000000000000000000000000000000000000000003" -}); -console.log(result); // "0x0000000000000000000000000000000000000000000000000000000000000015" -``` - -*** - -#### web3.eth.filter - -```js -// can be 'latest' or 'pending' -var filter = web3.eth.filter(filterString); -// OR object are log filter options -var filter = web3.eth.filter(options); - -// watch for changes -filter.watch(function(error, result){ - if (!error) - console.log(result); -}); - -// Additionally you can start watching right away, by passing a callback: -web3.eth.filter(options, function(error, result){ - if (!error) - console.log(result); -}); -``` - -##### Parameters - -1. `String|Object` - The string `"latest"` or `"pending"` to watch for changes in the latest block or pending transactions respectively. Or a filter options object as follows: - * `fromBlock`: `Number|String` - The number of the earliest block (`latest` may be given to mean the most recent and `pending` currently mining, block). By default `latest`. - * `toBlock`: `Number|String` - The number of the latest block (`latest` may be given to mean the most recent and `pending` currently mining, block). By default `latest`. - * `address`: `String` - An address or a list of addresses to only get logs from particular account(s). - * `topics`: `Array of Strings` - An array of values which must each appear in the log entries. The order is important, if you want to leave topics use `null`, e.g. `[null, '0x00...']`. - -##### Returns - -`Object` - A filter object with the following methods: - - * `filter.get()`: Returns all of the log entries that fit the filter. - * `filter.watch(callback)`: Watches for state changes that fit the filter and calls the callback. See [this note](#using-callbacks) for details. - * `filter.stopWatching()`: Stops the watch and uninstalls the filter in the node. Should always be called once it is done. - -##### Watch callback return value - -- `String` - When using the `"latest"` parameter, it returns the block hash of the last incoming block. -- `String` - When using the `"pending"` parameter, it returns a transaction hash of the last add pending transaction. -- `Object` - When using manual filter options, it returns a log object as follows: - - `logIndex`: `Number` - integer of the log index position in the block. `null` when its pending log. - - `transactionIndex`: `Number` - integer of the transactions index position log was created from. `null` when its pending log. - - `transactionHash`: `String`, 32 Bytes - hash of the transactions this log was created from. `null` when its pending log. - - `blockHash`: `String`, 32 Bytes - hash of the block where this log was in. `null` when its pending. `null` when its pending log. - - `blockNumber`: `Number` - the block number where this log was in. `null` when its pending. `null` when its pending log. - - `address`: `String`, 32 Bytes - address from which this log originated. - - `data`: `String` - contains one or more 32 Bytes non-indexed arguments of the log. - - `topics`: `Array of Strings` - Array of 0 to 4 32 Bytes `DATA` of indexed log arguments. (In *solidity*: The first topic is the *hash* of the signature of the event (e.g. `Deposit(address,bytes32,uint256)`), except you declared the event with the `anonymous` specifier.) - -**Note** For event filter return values see [Contract Events](#contract-events) - -##### Example - -```js -var filter = web3.eth.filter('pending'); - -filter.watch(function (error, log) { - console.log(log); // {"address":"0x0000000000000000000000000000000000000000", "data":"0x0000000000000000000000000000000000000000000000000000000000000000", ...} -}); - -// get all past logs again. -var myResults = filter.get(); - -... - -// stops and uninstalls the filter -filter.stopWatching(); - -``` - -*** - -#### web3.eth.contract - - web3.eth.contract(abiArray) - -Creates a contract object for a solidity contract, which can be used to initiate contracts on an address. -You can read more about events [here](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI#example-javascript-usage). - -##### Parameters - -1. `Array` - ABI array with descriptions of functions and events of the contract. - -##### Returns - -`Object` - A contract object, which can be initiated as follows: - -```js -var MyContract = web3.eth.contract(abiArray); - -// instantiate from an existing address -var myContractInstance = MyContract.at(myContractAddress); - -// Create the contract async -var myContract = MyContract.new(param1, param2, { - data: myContractCode, - gas: 300000, - from: mySenderAddress}, function(err, contract){ - if(!err) { - // The callback will fire after the contract is mined - // Note that the returned "myContract" === "myContractInstance" - console.log(myContractInstance.address) // "0xc4abd0339eb8d57087278718986382264244252f" - console.log(myContractInstance.transactionHash) // The hash of the transaction, which created the contract - } - }); - -// Create contract sync: Then the address will be added as soon as the contract is mined. -// Additionally you can watch the transaction by using the "transactionHash" property -var myContractInstance = MyContract.new(param1, param2, {data: myContractCode, gas: 300000, from: mySenderAddress}); -myContractInstance.transactionHash // The hash of the transaction, which created the contract -myContractInstance.address // undefined at start, but will be auto-filled later -``` - -##### Example - -```js -// contract abi -var abi = [{ - name: 'myConstantMethod', - type: 'function', - constant: true, - inputs: [{ name: 'a', type: 'string' }], - outputs: [{name: 'd', type: 'string' }] -}, { - name: 'myStateChangingMethod', - type: 'function', - constant: false, - inputs: [{ name: 'a', type: 'string' }, { name: 'b', type: 'int' }], - outputs: [] -}, { - name: 'myEvent', - type: 'event', - inputs: [{name: 'a', type: 'int', indexed: true},{name: 'b', type: 'bool', indexed: false] -}]; - -// creation of contract object -var MyContract = web3.eth.contract(abi); - -// initiate contract for an address -var myContractInstance = MyContract.at('0xc4abd0339eb8d57087278718986382264244252f'); - -// call constant function -var result = myContractInstance.myConstantMethod('myParam'); -console.log(result) // '0x25434534534' - -// send a transaction to a function -myContractInstance.myStateChangingMethod('someParam1', 23, {value: 200, gas: 2000}); - -// short hand style -web3.eth.contract(abi).at(address).myAwesomeMethod(...); - -// create filter -var filter = myContractInstance.myEvent({a: 5}, function (error, result) { - if (!error) - console.log(result); - /* - { - address: '0x8718986382264244252fc4abd0339eb8d5708727', - topics: "0x12345678901234567890123456789012", "0x0000000000000000000000000000000000000000000000000000000000000005", - data: "0x0000000000000000000000000000000000000000000000000000000000000001", - ... - } - */ -}); -``` - -*** - -#### Contract Methods - -```js -// Automatically determines the use of call or sendTransaction based on the method type -myContractInstance.myMethod(param1 [, param2, ...] [, transactionObject] [, callback]); - -// Explicitly calling this method -myContractInstance.myMethod.call(param1 [, param2, ...] [, transactionObject] [, callback]); - -// Explicitly sending a transaction to this method -myContractInstance.myMethod.sendTransaction(param1 [, param2, ...] [, transactionObject] [, callback]); -``` - -The contract object exposes the contracts methods, which can be called using parameters and a transaction object. - -##### Parameters - -- `String|Number` - (optional) Zero or more parameters of the function. -- `Object` - (optional) The (previous) last parameter can be a transaction object, see [web3.eth.sendTransaction](#web3ethsendtransaction) parameter 1 for more. -- `Function` - (optional) If you pass a callback as the last parameter the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - If its a call the result data, if its a send transaction a created contract address, or the transaction hash, see [web3.eth.sendTransaction](#web3ethsendtransaction) for details. - - -##### Example - -```js -// creation of contract object -var MyContract = web3.eth.contract(abi); - -// initiate contract for an address -var myContractInstance = MyContract.at('0x78e97bcc5b5dd9ed228fed7a4887c0d7287344a9'); - -var result = myContractInstance.myConstantMethod('myParam'); -console.log(result) // '0x25434534534' - -myContractInstance.myStateChangingMethod('someParam1', 23, {value: 200, gas: 2000}, function(err, result){ ... }); -``` - -*** - - -#### Contract Events - -```js -var event = myContractInstance.MyEvent({valueA: 23}, additionalFilterObject) - -// watch for changes -event.watch(function(error, result){ - if (!error) - console.log(result); -}); - -// Or pass a callback to start watching immediately -var event = myContractInstance.MyEvent({valueA: 23}, additionalFilterObject, function(error, result){ - if (!error) - console.log(result); -}); - -``` - -You can use events like [filters](#web3ethfilter) and they have the same methods, but you pass different objects to create the event filter. - -##### Parameters - -1. `Object` - Indexed return values you want to filter the logs by, e.g. `{'valueA': 1, 'valueB': [myFirstAddress, mySecondAddress]}`. By default all filter values are set to `null`. It means, that they will match any event of given type sent from this contract. -2. `Object` - Additional filter options, see [filters](#web3ethfilter) parameter 1 for more. By default filterObject has field 'address' set to address of the contract. Also first topic is the signature of event. - -##### Callback return - - -`Object` - An event object as follows: - -- `args`: `Object` - The arguments coming from the event. -- `event`: `String` - The event name. -- `logIndex`: `Number` - integer of the log index position in the block. -- `transactionIndex`: `Number` - integer of the transactions index position log was created from. -- `transactionHash`: `String`, 32 Bytes - hash of the transactions this log was created from. -- `address`: `String`, 32 Bytes - address from which this log originated. -- `blockHash`: `String`, 32 Bytes - hash of the block where this log was in. `null` when its pending. -- `blockNumber`: `Number` - the block number where this log was in. `null` when its pending. - - -##### Example - -```js -var MyContract = web3.eth.contract(abi); -var myContractInstance = MyContract.at('0x78e97bcc5b5dd9ed228fed7a4887c0d7287344a9'); - -// watch for an event with {some: 'args'} -var myEvent = myContractInstance.MyEvent({some: 'args'}, {fromBlock: 0, toBlock: 'latest'}); -myEvent.watch(function(error, result){ - ... -}); - -// would get all past logs again. -var myResults = myEvent.get(); - -... - -// would stop and uninstall the filter -myEvent.stopWatching(); -``` - -*** - -#### web3.eth.getCompilers - - web3.eth.getCompilers([callback]) - -Gets a list of available compilers. - -##### Parameters - -1. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Array` - An array of strings of available compilers. - -##### Example - -```js -var number = web3.eth.getCompilers(); -console.log(number); // ["lll", "solidity", "serpent"] -``` - -*** - -#### web3.eth.compile.solidity - - web3.eth.compile.solidity(sourceString [, callback]) - -Compiles solidity source code. - -##### Parameters - -1. `String` - The solidity source code. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Object` - Contract and compiler info. - - -##### Example - -```js -var source = "" + - "contract test {\n" + - " function multiply(uint a) returns(uint d) {\n" + - " return a * 7;\n" + - " }\n" + - "}\n"; -var compiled = web3.eth.compile.solidity(source); -console.log(compiled); -// { - "test": { - "code": "0x605280600c6000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa114602e57005b60376004356041565b8060005260206000f35b6000600782029050604d565b91905056", - "info": { - "source": "contract test {\n\tfunction multiply(uint a) returns(uint d) {\n\t\treturn a * 7;\n\t}\n}\n", - "language": "Solidity", - "languageVersion": "0", - "compilerVersion": "0.8.2", - "abiDefinition": [ - { - "constant": false, - "inputs": [ - { - "name": "a", - "type": "uint256" - } - ], - "name": "multiply", - "outputs": [ - { - "name": "d", - "type": "uint256" - } - ], - "type": "function" - } - ], - "userDoc": { - "methods": {} - }, - "developerDoc": { - "methods": {} - } - } - } -} -``` - -*** - -#### web3.eth.compile.lll - - web3. eth.compile.lll(sourceString [, callback]) - -Compiles LLL source code. - -##### Parameters - -1. `String` - The LLL source code. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - The compiled LLL code as HEX string. - - -##### Example - -```js -var source = "..."; - -var code = web3.eth.compile.lll(source); -console.log(code); // "0x603880600c6000396000f3006001600060e060020a600035048063c6888fa114601857005b6021600435602b565b8060005260206000f35b600081600702905091905056" -``` - -*** - -#### web3.eth.compile.serpent - - web3.eth.compile.serpent(sourceString [, callback]) - -Compiles serpent source code. - -##### Parameters - -1. `String` - The serpent source code. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`String` - The compiled serpent code as HEX string. - - -```js -var source = "..."; - -var code = web3.eth.compile.serpent(source); -console.log(code); // "0x603880600c6000396000f3006001600060e060020a600035048063c6888fa114601857005b6021600435602b565b8060005260206000f35b600081600702905091905056" -``` - -*** - -#### web3.eth.namereg - - web3.eth.namereg - -Returns GlobalRegistrar object. - -##### Usage - -see [namereg](https://github.com/ethereum/web3.js/blob/master/example/namereg.html) example - -*** - -### web3.db - -#### web3.db.putString - - web3.db.putString(db, key, value) - -This method should be called, when we want to store a string in the local leveldb database. - -##### Parameters - -1. `String` - The database to store to. -2. `String` - The name of the store. -3. `String` - The string value to store. - -##### Returns - -`Boolean` - `true` if successfull, otherwise `false`. - -##### Example - - param is db name, second is the key, and third is the string value. -```js -web3.db.putString('testDB', 'key', 'myString') // true -``` - -*** - -#### web3.db.getString - - web3.db.getString(db, key) - -This method should be called, when we want to get string from the local leveldb database. - -##### Parameters - -1. `String` - The database string name to retrieve from. -2. `String` - The name of the store. - -##### Returns - -`String` - The stored value. - -##### Example - param is db name and second is the key of string value. -```js -var value = web3.db.getString('testDB', 'key'); -console.log(value); // "myString" -``` - -*** - -#### web3.db.putHex - - web3.db.putHex(db, key, value) - -This method should be called, when we want to store binary data in HEX form in the local leveldb database. - -##### Parameters - -1. `String` - The database to store to. -2. `String` - The name of the store. -3. `String` - The HEX string to store. - -##### Returns - -`Boolean` - `true` if successfull, otherwise `false`. - -##### Example -```js -web3.db.putHex('testDB', 'key', '0x4f554b443'); // true - -``` - -*** - -#### web3.db.getHex - - web3.db.getHex(db, key) - -This method should be called, when we want to get a binary data in HEX form from the local leveldb database. - -##### Parameters - -1. `String` - The database to store to. -2. `String` - The name of the store. - -##### Returns - -`String` - The stored HEX value. - - -##### Example - param is db name and second is the key of value. -```js -var value = web3.db.getHex('testDB', 'key'); -console.log(value); // "0x4f554b443" -``` - -*** - -### web3.shh - -[Whisper Overview](https://github.com/ethereum/wiki/wiki/Whisper-Overview) - -##### Example - -```js -var shh = web3.shh; -``` - -*** - -#### web3.shh.post - - web3.shh.post(object [, callback]) - -This method should be called, when we want to post whisper message to the network. - -##### Parameters - -1. `Object` - The post object: - - `from`: `String`, 60 Bytes HEX - (optional) The identity of the sender. - - `to`: `String`, 60 Bytes HEX - (optional) The identity of the receiver. When present whisper will encrypt the message so that only the receiver can decrypt it. - - `topics`: `Array of Strings` - Array of topics `Strings`, for the receiver to identify messages. - - `payload`: `String|Number|Object` - The payload of the message. Will be autoconverted to a HEX string before. - - `priority`: `Number` - The integer of the priority in a rang from ... (?). - - `ttl`: `Number` - integer of the time to live in seconds. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Boolean` - returns `true` if the message was send, otherwise `false`. - - -##### Example - -```js -var identity = web3.shh.newIdentity(); -var topic = 'example'; -var payload = 'hello whisper world!'; - -var message = { - from: identity, - topics: [topic], - payload: payload, - ttl: 100, - workToProve: 100 // or priority TODO -}; - -web3.shh.post(message); -``` - -*** - -#### web3.shh.newIdentity - - web3.shh.newIdentity([callback]) - -Should be called to create new identity. - -##### Parameters - -1. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - - -##### Returns - -`String` - A new identity HEX string. - - -##### Example - -```js -var identity = web3.shh.newIdentity(); -console.log(identity); // "0xc931d93e97ab07fe42d923478ba2465f283f440fd6cabea4dd7a2c807108f651b7135d1d6ca9007d5b68aa497e4619ac10aa3b27726e1863c1fd9b570d99bbaf" -``` - -*** - -#### web3.shh.hasIdentity - - web3.shh.hasIdentity(identity, [callback]) - -Should be called, if we want to check if user has given identity. - -##### Parameters - -1. `String` - The identity to check. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Returns - -`Boolean` - returns `true` if the identity exists, otherwise `false`. - - -##### Example - -```js -var identity = web3.shh.newIdentity(); -var result = web3.shh.hasIdentity(identity); -console.log(result); // true - -var result2 = web3.shh.hasIdentity(identity + "0"); -console.log(result2); // false -``` - -*** - -#### web3.shh.newGroup - -##### Example -```js -// TODO: not implemented yet -``` - -*** - -#### web3.shh.addToGroup - -##### Example -```js -// TODO: not implemented yet -``` - -*** - -#### web3.shh.filter - -```js -var filter = web3.shh.filter(options) - -// watch for changes -filter.watch(function(error, result){ - if (!error) - console.log(result); -}); -``` - -Watch for incoming whisper messages. - -##### Parameters - -1. `Object` - The filter options: - * `topics`: `Array of Strings` - Filters messages by this topic(s). You can use the following combinations: - - `['topic1', 'topic2'] == 'topic1' && 'topic2'` - - `['topic1', ['topic2', 'topic3']] == 'topic1' && ('topic2' || 'topic3')` - - `[null, 'topic1', 'topic2'] == ANYTHING && 'topic1' && 'topic2'` -> `null` works as a wildcard - * `to`: Filter by identity of receiver of the message. If provided and the node has this identity, it will decrypt incoming encrypted messages. -2. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - -##### Callback return - -`Object` - The incoming message: - - - `from`: `String`, 60 Bytes - The sender of the message, if a sender was specified. - - `to`: `String`, 60 Bytes - The receiver of the message, if a receiver was specified. - - `expiry`: `Number` - Integer of the time in seconds when this message should expire (?). - - `ttl`: `Number` - Integer of the time the message should float in the system in seconds (?). - - `sent`: `Number` - Integer of the unix timestamp when the message was sent. - - `topics`: `Array of String` - Array of `String` topics the message contained. - - `payload`: `String` - The payload of the message. - - `workProved`: `Number` - Integer of the work this message required before it was send (?). \ No newline at end of file diff --git a/[Japanese]-License.md b/[Japanese]-License.md deleted file mode 100644 index ce643a3ab..000000000 --- a/[Japanese]-License.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -name: License -category: ---- - -Overview - -The Ethereum Foundation ensures three principles concerning the funds it uses to develop Ethereum: - -- it is both open source software and Free software after the definition of the Free Software Foundation (so-called FOSS); -- no special treatment is given to any single entity concerning the copyright of the software, the Foundation included; -- source-code will not be distributed ahead of binaries. - -However, this is not where the story ends; there are many different licences available that conform to these rules. After considerable discussion, both internal and external together with The Ethereum software collection is distributed under several licences, partly to reflect the different thinking of the minds behind different pieces of software and partly to reflect the need to adapt to real-world issues and opportunities and lay out a strategy to provide the best possible future for the Ethereum community. - -### The Core - -Ethereum の core (核となる部分)には、分散型大衆決定マシンのエンジンとネットワークを担うコードとethereumをサポートする -全てのライブラリが含まれています。: -* libethereum -* libp2p -* libdevcore -* libethcore -* livevm -* libevmface - -Ethereum core は、最もライセンスフリーである概念のもとでリリース予定であり、できるだけ多様な環境で Ethereum が使用されること願っております。閉鎖的な環境においてリリースされる、修正や拡張が必要な場合においても、同様に、フリーソフトとして使用していただくことを願っております。 - -In this way, while we have not arrived at a final licence, we expect to select one of the MIT licence, the MPL licence or the LGPL licence. If the latter is chosen, it will come with an amendment allowing it to be linked to be statically linked to software for which source code is not available. - -In this way, the core of Ethereum, be it C++ or Go, will be available for use in any commercial environment, closed or open source. - -### The Applications - -Ethereum の application は以下を含め、GNUライセンスのもとで配布予定です。 -* Solidityコンパイラ ( Libsolidity , solc ) -* AlethZero -* Mix - -This is to reflect the fact that these pieces of software tend to not, by nature, need to be amalgamated or augmented into a larger, closed-source, whole. There is however, much to be gained through many different members of the Ethereum-community being incentivised to develop on and build out such software. - -In this way we hope our initial version of Solidity and Mix lay down the foundation for others to build upon and improve in the true Free/open-source software manner. - -### The Middleware - -Ethereum の middleware は、以下の3つを含み、Affero licence のもとで配布予定です。これはLGPライセンスの一種のようなものです。 -* Javascriptで書かれた ethereum.js -* webthree libraries -* eth (command line client) - -We wish to allow free development of technologies by allowing linking to arbitrary software, but again would like to incentivise feeding of back-end integration work back into the community, especially regarding the interoperability with legacy systems. \ No newline at end of file diff --git a/[Japanese]-Solidity-Tutorial.md b/[Japanese]-Solidity-Tutorial.md deleted file mode 100644 index 8d7838d55..000000000 --- a/[Japanese]-Solidity-Tutorial.md +++ /dev/null @@ -1,954 +0,0 @@ ---- -name: Solidity Tutorial -category: ---- - -- [Cheat Sheet](#cheatsheet) -- [Tips and Tricks](#tips-and-tricks) - - - - -Solidity は、構文がJavaScriptとよく似た高級言語で、 -EVM(イーサリアム仮想マシン)上で動くコードへとコンパイルされるために設計されました。 -この項では、Solidityの基礎事項を抑え、EVMの知識を深めます。 -より詳細な事項については[Solidity 特記事項(建設中)]()を参照して下さい。 -また、この項では、非開発者向けの言語で書かれておらず、さらに安定版を確約するものでもありません。 - -オンライン・エミュレーターはこちら: - [Solidity in your browser](http://chriseth.github.io/cpp-ethereum), -このリンクはコンパイルのみをサポートしています。 -Contract を実際に走らせたり、Blockchain 上に埋め込んだりするには、 -Alethzero (cpp-client) 等をご使用ください。 - - -## Simple Example - -``` -contract SimpleStorage { - uint storedData; - function set(uint x) { - storedData = x; - } - function get() constant returns (uint retVal) { - return storedData; - } -} -``` -`uint storedData` は、`uint`型の `storedData`という呼び名の状態変数を宣言します。 -(`uint`: unsigned integer of 256 bits) -この変数のアドレス領域はコンパイラによって自動生成されます。 -`set`関数と`get`関数はこの値を引用したり修正したりするのに使われます。 - - -## Subcurrency Example - - -```js -contract Coin { - address minter; - mapping (address => uint) balances; - - event Send(address from, address to, uint value); - - function Coin() { - minter = msg.sender; - } - function mint(address owner, uint amount) { - if (msg.sender != minter) return; - balances[owner] += amount; - } - function send(address receiver, uint amount) { - if (balances[msg.sender] < amount) return; - balances[msg.sender] -= amount; - balances[receiver] += amount; - Send(msg.sender, receiver, amount); - } - function queryBalance(address addr) constant returns (uint balance) { - return balances[addr]; - } -} -``` - - - -このコントラクトでは少し新しい概念が出てきます。 -   - -* まず `address`型です。これは 160 bitの値で、論理数値演算できません。    -* 状態変数`balance`を見て欲しいのですが、これは複雑なデータ型から成り立っており、 -難しい言葉で言うと、`address`型から`uint`型への射(写像) ということになります。 -Mapping(写像)はハッシュテーブルのようなもので、自動的に初期化され、 -どんなkeyに対しても、初期値0(byte表記)を与えます。 -* `Coin`という関数を見てみましょう。 -コードをよく見ると、`contract Code`の中に`function Code`が定義されており、 -コンストラクタであることが見て取れます。 -コンスタラクタでありますから当然、あとでこの関数を呼び出すことはできません。 -この例では、コンストラクタにより、contract 作成者のアドレスが永久的に保存されます。    - `tx`、`block`、`msg`はグローバル変数で魔法のように場所を選びません。 -この3種類の魔法変数によって保持されるメンバにより contract の外部にアクセスすることが可能です。 -* `queryBalance`関数は`constant`宣言がされており、contractの状態を修正できないようにします。 -(まだ完全に修正不可能というわけではない、ということに注意してください) -Solidity 言語では、returns のとる引数には名前がついていて、戻り値は基本、ローカル変数を作成します。 -なので、ここでは、リターン文を記述しなくとも、 `balance = balances[addr];` と書くだけで、戻り値が返ります。 -* `Send` のような event は外部クライアントがブロックチェーンをより効率的に探索できるようにするものです。 -`send` 関数の中にあるようにして、 event が呼び起こされると、このことは、永久的にblockchain 上に保存されます。 -このことについては、あとでもう少し詳しく述べます。 - - - - -## Comments - - -一行コメント (`//`) と 複数行コメント (`/*...*/`) が使えます。 -トリプルスラッシュのコメント (`///`) を用いると、[NatSpec](https://github.com/ethereum/wiki/wiki/Natspec-Example)を導入することができますが、ここでは詳しく述べません。 - - - - -## Types - -現段階で開発済みの 基本型 は  -* booleans `bool` -* integer -* 固定長string / byte配列(bytes0 ~ bytes32) - -の3つです。 -integer は -`int8`/`uint8` から8刻みで、`int256`/`uint256` まで -`uint`/`int` は `uint256`/`int256` の alias なので、同じ型 -`address` 型は `uint160` から派生した型です。 - -Comparisons (`<=`, `!=`, `==`, etc.) の影響力の優劣は、booleans ( `&&`, `||` and `!`の組合せ) より常に小さく、 -また、`&&` and `||` に対しては、short-circuiting rules (短回路優先の法則) が成立することに注意してください。 -たとえば `(0 < 1 || fun())` では最初の命題が常に真で、fun()関数は永遠に呼ばれません。 - -もし、演算子が違う型に適用されたら、 -コンパイラは暗黙のうちに一方を別の演算子へ変換しようとします (代入演算子に関してもあてはまります)。 -一般論としては、この暗黙変換が適用されるのは、構文がしっかりとしているときで、情報は失われません。: -`uint8` は `uint16` ・ `int120` ・ `int256` に変換可能ですが `int8` から `uint256` へはできません。 -さらに、unsigned integers は 同等もしくはそれ以上 のサイズの bytes へ変換可ですが、その逆は不可です。 -`uint160` へ変換可能な型は `address` 型への変換可となります。 - - -コンパイラが暗黙変換を許さない状況であっても、 -あなたが何をしているのか把握している状況では、 -例えば以下のような型変換が可能です。 - -```js -int8 y = -3; -uint x = uint(y); -``` - -この断片的なソースコードにおける `x` の最終状態は、`0xfffff..fd` (64桁の16進コード) となります。 -これは 256 bit の2進数表現における -3 です。 - -変数の型を常に外部で特定する必要はなく、コンパイラが自動的に、その変数が最初にでてくる代入文から、決定します。 - -```js -uint20 x = 0x123; -var y = x; -``` - -ここでは、`y` の型は `uint20` となります。 -ただし関数の引数や、戻り値に `var` は使用できません。 -integer 型と byte 型は定数として宣言できます。 - -```js -uint constant x = 32; -bytes3 constant text = "abc"; -``` - - - -## Integer Literals - -integer 式 の型は、式の計算がされたのちに、さいごに決定されます。 -次の例を見てみましょう。 - -```js -var x = 1 - 2; -``` -`1 - 2` の値は `-1` です。 これが `x` に代入され、`x` の型は `-1` を含みうる最小の型である `int8` となります。 -次にいきましょう。 -今度は少し結果が違います。 - -```js -var one = 1; -var two = 2; -var x = one - two; -``` - -ここでは、`one` と `two` は `uint8`となり、`x` に対しても同じ型が遺伝します。 -`uint8` 型の内部での引き算は、wrapping (`uint8`として処理) されるため、`x` の値は、`255` となります。 - -integer のみで表された計算式であれば、 -一時的には、256bit で表される型の最大の値すら超えることが可能です。 - -```js -var x = (0xffffffffffffffffffff * 0xffffffffffffffffffff) * 0; -``` - -ここでは、`x` は `uint` 型の `0` となります。 - - -## Ether と Time の単位 - -文字としての数値は `wei` , `finney` , `szabo` , `ether` といった単位を取ることができます。 -単位を記述しないと、単位は "wei" となります。例を挙げると、 `2 ether == 2000 finney` は `true` を返します。 -さらに、 `seconds`, `hours`, `days`, `weeks`, `years` といった単位が使用でき、 秒が基本単位となります。 -(結果として a year は常にちょうど 365 days を表します。等等) - - - -## Control Structures - -C/JapaScript 由来の、大部分の(分岐やジャンプといった)制御構造が Solidity で利用可能です。 -ただし、 `switch` と `goto` (Solidity と呼ばれることに注意) は含まれません。 -ということで、`if` , `else` , `while` , `for` , `break` , `continue` , `return` といった制御文が使えます。 -C言語やJavascriptにみられるような、非boolean型からboolean型への型変換は存在せず、 -`if (1) { ... }` は Solidity では無効なものとなります。 - - -## Function Calls - -the current contract の関数は直接呼び出すことができ、 -また再起呼び出しも可能です。 -ナンセンスな事例ですが、次をごらんください。 - -```js -contract c { - function g(uint a) returns (uint ret) { return f(); } - function f() returns (uint ret) { return g(7) + f(); } -} -``` - -`this.g(8);` という表現も関数呼び出しに有効ですが、 -この方法では、関数の呼び出しは message call を介して呼び出されるので、 -直接 jump operation 等により呼び出されるものではありません。 -他の contract の関数呼び出し時、呼び出しで使用されるガスの単価と量は特定されます。 - - -```js -contract InfoFeed { - function info() returns (uint ret) { return 42; } -} -contract Consumer { - InfoFeed feed; - function setFeed(address addr) { feed = InfoFeed(addr); } - function callFeed() { feed.info.value(10).gas(800)(); } -} -``` -`InfoFeed(addr)` という表現は、 -与えられた address 上のコントラクトの型は `InfoFeed` であると宣言し、 -外部型への変換を行い、ここにおいてコンストラクタの遂行はしません。 - -`feed.info.value(10).gas(800)` は関数呼び出しで送られるガスの値と量をローカルでsetするだけであり、 -実際の呼び出しは終わりにある括弧が遂行します。 - - -関数呼び出しにおける引数は名前で指定することができ、順番がバラバラでも構いません。 - -```js -contract c { -function f(uint key, uint value) { ... } -function g() { - f({value: 2, key: 3}); -} -} -``` - -関数や戻り宣言の仮引数名はなくても構いません。 - -```js -contract test { - function func(uint k, uint) returns(uint){ - return k; - } -} -``` - - - -## Special Variables and Functions - -デフォルトのグローバル名前空間に存在する -グローバル変数およびグローバル関数を紹介します。 - - -### Block and Transaction Properties - - - `block.coinbase` (`address`): current block miner's address - - `block.difficulty` (`uint`): current block difficulty - - `block.gaslimit` (`uint`): current block gaslimit - - `block.number` (`uint`): current block number - - `block.blockhash` (`function(uint) returns (bytes32)`): hash of the given block - - `block.timestamp` (`uint`): current block timestamp - - `msg.data` (`bytes`): complete calldata - - `msg.gas` (`uint`): remaining gas - - `msg.sender` (`address`): sender of the message (current call) - - `msg.value` (`uint`): number of wei sent with the message - - `now` (`uint`): current block timestamp (alias for `block.timestamp`) - - `tx.gasprice` (`uint`): gas price of the transaction - - `tx.origin` (`address`): sender of the transaction (full call chain) - -### Cryptographic Functions - - - `sha3(...) returns (bytes32)`: compute the SHA3 hash of the (tightly packed) arguments - - `sha256(...) returns (bytes32)`: compute the SHA256 hash of the (tightly packed) arguments - - `ripemd160(...) returns (bytes20)`: compute RIPEMD of 256 the (tightly packed) arguments - - `ecrecover(bytes32, byte, bytes32, bytes32) returns (address)`: recover public key from elliptic curve signature - - "tightly packed" :複数の引数間の余白をなくしひとまとめにできることを意味します。 -`sha3("ab", "c") == sha3("abc") == sha3(0x616263) == sha3(6382179) = sha3(97, 98, 99)`。 -もし余白が必要ならば、外部型変換が利用可能です。 - -注意事項として、プライベート・ブロックチェーン上においては、`sha256` 、`ripemd160` あるいは `ecrecover` はガス欠になりえます。 -というのは、コントラクトは最初いわゆるプリ・コンパイルされた contract としてコンパイルされ、コントラクトは最初の message を受信してはじめて存在することとなるからです。(インスタンスが生成されるとも言います。) -存在しない(インスタンスが生成されていない)コントラクトへのメッセージはとても高くつき、このためエラーが(ガス欠が)生じるのです。 -この問題への動作対処法ははじめに、(例えば)1 Wei を暗号関数を含む各コントラクトへ送信(初期化)してから、あなたの作成したコントラクト上でそれらのコントラクトを呼び出す形をとります。 -テストネット上や、公式のブロックチェーン上では、(初期の段階であらかじめ初期化されているため、)このようなことは起こりません。 - - - -### Contract Related - - - `this` (current contract's type): the current contract, explicitly convertible to `address` - - `suicide(address)`: suicide the current contract, sending its funds to the given address - -Furthermore, all functions of the current contract are callable directly including the current function. - -## Functions on addresses - -It is possible to query the balance of an address using the property `balance` -and to send Ether (in units of wei) to an address using the `send` function: - -```js -address x = 0x123; -if (x.balance < 10 && address(this).balance >= 10) x.send(10); -``` - -Beware that if `x` is a contract address, its code will be executed together with the `send` call (this is a limitation of the EVM and cannot be prevented). If that execution runs out of gas or fails in any way, the Ether transfer will be reverted. In this case, `send` returns `false`. - -Furthermore, to interface with contracts that do not adhere to the ABI (like the classic NameReg contract), -the function `call` is provided which takes an arbitrary number of arguments of any type. These arguments are ABI-serialized (i.e. also padded to 32 bytes). One exception is the case where the first argument is encoded to exactly four bytes. In this case, it is not padded to allow the use of function signatures here. - -```js -address nameReg = 0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2; -nameReg.call("register", "MyName"); -nameReg.call(bytes4(sha3("fun(uint256)")), a); -``` - -`call` returns a boolean indicating whether the invoked function terminated (`true`) or caused an EVM exception (`false`). It is not possible to access the actual data returned (for this we would need to know the encoding and size in advance). - -In a similar way, the function `callcode` can be used: The difference is that only the code of the given address is used, all other aspects (storage, balance, ...) are taken from the current contract. The purpose of `callcode` is to use library code which is stored in another contract. The user has to ensure that the layout of storage in both contracts is suitable for callcode to be used. - -Both `call` and `callcode` are very low-level functions and should only be used as a *last resort* as they break the type-safety of Solidity. - -Note that contracts inherit all members of address, so it is possible to query the balance of the -current contract using `this.balance`. - -## Order of Evaluation of Expressions - -The evaluation order of expressions is not specified (more formally, the order -in which the children of one node in the expression tree are evaluated is not -specified, but they are of course evaluated before the node itself). It is only -guaranteed that statements are executed in order and short-circuiting for -boolean expressions is done. - -## Arrays - -Both variably and fixed size arrays are supported in state and as parameters of external -functions: - -```js -contract ArrayContract { - uint[2**20] m_aLotOfIntegers; - bool[2][] m_pairsOfFlags; - function setAllFlagPairs(bool[2][] newPairs) external { - // assignment to array replaces the complete array - m_pairsOfFlags = newPairs; - } - function setFlagPair(uint index, bool flagA, bool flagB) { - // access to a non-existing index will throw an exception - m_pairsOfFlags[index][0] = flagA; - m_pairsOfFlags[index][1] = flagB; - } - function changeFlagArraySize(uint newSize) { - // if the new size is smaller, removed array elements will be cleared - m_pairsOfFlags.length = newSize; - } - function clear() { - // these clear the arrays completely - delete m_pairsOfFlags; - delete m_aLotOfIntegers; - // identical effect here - m_pairsOfFlags.length = 0; - } - bytes m_byteData; - function byteArrays(bytes data) external { - // byte arrays ("bytes") are different as they are stored without padding, - // but can be treated identical to "uint8[]" - m_byteData = data; - m_byteData.length += 7; - m_byteData[3] = 8; - delete m_byteData[2]; - } -} -``` - -## Structs - -Solidity provides a way to define new types in the form of structs, which is -shown in the following example: - -```js -contract CrowdFunding { - struct Funder { - address addr; - uint amount; - } - struct Campaign { - address beneficiary; - uint fundingGoal; - uint numFunders; - uint amount; - mapping (uint => Funder) funders; - } - uint numCampaigns; - mapping (uint => Campaign) campaigns; - function newCampaign(address beneficiary, uint goal) returns (uint campaignID) { - campaignID = numCampaigns++; // campaignID is return variable - Campaign c = campaigns[campaignID]; // assigns reference - c.beneficiary = beneficiary; - c.fundingGoal = goal; - } - function contribute(uint campaignID) { - Campaign c = campaigns[campaignID]; - Funder f = c.funders[c.numFunders++]; - f.addr = msg.sender; - f.amount = msg.value; - c.amount += f.amount; - } - function checkGoalReached(uint campaignID) returns (bool reached) { - Campaign c = campaigns[campaignID]; - if (c.amount < c.fundingGoal) - return false; - c.beneficiary.send(c.amount); - c.amount = 0; - return true; - } -} -``` - -The contract does not provide the full functionality of a crowdfunding -contract, but it contains the basic concepts necessary to understand structs. -Struct types can be used as value types for mappings and they can itself -contain mappings (even the struct itself can be the value type of the mapping, although it is not possible to include a struct as is inside of itself). Note how in all the functions, a struct type is assigned to a local variable. This does not copy the struct but only store a reference so that assignments to members of the local variable actually write to the state. - -## Assignment - -The semantics of assignment are a bit more complicated for non-value types like arrays and structs. -Assigning *to* a state variable always creates an independent copy. On the other hand, assigning to a local variable creates an independent copy only for elementary types, i.e. static types that fit into 32 bytes. If structs or arrays (including `bytes`) are assigned from a state variable to a local variable, the local variable holds a reference to the original state variable. A second assignment to the local variable does not modify the state but only changes the referenc. Assignments to members (or elements) of the local variable *do* change the state. - -## Enums - -Enums are another way to create a user-defined type in Solidity. They are explicitly convertible -to and from all integer types but implicit conversion is not allowed. The variable of enum type can be declared as constant. - -```js -contract test { - enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill } - ActionChoices choices; - ActionChoices constant defaultChoice = ActionChoices.GoStraight; - function setGoStraight() - { - choices = ActionChoices.GoStraight; - } - function getChoice() returns (uint) - { - return uint(choices); - } - function getDefaultChoice() returns (uint) - { - return uint(defaultChoice); - } -} -``` - -## Exceptions - -Currently, there are two situations, where exceptions can happen in Solidity: If you access an array beyond its length (i.e. `x[i]` where `i >= x.length`) or if a function called via a message call does not finish properly (i.e. it runs out of gas or throws an exception itself). In such cases, Solidity will trigger an "invalid jump" and thus cause the EVM to revert all changes made to the state. - -It is planned to also throw and catch exceptions manually. - -## Interfacing with other Contracts - -There are two ways to interface with other contracts: Either call a method of a contract whose address is known or create a new contract. Both uses are shown in the example below. Note that (obviously) the source code of a contract to be created needs to be known, which means that it has to come before the contract that creates it (and cyclic dependencies are not possible since the bytecode of the new contract is actually contained in the bytecode of the creating contract). - -```js -contract OwnedToken { - // TokenCreator is a contract type that is defined below. It is fine to reference it - // as long as it is not used to create a new contract. - TokenCreator creator; - address owner; - bytes32 name; - function OwnedToken(bytes32 _name) { - address nameReg = 0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2; - nameReg.call("register", _name); - owner = msg.sender; - // We do an explicit type conversion from `address` to `TokenCreator` and assume that the type of - // the calling contract is TokenCreator, there is no real way to check. - creator = TokenCreator(msg.sender); - name = _name; - } - function changeName(bytes32 newName) { - // Only the creator can alter the name -- contracts are explicitly convertible to addresses. - if (msg.sender == address(creator)) name = newName; - } - function transfer(address newOwner) { - // Only the current owner can transfer the token. - if (msg.sender != owner) return; - // We also want to ask the creator if the transfer is fine. - // Note that this calls a function of the contract defined below. - // If the call fails (e.g. due to out-of-gas), the execution here stops - // immediately (the ability to catch this will be added later). - if (creator.isTokenTransferOK(owner, newOwner)) - owner = newOwner; - } -} -contract TokenCreator { - function createToken(bytes32 name) returns (address tokenAddress) { - // Create a new Token contract and return its address. - return address(new OwnedToken(name)); - } - function changeName(address tokenAddress, bytes32 name) { - // We need an explicit type conversion because contract types are not part of the ABI. - OwnedToken token = OwnedToken(tokenAddress); - token.changeName(name); - } - function isTokenTransferOK(address currentOwner, address newOwner) returns (bool ok) { - // Check some arbitrary condition. - address tokenAddress = msg.sender; - return (sha3(newOwner) & 0xff) == (bytes20(tokenAddress) & 0xff); - } -} -``` - -## Constructor Arguments - -A Solidity contract expects constructor arguments after the end of the contract data itself. -This means that you pass the arguments to a contract by putting them after the -compiled bytes as returned by the compiler in the usual ABI format. - -## Contract Inheritance - -Solidity supports multiple inheritance by copying code including polymorphism. -Details are given in the following example. - -```js -contract owned { - function owned() { owner = msg.sender; } - address owner; -} - -// Use "is" to derive from another contract. Derived contracts can access all members -// including private functions and state variables. -contract mortal is owned { - function kill() { if (msg.sender == owner) suicide(owner); } -} - -// These are only provided to make the interface known to the compiler. -contract Config { function lookup(uint id) returns (address adr) {} } -contract NameReg { function register(bytes32 name) {} function unregister() {} } - -// Multiple inheritance is possible. Note that "owned" is also a base class of -// "mortal", yet there is only a single instance of "owned" (as for virtual -// inheritance in C++). -contract named is owned, mortal { - function named(bytes32 name) { - address ConfigAddress = 0xd5f9d8d94886e70b06e474c3fb14fd43e2f23970; - NameReg(Config(ConfigAddress).lookup(1)).register(name); - } - -// Functions can be overridden, both local and message-based function calls take -// these overrides into account. - function kill() { - if (msg.sender == owner) { - address ConfigAddress = 0xd5f9d8d94886e70b06e474c3fb14fd43e2f23970; - NameReg(Config(ConfigAddress).lookup(1)).unregister(); -// It is still possible to call a specific overridden function. - mortal.kill(); - } - } -} - -// If a constructor takes an argument, it needs to be provided in the header (or modifier-invocation-style at the constructor of the derived contract (see below)). -contract PriceFeed is owned, mortal, named("GoldFeed") { - function updateInfo(uint newInfo) { - if (msg.sender == owner) info = newInfo; - } - - function get() constant returns(uint r) { return info; } - - uint info; -} -``` - -Note that above, we call `mortal.kill()` to "forward" the destruction request. The way this is done -is problematic, as seen in the following example: -```js -contract mortal is owned { - function kill() { if (msg.sender == owner) suicide(owner); } -} -contract Base1 is mortal { - function kill() { /* do cleanup 1 */ mortal.kill(); } -} -contract Base2 is mortal { - function kill() { /* do cleanup 2 */ mortal.kill(); } -} -contract Final is Base1, Base2 { -} -``` - -A call to `Final.kill()` will call `Base2.kill` as the most derived override, but this -function will bypass `Base1.kill`, basically because it does not even know about `Base1`. -The way around this is to use `super`: -```js -contract mortal is owned { - function kill() { if (msg.sender == owner) suicide(owner); } -} -contract Base1 is mortal { - function kill() { /* do cleanup 1 */ super.kill(); } -} -contract Base2 is mortal { - function kill() { /* do cleanup 2 */ super.kill(); } -} -contract Final is Base2, Base1 { -} -``` - -If `Base1` calls a function of `super`, it does not simply call this function on one of its -base contracts, it rather calls this function on the next base contract in the final -inheritance graph, so it will call `Base2.kill()` (note that the final inheritance sequence is --- starting with the most derived contract: Final, Base1, Base2, mortal, owned). Note that the actual function that -is called when using super is not known in the context of the class where it is used, -although its type is known. This is similar for ordinary virtual method lookup. - -### Arguments for Base Constructors - -Derived contracts need to provide all arguments needed for the base constructors. This can be done at two places: - -```js -contract Base { - uint x; - function Base(uint _x) { x = _x; } -} -contract Derived is Base(7) { - function Derived(uint _y) Base(_y * _y) { - } -} -``` - -Either directly in the inheritance list (`is Base(7)`) or in the way a modifier would be invoked as part of the header of the derived constructor (`Base(_y * _y)`). The first way to do it is more convenient if the constructor argument is a constant and defines the behaviour of the contract or describes it. The second way has to be used if the constructor arguments of the base depend on those of the derived contract. - - -### Multiple Inheritance and Linearization - -Languages that allow multiple inheritance have to deal with several problems, one of them being the [Diamond Problem](https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem). Solidity follows the path of Python and uses "[C3 Linearization](https://en.wikipedia.org/wiki/C3_linearization)" to force a specific order in the DAG of base classes. This results in the desirable property of monotonicity but disallows some inheritance graphs. Especially, the order in which the base classes are given in the `is` directive is important. In the following code, Solidity will give the error "Linearization of inheritance graph impossible". -```js -contract X {} -contract A is X {} -contract C is A, X {} -``` -The reason for this is that `C` requests `X` to override `A` (by specifying `A, X` in this order), but `A` itself requests to override `X`, which is a contradiction that cannot be resolved. - -A simple rule to remember is to specify the base classes in the order from "most base-like" to "most derived". - -## Abstract Contracts - -Contract functions can lack an implementation as in the following example (note that the function declaration header is terminated by `;`). -```js -contract feline { - function utterance() returns (bytes32); -} -``` -Such contracts cannot be compiled (even if they contain implemented functions alongside non-implemented functions), but they can be used as base contracts: -```js -contract Cat is feline { - function utterance() returns (bytes32) { return "miaow"; } -} -``` -If a contract inherits from an abstract contract and does not implement all non-implemented functions by overriding, it will itself be abstract. - -## Visibility Specifiers - -Functions and state variables can be specified as being `public`, `internal` or `private`, where the default for functions is `public` and `internal` for state variables. In addition, functions can also be specified as `external`. - -`external`: External functions are part of the contract interface and they can be called from other contracts and via transactions. An external function `f` cannot be called internally (i.e. `f()` does not work, but `this.f()` works). Furthermore, all function parameters are immutable. - -`public`: Public functions are part of the contract interface and can be either called internally or via messages. For public state variables, an automatic accessor function (see below) is generated. - -`internal`: Those functions and state variables can only be accessed internally, i.e. from within the current contract or contracts deriving from it without using `this`. - -`private`: Private functions and state variables are only visible for the contract they are defined in and not in derived contracts. - -```js -contract c { - function f(uint a) private returns (uint b) { return a + 1; } - function setData(uint a) internal { data = a; } - uint public data; -} -``` - -Other contracts can call `c.data()` to retrieve the value of data in state storage, but are not able to call `f`. Contracts derived from `c` can call `setData` to alter the value of `data` (but only in their own state). - -## Accessor Functions - -The compiler automatically creates accessor functions for all public state variables. The contract given below will have a function called `data` that does not take any arguments and returns a uint, the value of the state variable `data`. The initialization of state variables can be done at declaration. - -```js -contract test { - uint public data = 42; -} -``` - -The next example is a bit more complex: - -```js -contract complex { - struct Data { uint a; bytes3 b; mapping(uint => uint) map; } - mapping(uint => mapping(bool => Data[])) public data; -} -``` - -It will generate a function of the following form: -```js -function data(uint arg1, bool arg2, uint arg3) returns (uint a, bytes3 b) -{ - a = data[arg1][arg2][arg3].a; - b = data[arg1][arg2][arg3].b; -} -``` - -Note that the mapping in the struct is omitted because there is no good way to provide the key for the mapping. - -## Fallback Functions - -A contract can have exactly one unnamed -function. This function cannot have arguments and is executed on a call to the contract if -none of the other functions matches the given function identifier (or if no data was supplied at all). - -```js -contract Test { - function() { x = 1; } - uint x; -} - -contract Caller { - function callTest(address testAddress) { - Test(testAddress).call(0xabcdefgh); // hash does not exist - // results in Test(testAddress).x becoming == 1. - } -} -``` - -## Function Modifiers - -Modifiers can be used to easily change the behaviour of functions, for example to automatically check a condition prior to executing the function. They are inheritable properties of contracts and may be overridden by derived contracts. - -```js -contract owned { - function owned() { owner = msg.sender; } - address owner; - - // This contract only defines a modifier but does not use it - it will - // be used in derived contracts. - // The function body is inserted where the special symbol "_" in the - // definition of a modifier appears. - modifier onlyowner { if (msg.sender == owner) _ } -} -contract mortal is owned { - // This contract inherits the "onlyowner"-modifier from "owned" and - // applies it to the "kill"-function, which causes that calls to "kill" - // only have an effect if they are made by the stored owner. - function kill() onlyowner { - suicide(owner); - } -} -contract priced { - // Modifiers can receive arguments: - modifier costs(uint price) { if (msg.value >= price) _ } -} -contract Register is priced, owned { - mapping (address => bool) registeredAddresses; - uint price; - function Register(uint initialPrice) { price = initialPrice; } - function register() costs(price) { - registeredAddresses[msg.sender] = true; - } - function changePrice(uint _price) onlyowner { - price = _price; - } -} -``` - -Multiple modifiers can be applied to a function by specifying them in a whitespace-separated list and will be evaluated in order. Explicit returns from a modifier or function body immediately leave the whole function, while control flow reaching the end of a function or modifier body continues after the "_" in the preceding modifier. Arbitrary expressions are allowed for modifier arguments and in this context, all symbols visible from the function are visible in the modifier. Symbols introduced in the modifier are not visible in the function (as they might change by overriding). - -## Events - -Events allow the convenient usage of the EVM logging facilities. Events are inheritable members of contracts. When they are called, they cause the arguments to be stored in the transaction's log. Up to three parameters can receive the attribute `indexed` which will cause the respective arguments to be treated as log topics instead of data. The hash of the signature of the event is one of the topics except you declared the event with `anonymous` specifier. All non-indexed arguments will be stored in the data part of the log. Example: - -```js -contract ClientReceipt { - event Deposit(address indexed _from, bytes32 indexed _id, uint _value); - function deposit(bytes32 _id) { - Deposit(msg.sender, _id, msg.value); - } -} -``` -Here, the call to `Deposit` will behave identical to -`log3(msg.value, 0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20, sha3(msg.sender), _id);`. Note that the large hex number is equal to the sha3-hash of "Deposit(address,bytes32,uint256)", the event's signature. - -### Additional Resources for Understanding Events: - -- Javascript documentation: -- Example usage of events: -- How to access them in js: - -## Layout of State Variables in Storage - -Statically-sized variables (everything except mapping and dynamically-sized array types) are laid out contiguously in storage starting from position `0`. Multiple items that need less than 32 bytes are packed into a single storage slot if possible, according to the following rules: - -- The first item in a storage slot is stored lower-order aligned. -- Elementary types use only that many bytes that are necessary to store them. -- If an elementary type does not fit the remaining part of a storage slot, it is moved to the next storage slot. -- Structs and array data always start a new slot and occupy whole slots (but items inside a struct or array are packed tightly according to these rules). - -The elements of structs and arrays are stored after each other, just as if they were given explicitly. - -Due to their unpredictable size, mapping and dynamically-sized array types use a `sha3` -computation to find the starting position of the value or the array data. These starting positions are always full stack slots. - -The mapping or the dynamic array itself -occupies an (unfilled) slot in storage at some position `p` according to the above rule (or by -recursively applying this rule for mappings to mappings or arrays of arrays). For a dynamic array, this slot stores the number of elements in the array. For a mapping, the slot is unused (but it is needed so that two equal mappings after each other will use a different hash distribution). -Array data is located at `sha3(p)` and the value corresponding to a mapping key -`k` is located at `sha3(k . p)` where `.` is concatenation. If the value is again a -non-elementary type, the positions are found by adding an offset of `sha3(k . p)`. - -So for the following contract snippet: -```js -contract c { - struct S { uint a; uint b; } - uint x; - mapping(uint => mapping(uint => S)) data; -} -``` -The position of `data[4][9].b` is at `sha3(uint256(9) . sha3(uint256(4) . uint(256(1))) + 1`. - -## Esoteric Features - -There are some types in Solidity's type system that have no counterpart in the syntax. One of these types are the types of functions. But still, using `var` it is possible to have local variables of these types: - -```js -contract FunctionSelector { - function select(bool useB, uint x) returns (uint z) { - var f = a; - if (useB) f = b; - return f(x); - } - function a(uint x) returns (uint z) { - return x * x; - } - function b(uint x) returns (uint z) { - return 2 * x; - } -} -``` - -Calling `select(false, x)` will compute `x * x` and `select(true, x)` will compute `2 * x`. - - -## Internals - the Optimizer - -The Solidity optimizer operates on assembly, so it can be and also is used by other languages. It splits the sequence of instructions into basic blocks at JUMPs and JUMPDESTs. Inside these blocks, the instructions are analysed and every modification to the stack, to memory or storage is recorded as an expression which consists of an instruction and a list of arguments which are essentially pointers to other expressions. The main idea is now to find expressions that are always equal (on every input) and combine them into an expression class. The optimizer first tries to find each new expression in a list of already known expressions. If this does not work, the expression is simplified according to rules like `constant` + `constant` = `sum_of_constants` or `X` * 1 = `X`. Since this is done recursively, we can also apply the latter rule if the second factor is a more complex expression where we know that it will always evaluate to one. Modifications to storage and memory locations have to erase knowledge about storage and memory locations which are not known to be different: If we first write to location x and then to location y and both are input variables, the second could overwrite the first, so we actually do not know what is stored at x after we wrote to y. On the other hand, if a simplification of the expression x - y evaluates to a non-zero constant, we know that we can keep our knowledge about what is stored at x. - -At the end of this process, we know which expressions have to be on the stack in the end and have a list of modifications to memory and storage. This information is stored together with the basic blocks and is used to link them. Furthermore, knowledge about the stack, storage and memory configuration is forwarded to the next block(s). If we know the targets of all JUMP and JUMPI instructions, we can build a complete control flow graph of the program. If there is only one target we do not know (this can happen as in principle, jump targets can be computed from inputs), we have to erase all knowledge about the input state of a block as it can be the target of the unknown JUMP. If a JUMPI is found whose condition evaluates to a constant, it is transformed to an unconditional jump. - -As the last step, the code in each block is completely re-generated. A dependency graph is created from the expressions on the stack at the end of the block and every operation that is not part of this graph is essentially dropped. Now code is generated that applies the modifications to memory and storage in the order they were made in the original code (dropping modifications which were found not to be needed) and finally, generates all values that are required to be on the stack in the correct place. - -These steps are applied to each basic block and the newly generated code is used as replacement if it is smaller. If a basic block is split at a JUMPI and during the analysis, the condition evaluates to a constant, the JUMPI is replaced depending on the value of the constant, and thus code like -```js -var x = 7; -data[7] = 9; -if (data[x] != x + 2) - return 2; -else - return 1; -``` -is simplified to code which can also be compiled from -```js -data[7] = 9; -return 1; -``` -even though the instructions contained a jump in the beginning. - -## Tips and Tricks - - * Use `delete` on arrays to delete all its elements. - * Use shorter types for struct elements and sort them such that short types are grouped together. This can lower the gas costs as multiple SSTORE operations might be combined into a single (SSTORE costs 5000 or 20000 gas, so this is what you want to optimise). Use the gas price estimator (with optimiser enabled) to check! - * Make your state variables public - the compiler will create [getters](#accessor-functions) for you for free. - * If you end up checking conditions on input or state a lot at the beginning of your functions, try using [modifiers](#function-modifiers) - -## Cheatsheet - -### Global Variables - - - `block.coinbase` (`address`): current block miner's address - - `block.difficulty` (`uint`): current block difficulty - - `block.gaslimit` (`uint`): current block gaslimit - - `block.number` (`uint`): current block number - - `block.blockhash` (`function(uint) returns (bytes32)`): hash of the given block - - `block.timestamp` (`uint`): current block timestamp - - `msg.data` (`bytes`): complete calldata - - `msg.gas` (`uint`): remaining gas - - `msg.sender` (`address`): sender of the message (current call) - - `msg.value` (`uint`): number of wei sent with the message - - `now` (`uint`): current block timestamp (alias for `block.timestamp`) - - `tx.gasprice` (`uint`): gas price of the transaction - - `tx.origin` (`address`): sender of the transaction (full call chain) - - `sha3(...) returns (bytes32)`: compute the SHA3 hash of the (tightly packed) arguments - - `sha256(...) returns (bytes32)`: compute the SHA256 hash of the (tightly packed) arguments - - `ripemd160(...) returns (bytes20)`: compute RIPEMD of 256 the (tightly packed) arguments - - `ecrecover(bytes32, byte, bytes32, bytes32) returns (address)`: recover public key from elliptic curve signature - - `this` (current contract's type): the current contract, explicitly convertible to `address` - - `super`: the contract one level higher in the inheritance hierarchy - - `suicide(address)`: suicide the current contract, sending its funds to the given address - - `
.balance`: balance of the address in Wei - - `
.send(uint256) returns (bool)`: send given amount of Wei to address, returns `false` on failure. - -### Function Visibility Specifiers - -```js -function myFunction() returns (bool) { - return true; -} -``` - - - `public`: visible externally and internally (creates accessor function for storage/state variables) - - `private`: only visible in the current contract - - `external`: only visible externally (only for functions) - i.e. can only be message-called (via `this.fun`) - - `internal`: only visible internally - -### Modifiers - - - `constant` for state variables: Disallows assignment (except initialisation), does not occupy storage slot. - - `constant` for functions: Disallows modification of state - this is not enforced yet. - - `anonymous` for events: Does not store event signature as topic. - - `indexed` for event parameters: Stores the parameter as topic. - -### Types - -TODO diff --git "a/[Japanese]-Whisper-\357\274\210\343\202\246\343\202\243\343\202\271\343\203\221\343\203\274\357\274\211.md" "b/[Japanese]-Whisper-\357\274\210\343\202\246\343\202\243\343\202\271\343\203\221\343\203\274\357\274\211.md" deleted file mode 100644 index e052e9520..000000000 --- "a/[Japanese]-Whisper-\357\274\210\343\202\246\343\202\243\343\202\271\343\203\221\343\203\274\357\274\211.md" +++ /dev/null @@ -1,127 +0,0 @@ ---- -name: Whisper -category: ---- - -ユースケース - -* DApps(分散形アプリ)は、互いに少量の情報を出しあう必要があり、一定時間情報を公開したまま保持する。 -例えば分散型の通貨換算所を目指すDAppでは、あるレートで通貨を売って欲しいという要求を記録するために公開された情報を利用する。 -このような使い方においては、何十分何日間と情報を公開している状態が続く。 -オファーは決して取引を強制するものではなく、ただ潜在的な取引の始まりを示唆しているだけである。 - -* 分散形アプリは、あるトランザクションにおいて究極的に協力する関係を持つために -お互いに信号を送り合う必要がある。 -例えば分散形の通貨取引所アプリは、1つの取引を作成する前に(交換所に依っては2つの取引)、 -オファーを調整するためにお互いの信号を利用する必要がある。 - -* リアルタイムではない情報を提供する必要がある、もしくは互いに -一般的な通信を行う必要がある分散形のアプリの例は、例えば小さなチャットルームの部屋だ。 - -* 分散形のアプリは、お互いのことを何も分からないがハッシュだけは分かる2つの通信者に対して -見えない通信を提供する必要がある。(全体のネットワークを通じた解析に対して合理的な拒否を行う) -不正告発者が、著名なジャーナリストにコンタクトをとり、少量の証明可能な情報をやりとりし、 -そして、何か他のプロトコル(Swarm, かもしれない)によって、大量の通信を出来るようにするある分散形のアプリかもしれない。 - -一般的にトランザクションを考えると、出来事が記された記録がなかったとしても、 -あらゆる必要な物事は、言ったことや、自動執行や、状態の変更に結びついている。 - -仕様 - -* Low-level 低位のAPIは分散形アプリにのみ提供され、ユーザーには決して提供されない。 -* Low-bandwidth 低位の通信帯は大きなデータの通信には利用されない。 -* Uncertaing-latency 不確実な遅れはRTCには利用されない -* Dark パケットを追跡するための方法は無い。 -* Typical Usage: -** Low-latency 遅延の少ないメッセージは1対1や、1対Nでのメッセージを送る際に使われる。 -** High-latency 遅延は大きいが、生存時間(TTL)の長いメッセージは、メッセージを公開する際に使用される。 -メッセージは64Kバイト未満であり、一般的には約256バイトである。 - -既存の解決策 -* UDP: APIレベルでよく似ていて、ネイティブのマルチキャスティング。生存時間は設定されておらず、セキュリティや、プライバシーの保護もない。 -* [0MQ](http://zeromq.org/): 分散形のメッセージシステム。何もプライバシーの保護機能は備わっていない。 -* [Bitmessage](https://bitmessage.org/wiki/Main_Page): P2Pのネットワーク上でのメッセージ交換システムと似ている。 -高位のプロトコルで、決まった生存期間(TTL)を持ち、スループットに対しての調整機能を持たない。 -* [TeleHash](https://github.com/telehash/telehash.org/blob/master/network.md#paths): 安全な通信を目指したRTC通信。Bittorrentの方法と似ている。(修正版Kademila Techを使用), -だが与えられたハッシュのピアーを見つけるよりも、与えられたハッシュの受信者を見つける。 -DHTを使って決定論的なルーティングを行うため、それゆえに大規模な攻撃に対しての単純で解析的なパケット解析攻撃に脆弱である、 -接続を主目的としているため、生存期間(TTL)や、非同期的な通信の公開のために作られていない。 -* [Tox](https://github.com/irungentoo/toxcore/blob/master/docs/updates/DHT.md): 高位(IM & AV チャット)の補完を目的として作られた。 - -### 基本的なデザイン - -Uses the `"shh"` protocol string of ÐΞVP2P. - -残りはもうじき公開される。一度プロトタイピングは完了した。by Gav -### トラフィック解析を出来なくすることが考慮されている。 - -(Lokiverloren より) -既に存在する位置情報が覆い隠されているインスタントメッセージサービスを目的としている全てのプロトコルは、 -ルーティングに対処するための複雑な問題を抱えている。 - -Bitmessageプロトコルでは、メッセージを匿名でネットワークに公開するが、 -適切な受信者がどうやって復号化して受け取るのかを知る必要がある(他のメッセージツールと丁度同じように)。 -だが、メッセージを保存後、ユーザーが新しいメッセージを得られたことを知る事が出来る。 -問題は全体のネットワークに公開される情報量が著しく増えるに連れて、 -理想的な状態では用意にアクセスされるべきではない暗号化された通信が全体のネットワークに公開されることだ。 - -上記のどの通信プロトコルもとりわけメッセージの出処とその行き先を隠すということについての方法がない。 -そのため、私はウィスパープロトコルの1つの主目的は送信者と受信者の位置情報を匿名化して、 -中継点からにその他、もしくは双方との接続を不可能ではないにしても難しくすることである。 - -Tor システムは2つのノードの間でお互いの位置情報を知ること無く接続を確立する事が出来るプロトコルを持っている。 -それは隠されたサービスを提供するために使われているランデブープロトコルによるものである。 -この記事の読者の大半は、既にどのようにして動くかを知っているだろう。 -だがどのようにして動いているかといえば、隠されたサービス(TCP/IP通信中のポートを聞くサーバーと同様のサービス) -が通信紹介者のノード達の間からランダムな番号を選び出す(通常は6であると筆者は思う)。 -そのためには、一般的な3-hopで届く導入者への接続を確立し、 -ユーザーが隠されたサービスとのコネクションを確立しようと望んだ時には、 -特定の公開鍵と組となる隠されたサービスへと接続しようとするリクエストを発信する必要がある。 - -どのようにしてリクエストが伝播するのかについては確かな確信が無いが、 -明らかに円形の回線かランデブー型のTor導入者のノードが、 -どのノードが回線を創りだそうとしているのかを知っていることによって、 -隠されたサービスへの接続のためのリクエストの伝播が為されている。 -一旦クライアントが有効な接続可能なランデブーノードを知れば、コネクションを確立し、 -隠されたサービスへランデブーノードを中継して、トラフィックを持つことが出来るようにリクエストを送る - -通信接続のプロトコルを隠すための実装としてあまり良いもので内容に思う。 -何故ならば、クライアントのノードとしてノード間を伝わっていくために異なるIDが必要となるためだ。 -同様の原理はEthereum にも当てはまる。 - -しかしながらランデブーを使用することによって、再度互いのことを知っているノード間の接続 -(たとえお互いのアカウントやIDや通信開始者を知らないにしても)が出来るようにし、 -3hop 回線を形成するよりも何か。 - -Tor上の出口となるノードへと繋がる回線を形成するためには、クライアントが通信中のホップのリレーのIDを知る事が危険でない -だが、そのためには、"ネットワーク内で" 位置情報を難読化するセキュリティに対しての脆弱性がある。 -貴方のルーターのIDと、貴方のEthereumのIDを結びつける(筆者は明白にイーサリウムのノードが実行する、ルーティングの機能を公開する必要があると考える。)ランデブーノードに接続する際に、あなたの位置情報をランデブーに対して公開しない。 -そしてランデブーノードは隠されたサービスの位置情報を知ることもない。 -そして、ルーターが創りだされる公開ディレクトリの情報だけを必要とするこれらの通信を確立する。 - -攻撃者にとって結果として手に入る情報ではなく、 -貴方のIPアドレスに関係するサーバーを直接調べることによって明かされてしまうかもしれない。 - -この議論に対して私は下記を述べたい。 - -1. ウィスパーのプロトコルはTorのような位置情報を匿名化するシステムを通して動く必要があると、上記の事実は示唆している。 -それだけでなく、Torが隠されたサービスのために用いているランデブープロトコルを形成する形式を用いなければならない。 - -2. しかしながら、Torは元来ウェブサーバーが貴方のIPアドレス(セッションのクッキーと記録と関連する)を記録することを防ぐための手段を第一義として設計された。そして第二義的に、TCP/IPルーティング(ポート)の通信の同様の手段を実装するための機能が付け加えられた。ランデブープロトコルを形成して位置情報を匿名化するという文脈の中で最初の目的を達成するために残った中間生成物が、3hop ノードとコネクションを利用する方法の形成へと繋がった。そしてコネクションが無いセッションのようなHTTPで使われているプロトコルよりもむしろオープンなまま残っている。 -そこで私が提言したいことは、特定のコネクションが必要であるために、そこには匿名化のプロセスを混ぜあわせる機会がある。その機会を使うことによって、悪意あるノードが攻撃者に対してデータを集めるためのトラフィックの解析があった場合に、 -コネクションを一層隠されたものに出来るのではないかということだ。 - -例えば、ブラウザとサーバー間のような通常の通信では再び接続を確立するために遅れが生じるので、通信は開いたままで -更にリクエストを送る場合にはセッションのクッキーを保管しておく。セッションのクッキーを保存しておく代わりに、クライアントが隠され隠されたノードへのコネクションの方法を変更することが出来る。 -そのコネクションでは秘密鍵を共有して通信する代わりに、多数の異なる回線を通ったデータの断片、そして受信者は断片がオリジナルのパケットを構成できる様になるまで待たなければならない。確かに(ウィスパーに関連しているだけでなく他の分散形のデータストレージプロトコルにおいても)大きな通信や、様々なパートに分かれた通信においてプロセスを取った匿名化の方法を変えることによって、一層トラフィック解析データを難読化するだろう。 - -メッセージシステムであっても、分散形のファイルシステムであっても、 -只送信されるデータの大きさに対処する必要がある違いだけで、本質的に同様の考察が当てはまる。 - -どのようにしてルーティングを進めるかを決定するための評価指標は、通信遅延だ。 -幾つかの目的に対しては通信遅延が少ないことが求められる、他のいくつかの目的に対しては、 -セキュリティが高いことの方が重要である。 -プロセスの流れの中でパーツに分類された際に、パーツから全体のパッケージへとコンバートするためには、 -全てのパーツが揃っている際にだけ出来るとすることによって、セキュリティを一層向上させる事が出来る。 -一部のパートが傍受されて、完全なメッセージでなかった際には、 -データを組み合わせることは不可能で暗号解析の目的にさえも使用することが出来ない。 \ No newline at end of file diff --git a/[Japenese]-Ethereum-TOC.md b/[Japenese]-Ethereum-TOC.md deleted file mode 100644 index 810bdab91..000000000 --- a/[Japenese]-Ethereum-TOC.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -name: 日本語版 -category: ---- - -# ようこそ Ethereum wiki へ - -この項は ÐΞV によって開発された 次世代型 P2P 技術基盤 について、全情報を集約した wiki であり、イーサリアムコミュニティによって維持されています。次世代型 P2P 技術基盤 は以下の内容を含みます。 -* **Ethereum** : スマートコントラクト開発のために一般化を施した ブロックチェイン -* **Whisper** : イーサリアムによる private low-level datagram コミュニケーション基盤 - -どなたでも GitHub にサインインすることで [browser](https://help.github.com/articles/editing-wiki-pages-via-the-online-interface) や [locally](https://help.github.com/articles/adding-and-editing-wiki-pages-locally) に記事を追加することができます。 - -## 進行状況 - -### Frontier - -Ethereum Frontier は試験段階として現在運用されています。 (2015/5/1) -Frontier についての詳細は [Vinay Gupta's blog post](https://blog.ethereum.org/2015/03/03/ethereum-launch-process/) をご覧ください。 - -## はじめに -Ethereum の基本概念の理解といたしましては [ethereum whitepaper (日本語版) ](https://github.com/ethereum/wiki/wiki/%5BJapanese%5D-White-Paper) や [設計原理 (日本語版)](https://github.com/ethereum/wiki/wiki/%5BJapanese%5D-Design-Rationale--(設計原理)) もしくは論文 [ethereum yellow paper (英語版)](http://gavwood.com/Paper.pdf) をご覧ください。またエンジニアの方は [ethereum development tutorial (日本語版)](https://github.com/ethereum/wiki/wiki/%5BJapanese%5D--Ethereum-Development-Tutorial) をご覧ください。 - -## 仕様 -- [Glossary](https://github.com/ethereum/wiki/wiki/Glossary) と [FAQ](https://github.com/ethereum/wiki/wiki/FAQ) は必ずご覧になってください。 -- [C++言語](https://github.com/ethereum/cpp-ethereum/wiki) と [Go言語](https://github.com/ethereum/go-ethereum/wiki) による実装についての wiki です。 ( Python と Javascript 言語につきましてはもうしばらくお待ちください) - -## ダウンロード -開発中ですが PoC-9 code は以下の git レポジトリの branch からダウンロード可能です: -- https://github.com/ethereum/cpp-ethereum -- https://github.com/ethereum/go-ethereum -- https://github.com/ethereum/pyethereum - -最新情報は [build server](http://build.ethdev.com/console) をご覧ください。 \ No newline at end of file diff --git a/[Persian]-Ethereum-TOC.md b/[Persian]-Ethereum-TOC.md deleted file mode 100644 index 4c37bb10d..000000000 --- a/[Persian]-Ethereum-TOC.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: Ethereum TOC -category: ---- - -### به اتریوم، نسل بعدی قراردادهای هوشمند و نرم افزارهای غیر متمرکز خوش آمدید - -[برگ سفید](https://github.com/ethereum/wiki/wiki/%5BPersian%5D-White-Paper) \ No newline at end of file diff --git a/[Romanian]-Block-Protocol-2.0.md b/[Romanian]-Block-Protocol-2.0.md deleted file mode 100644 index c59fe293b..000000000 --- a/[Romanian]-Block-Protocol-2.0.md +++ /dev/null @@ -1,205 +0,0 @@ ---- -name: Block Protocol 2.0 -category: ---- - -###Block Protocol 2.0 - -Una din principalele critici aduse Ethereum-ului, si in general protocoalelor blockchain de tipul Bitcoin, este problema scalabilitatii. Desi dezvoltatorii de baza ai Bitcoin, si ai altor platforme , cum ar fi Ripple, au continuat sa faca imbunatatiri iterative modului in care blockchain-ul este stocat, incluzand inovatii, cum ar fi separarea de starea (“registrul” sau “setul UTXO”) din lista de tranzactie sau folosind structuri separate de date pentru a stoca cele două pe disc / memorie, nimeni nu a implementat cu succes nici o modalitate de a îmbunătăți limitarea fundamentala pe care fiecare nod complet trebuie să prelucreze fiecare tranzacție. In acest punct, nici Ethereum nu rezolva aceasta problema. Totusi, protocolul block descris aici, si in special mecanismul stack trace, permite sexistenta “light nodes” sigure, care downloadeaza doar header-ele fiecarui block si nu intregul set de tranzactii, mentinand acelasi nivel de securitate pentru utilizatorii sai ca si nodurile intregi, sub asumptia gresita ca cel putin un nod cu putere de minare non-neglijabila( ie. >0.01%) sau ether din sistem este onesta. -Data definitions -Un block intreg este stocat ca: -[ - block_header, - transaction_list, - uncle_list, - stack_trace -] - -Unde: -transaction_list = [ - transaction 0, - transaction 1, - ... -] - -uncle list = [ - uncle_block_header_1, - uncle_block_header_2, - ... -] - -block_header = [ - parent hash, - number, - TRIEHASH(transaction_list), - TRIEHASH(uncle_list), - TRIEHASH(stack_trace), - coinbase address, - state_root, - difficulty, - timestamp, - extra_data, - nonce -] - -stack_trace = [ - [ medhash 0, stkhash 0 ], - [ medhash 1, stkhash 1 ], - ... -] - -Fiecare tranzactie si header al block-ului unchi este in sine furnizat direct sub forma unei liste, si nu intr-o forma serializata. uncle_list si transaction_list sunt listele header-lor block-ului unchi si ale tranzactiilor din block. Retineti ca numarul block, dificultatea si timestamp sunt numere intregi , si prin urmare nu pot incepe cu zero; extra_data si nonce pot fi multimi de cel mult 32 bytea, NU liste, desi aceasta verificare in special nu ar trebui facuta pentru block-ul geneza unde campul extra_data va ocupa multi kilobytes. - state_root este radacina Arborelui Patricia continand perechi (key/value) pentru toate conturile, unde fiecare adresa este reprezentata ca un sir binar 20-byte. La adresa fiecarui cont, valoarea stocata in arborele Merkle Patricia este un sir care este forma RLP serializata a unui obiect de forma: -[ balance, nonce, contract_root ] - -nonce este numarul de tranzactii facute din cont, si este incrementat de fiecare data cand este facuta o tranzactie. Scopul este (1) de a face fiecare tranzactie valida pentru a preveni atacurile reply, si (2) de a face imposibil (mai precis, criptografic nefezabil) construirea unui contract cu acelasi hash ca al unui contract deja existent. balance se refera la balanta contului , denominata in wei. contract_root este radacina unui alt arbore Patricia, continand memoria contractului, daca acel cont este controlat de un contract. Daca un cont nu este controlat de un contract, radacina contractului va fi doar un sir gol. -Pentru a intelege toate cele de mai sus, avem nevoie si de cateva definitii ale functiilor: -def H(x): - if len(rlp.encode(x)) < 32: return x - else: return sha3(rlp.encode(x)) - -def H20(x): - if len(rlp.encode(x)) < 20: return x - else: return sha3(rlp.encode(x))[:12] - -def adjust_difficulty(pdiff,ptime,ntime): - if ntime > ptime + 42: return pdiff - int(pdiff / 1024) - else: return pdiff + int(pdiff / 1024) - -def int_to_bin(n,bytes): - return '' if bytes == 0 else int_to_bin(int(n / 256),bytes - 1) + chr(n % 256) - -def TRIE(objs): - t = Trie() - for i in range(len(objs)): - t.insert(int_to_bin(i,32),rlp.encode(objs[i])) - return t - -def TRIEHASH(objs): - return TRIE(objs).root - -Deasemenea, dorim cateva metode pentru a ne ocupa de tries ca stack-uri -def TRIELEN(trie): - i = 0 - while trie.get(int_to_bin(i,32)): i += 1 - return i - -def TRIETOP(trie): - return trie.get(int_to_bin(TRIELEN(trie)-1,32)) - -def TRIEPOP(trie): - trie.update(int_to_bin(TRIELEN(trie)-1,32),'') - -def TRIEPUSH(trie,node): - trie.update(int_to_bin(TRIELEN(trie),3),node) - -Functia de minare este tentativa si va fi inlocuita odata ce stim ca avem alternative mai bune: -def compute_valid_nonce(header): - header[10] = 0 - while not verify_pow(header): - header[10] += 1 - return header[10] - -def verify_pow(header): - return sha3(sha3(header[:10]) + header[10]) * header[7] <= 2**256 - -Procesul de minare - -Cand se mineaza un block, minerul trece prin urmatorul proces: -1- Take as inputs -• uncle_headers – pentru a fi lista de header-e cunoscute nefolosite ale unchilor -• timestamp pentru a fi timestamp-ul curent -• parent pentru a fi block-ul parinte -• extra_data pentru ca extra data dorita sa fie adaugata block-ului -• coinbase pentru a fi adresa coinbase dorita -• txlist pentru a fi lista de tranzactii ce urmeaza a fi adaugata -2- Set: -• difficulty = adjust_difficulty(parent.difficulty,timestamp,parent.timestamp) -• reward = 15 * 10^18 (provizoriu) -• block_header = [ parent.hash, parent.number + 1, TRIEHASH(txlist), TRIEHASH(uncle_headers), 0, coinbase, 0, difficulty, timestamp, extra_data, 0 ] -3- Initializare: -• state pentru a fi starea de parinte block -• txstack = TRIE(txlist) -• stacktrace = TRIE([]) -4- In timp ce stacktrace.root != '': -• TRIEPUSH(stacktrace,[state.root,txstack.root]) -• Se aplica tranzactia TRIETOP(txstack) la state. -• TRIEPOP(txstack) -• Fie L[0] ... L[m-1] lista de tranzactii noi rezultata de acea tranzactie via MKTX, in ordinea in care au fost produse in timpul executie script. -• Initializati j = m-1. While j >= 0, TRIEPUSH(txstack,L[j]) si j -= 1 -5- Faceti urmatoarele modificari arborelui state (de stare): -• Cresteti balanta coinbase prin reward -• Pentru fiecare unchi u in uncle_headers, cresteti balanta lui u.coinbase prin reward * 13/16 si cresteti balanta lui coinbase prin reward * 1/16 -6- Completati primele doua zerouri in block_header cu state.root si TRIEHASH(stack_trace) -7- Setati nonce = compute_valid_nonce(block_header), si completati zeroul ramas in header-ul block cu valoarea lui - -Block Validation Algorithm -1- Luati ca inputs : -• block pentru a fi header-ul block -• uncle_list pentru a fi lista unchiului block -• transaction_list pentru a fi lista tranzactiei block -• stacktrace pentru a fi stack trace a block-ului -• now pentru a fi timpul actual precum e masurat de CPU-ul minerului -2- Verificati urmatoarele: -• Exista un obiect, care este un block, in baza de date cu block.prevhash ca fiind hash-ul sau? Fie parent acel block. -• Este valid proof of work-ul block-ului? -• Este valid proof of work-ul tuturor header-lor unchi? -• Sunt toti unchii unici si unchi intr-adevar? (ie. Copilul parintelui parintelui, dar nu parintele)? -• Este block.timestamp <= now + 900 and is block.timestamp >= parent.timestamp? -• Este block.number == parent.number + 1? -• Este block.difficulty == adjust_difficulty(parent.difficulty,timestamp,parent.timestamp)? -• Este block.transaction_hash = TRIEHASH(transaction_list)? -• Este block.stacktrace_hash = TRIEHASH(stacktrace)? -• Este block.uncle_hash = H(uncle_list)? -3- Initializare: -• state pentru a fi starea block a block-ului parinte -• txstack = TRIE(transaction_list) -• i = 0 -4- Fie stacktrace[k] = [ M[k], H[k] ], defaulting to '' if k is out of bounds. While i < len(stacktrace): -• Verificati daca state.root == M[i] and txstack.root == H[i] -• Aplicati transaction_list[i] la state. -• Aplicati tranzactia TRIETOP(txstack) la state. -• TRIEPOP(txstack) -• Fie L[0] ... L[m-1] lista de noi tranzactii rezultate de acea tranzactie via MKTX, in ordinea in care au fost produse in timpul executiei scriptului. -• Initializati j = m-1. While j >= 0, TRIEPUSH(txstack,L[j]) and j -= 1 -• Setati i += 1 -5- Faceti urmatoarele modificari la state: -• Cresteti balanta coinbase prin reward -• Pentru fiecaree unchi u in uncle_headers, cresteti balanta de u.coinbase prin reward * 13/16 si cresteti balanta de coinbase prin reward * 1/16 -6- Verificati daca txstack.root == '' -7- Verificati daca state.root == block.state_root -8- Daca orice verificare a esuat, returnati FALSE. Altfel, returnati TRUE. -Daca un block este valid, determinati TD(block) ("total difficulty") pentru noul block.. TD este definit recursiv prin TD(genesis_block) = 0 si TD(B) = TD(B.parent) + sum([u.difficulty for u in B.uncles]) + B.difficulty. Daca noul block are TD mai mare decat block-ul curent, setati block-ul curent la noi block-uri si continuati la urmatorul pas. In caz contrariu, iesiti. -Semi-collaborative Block Validation Via Challenge-Response Protocol -In Ethereum, un "light node"poate fi definit ca un nod care accepta header-e block, si fac verificarea in (2) cu exceptia tranzactiei si verificarilor stacktrace trie hash dar nu fac verificarea in (4) si (6), similar cu verificarea headers-only pe care light nodes o fac in Bitcoin. Light nodes ar stoca, astfel, state roots, si poate o parte a starii, insa nu in intregime. Daca un light node vrea sa stie balanta sau starea contractului unui cont oarecare, poate solicita valoarea altor noduri din retea , alaturi de subsetul minimal al nodurilor arborelui Patricia care dovedeste ca perechea key/value data este intr-adevar in stare. -Desi Ethereum nu poate functiona fara cel putin cateva noduri intregi care proceseaza si verifica fiecare tranzactie care ia loc in retea, acest block protocol este creat pentru a furniza o asigurare oarecum mai slaba: atat timp cat exista cel putin un nod intreg onest, clientii ligh (?) pot fi la fel de siguri si pot furniza aceleasi stimulente spre descentralizare precum nodurile intregi. Mecanismul se bazeaza pe un protocol provocare-raspuns in care un nod intreg poate, sub anumite conditii, sa prezinte o provocare precum o anumita parte din block este invalida, si ar depinde de miner furnizarea unui raspuns legat de ce noduri light pot fi verificate eficient. Daca o provocare ramane necontestata, atunci nodurile light s-ar indoi de acel block. -In validarea algoritmului descris in sectiunea anterioara, retineti ca exista cateva locuri specifice in care un block poate esua: -1. Una din verificarile in (2), separata de verificarea hash-ului trie al listei tranzactiei sau a hash-ului trie trace stack, esueaza. -2. Verificarea hash-ului trie al listei tranzactiei esueaza. -3. Verificarea hash-ului trie al trace stack esueaza -4.Una din verificarile din (4) esueaza pentru i=0 -5. Una din verificarile din (4) reuseste pentru toate ii care indica o tranzactie. Un raspuns trebuie sa contina (1) i, (2) j, dasca este aplicabil, (3) subsetul arborelui Patricia trebuie sa verifice valorile la i si j in trie. -Pentru (5), provocarea de invaliditate consta intr-un index k astfel incat tot pana la indexul k este valid, cu exceptia indexului k. Un raspuns consta in (1) k, (2) intrarile stack trace la k-1 si k impreuna cu subsetul arborelui Patricia pentru a le verifica, (3) un subset de noduri ale arborelui Patricia din state tree trebuie sa verifice calculul. Pentru (4), un raspuns consta doar intr-un subset de noduri ale arborelui Patricia pentru a dovedi intrarea stack trace la indexul 0, de unde doua componente pot fi verificate cu hash-ul listei tranzactiei in block header si parintele block state. Pentru (6), un raspuns functioneaza in acelasi mod ca si in (4), cu exceptia ca verificarea raspunsului necesita atat procesarea ultimei tranzactii cat si recompensarea block a unchilor si a coinbase. -Economics -Exista o imperfectiune in protocolul descris mai sus; este vulnerabil la negarea service attack. Mai exact pentru ca provocarile sunt mult mai usor de produs decat sunt raspunsurile de produs sau verificat, este posibil ca nodurile sa polueze reteaua cu provocari false, fortand nodurile light sa respinga orice block atat timp cat alte noduri sunt incapabile sa tina pasul cu verificarea. Pentru a rezolva acest lucru, introducem o rezolvare simpla:O provocare trebuie sa fie semnata de un nod care fie (1) a minat unul din ultimele 10000 de block-uri , sau (2) care detine cel putin 0.01% din tot etherul. Nodurile light ar tine apoi scoruri de calitate pentru toti peers si ii pot downgrada daca acestia prezinta o provocare ce este contracarata cu succes. Pentru ca aceasta metoda nu este anonima, cererea de inregistrare a unei dovezi de proprietate legata de blockchain adresata nodurilor nu poate fi contracarata prin reconectarea sub o alta adresa IP sau alte mecanisme asemanatoare. -Protocolul poate fi descris intr-u totul ca fiind stimulent-compatibil dupa cum urmeaza: -1. Minerii au stimulentul pentru a inregistra provocari block-urilor minate de alte noduri pentru ca daca o provocare este realizata cu succes si daca acestia mineaza block-ul urmator vor avea oportunitatea de a castiga o recompensa de 0.0625X prin includerea header-ului blocului invalid ca unchi. -2. Minerul unui block, si toti unchii din acel block, au cel putin doar stimulentul de a raspunde provocarilor. -3. Nodurile light au stimulentul de a respecta regulile de validitate ale block-ului, pentru ca toata lumea le respecta, un argument explicat mai pe larg in http://themonetaryfuture.blogspot.ca/2011/07/bitcoin-decentralization-and-nash.html. Fara protocolul provocare-raspuns, acest argument nu se aplica, din cauza costului determinarii daca un block este valid sau nu, care este prohibitiv de mare; cu protocolul , acest rationament nu se mai aplica. -4. Partenerii subtantiali (stakeholders) au stimulentul de a promova integritatea perceputa a sistemului pentru a maximiza valoarea unitatilor de valuta detinute, si astfel pot dori sa ajute activ prin introducerea de provocari si raspunsuri acolo unde este posibil. -5. Statistic vorbind, mult mai mult de 0,01% din agentii din inteeriorul agentilor economici din lumea reala, fie ca sunt motivati sau nu de puterea economica, tind sa fie motivati de considerente altruiste/ideologice.Cota de piata a organizatiilor de binefacere din intreaga lume este o dovada mai mult decat suficienta. - -Comparatia cu Bitcoin -In Bitcoin, se poate crea un protocol provocare-raspuns pentru a atinge o functionalitate similara prin cateva principii similare, dar este un singur mod cheie in care un astfel de protocol in Bitcoin ar fi inadecvat: Taxele pentru mineri. Deoarece Bitcoin nu include un mecanism Arbore-Merkle pentru adaugarea taxelor de tranzactii, singurul mod prin care se poate demonstra ca un block are o anumita suma de taxe de tranzactii este prin procesarea fiecarei tranzactii. Mai mult de atat,in Bitcoin taxele pentru tranzactii merg in totalitate la miner. Astfel, in Bitcoin un nod light nu are cum sa determine daca un anumit block este valid sau daca ii percepe creatorului sau taxe excesive, si se poate baza doar pe majoritatea calculata ca sursa de informatii. In Ethereum, toate schimbarile aduse starii sunt incorporate in stacktrace, astfel nu exista aceasta slabiciune si, avand in vedere ipoteza securitatii subrede ca cel putin un nod intreg cu minim 0.01% putere de minare este onesta, are 100% din proprietatile de securitate pe care le au nodurile intregi. - - - - - - diff --git a/[Romanian]-CLL.md b/[Romanian]-CLL.md deleted file mode 100644 index 3532dec16..000000000 --- a/[Romanian]-CLL.md +++ /dev/null @@ -1,151 +0,0 @@ ---- -name: CLL -category: ---- - -ECLL: Limbaj de programare ethereum, ce seamana cu C++. - -Scopul ECLL este de a furniza un limbaj simplu si accesibil utilizatorilor, folosit pentru a scrie contracte, dar in acelasi timp poate compila usor si eficient script-ul Ethereum. ECLL indeparteaza concepte precum indici, accesaul direct la memorie si favorizarea unei sintaxe traditionale de conditionale, bucle, matrice si variabile. Suportul pentru funcii si suportul de prima clasa pentru functii vor fi atribuite unei viitoare versiuni a acestui limbaj, denumita EHLL ("Ethereum High Level Language"), mai puternica dar mai putin eficienta. - -Specificarea va avea loc in trei parti. Prima parte va defini limbajul ca un arbore de sintaxa abstract, formalizat folosind o sintaxa S-expression, in stilul LISP; a doua parte va oferi specificatiile fiecarei operatiuni efectuate in parte, si a treia va arata cum se poate transpune AST in text. - - - -###Sintaxa arborescenta - -O expresie se defineste astfel: -- un numar e o expresie -- un nume variabil e o expresie -- `("arr" a b) `este o expresie, unde `a` si `b` sunt expresii. Aceasta este echivalentul in C `a[b]`. -- `(OP a b)` e o expresie, unde `OP` se afla in setul `(+ - * / % s/ s% ^ < > <= >= ==)` -- `(OP a)` e o expresie, unde `a` se afla in setul `(- !) ` -- Valorile speciale `tx.datan`, `tx.value`, `tx.sender`, `contract.address`, `block.number`, `block.difficulty`, `block.timestamp`, `block.parenthash` and `block.basefee` sunt expresii -- `("pseudo" a b)` este o expresie, unde `a` este o pseudomatrice and `b` este o expresie -- `("fun" a b...)` este o expresie, unde `a` este o returning function and `b...` contine numarul valid de argumente. - -O pseudofunctie se defineste astfel: -- `block.contract_storage` este o pseudofunctie - -Un pseudoarray se defineste astfel: -- `tx.data` si `contract.storage` sunt pseudomatrici -- `("pfun" a b...)` unde `a` este o pseudofunctie si `b...` contine numarul valid de argumente este o pseudomultime. -`contract.storage` este o pseudomatrice mutabila, si celelalte doua sunt pseudomatrici immutabile. - -O returning function se defineste astfel: -- `block.account_balance`, `sha256`, `sha3`, `ripemd160`, `ecvalid` sunt returning functions -- `array` este o returning function - -O multireturning function se defineste astfel: -- `ecsign` and `ecrecover` sunt multireturning functions - -O multiexpresie se defineste astfel: -- `("mfun" a b...)` unde a este o multireturning function si `b...` contine numarul valid de argumente este o multiexpresie - -O acting function este definita dupa cum urmeaza: -`mktx` este o acting function -O expresie left-hand-side se defineste astfel: -- o variabila este o expresie left-hand-side. -- `("arr" a b)` este o expresie left-hand-side, unde `a` este o expresie left-hand-side si `b` este o expresie -- `("pseudo" a b)` este o expresie left-hand-side, unde `a` este o pseudomatrice mutabila si `b` este o expresie. - -O afirmatie se defineste astfel: -- `("afun" a b...)` unde `a` este o acting function si `b...` contine numarul valid de argumente si o afirmatie -- `("set" a b)` unde `a` este o expresie left-hand-side si `b` este o expresie si o afirmatie -- `("mset" a... b)` unde `a...` este o lista de expresii left-hand-side cu numarul valid de argumente si `b` este o multiexpression si o afirmatie. -- `("seq" a...)` unde `a...` reprezinta afirmatii -- `("if" a b)` unde `a` este o expresie `b` e o afirmatie -- `("if" a1 b1 "elif" a2 b2 "elif" a3 b3 ...)` unde `ak` sunt expresii and `bk` sunt afirmatii -- `("if" a1 b1 "elif" a2 b2 "elif" a3 b3 ... "else" c)` unde `ak` sunt expresii iar `bk` si `c` sunt afirmatii -- `("while" a b)` unde `a` este o expresie si `b` este o afirmatie -- `"exit"`. - -###Definitii: - -Pre-compilarea, daca sunt `n` variabile, fiecarei variabile ii va fi repartizata un index in `[0,n-1]`. Fie `ind(x)` indexul variabilei `x`, si fie `M[x]` contractul de memorie la indexul `x` -In contextul unei expresii right-hand-side: -Aritmetica functioneaza in modul evident. `(* (+ 3 5) (+ 4 8))`, de exemplu, este returnat ca 96. - -• `a && b` este o prescurtare pentru `!(!(a) + !(b))` - -• `a || b` este o prescurtare pentru `!(!(a + b))` -• O variabila `x` trebuie sa devina `M[ind(x)]` -• `("arr" a b)` returneaza `M[M[ind(a)]+b]` -• `tx.datan` returneaza numarul de campuri de date din tranzactie. -• `("pseudo" "tx.data" i)` returneaza campul de date ith in tranzactie sau zero daca `i >= tx.datan` -• `tx.sender`, `tx.value`, `block.basefee`, `block.difficulty`, `block.timestamp`, `block.parenthash` and `contract.address` returneaza valorile evidente. -• `("pseudo "contract.storage" i)` returneaza stocarea contractului la index `i`. -• `("fun" "block.account_balance" a)` returneaza balanta adresei `a` -• `("pseudo" ("pfun" "block.contract_storage" a) b)` returneaza stocarea contractului apartinand contului `a` la indexul `b` -• `("mfun" "ecsign" hash key)` retuneaza ternarul `v,r,s` din semnatura -• `("mfun" "ecrcover" h v r s)` returneaza cheia publica `x,y` -• `("mfun" "sha256" len arr)` returneaza hash-ul SHA256 al sirului de lungimea len incepand de la `M[ind(arr)]`. La fel si `sha3` si `ripemd160work`. -• `("fun" "array")` returneaza `2^160 + M[2^256 - 1]` si seteaza `M[2^256 - 1] <- 2^160 + M[2^256 - 1]` -In contextul unei expresii left-hand-side: -• O variabila `x` returneaza `ind(x)` -• `("arr" a b)` returneaza `a + b` unde `a` si `b` au fost deja evaluate -• `("pseudo" a b)` returneaza un obiectcare, daca este setat, modifica valoarea pseudomatricei referente la indexul `a` la `b` in loc sa faca un memory set. -In contextul unei afirmatii: -• `("afun" "mktx" dest value dn ds)` creeaza o tranzactie trimitand `value` ether la `dest` cu campurile de date `dn` incepand de la `M[ind(ds)]` -• `("set" a b) sets M[a] <- b` unde `a` si `b` au fost deja evaluate -• `("mset" a... b)` seteaza secvential indexul de memorie la fiecare din valorile `a...` la o valoare din multiexpresia `b` -• `("if" a b), ("while" a b)` si derivatele vor functiona asa cum functioneaza si in alte limbaje. -###Sintaxa -• Din punct de vedere aritmetic se realizeaza folosind notatii infixe folosind C++ operator cu prioritate: `^` then `* / % s/ s%` then `+ -` then `< <= > >=` then `==` then `&&` then `||`.Adica, formulele aritmetice se vor comporta cum se comporta in mod normal; de exemplu, `(+ (* 3 5) (* x y))` ar fi `(3 * 5 + x * y)` si `(* (+ 3 5) (+ x y))` ar fi `((3 + 5) * (x + y))` -• `("arr" a b)` si `("pseudo" a b)` vor fi reprezentate de `a[b]` -• `("fun" a b...)`, `("mfun" a b...)`, `("afun" a b...)` si `("pfun" a...)` vor fi toate reprezentate ca `a(b1,b2, ... ,bn)` -• Multiexpresiile vor fi reprezentate ca `a1, a2, ... an` -• `("set" a b)` si `("mset a... b)` vor fi reprezentate ca `a = b` si respectiv `a1, a2 ...` ,`an = b`. -• `("seq" a...)` consta in fiecare din afirmatiile de pe propria linie separata -• `("if" a b)` si `("while" a b)` vor fi reprezentate ca in Python, folosind keyword-ul direct urmat de expresia pentru `a` si afirmatia indented pentru `b` -• Valorile pot fi reprezentate fie ca numere intregi sau in string quotes, in care caz vor fi tratate ca hexadecimale. -• `exit` –se iese. - -###Exemple: - -Factorial: -```python - x = 1 - n = 1 - while x < 10: - n = n * x - x = x + 1 -``` -Secventa Fibonacci: -```python - a = array() - a[0] = 1 - a[1] = 1 - i = 2 - while i < 70: - a[i] = a[i-1] + a[i-2] - i = i + 1 - mktx("0676d13c8d2cf5e9e988cc3b5f6dfb5a6a3938fa",a[69],70,a) -``` -Un exemplu real – un contract simplu de expediere pentru a crea un cont transferabil: -```python - if tx.value < tx.basefee * 200: - exit - else: - a = contract.storage[2^256 - 1] - if !(tx.sender == a) && (tx.sender > 0): - exit - if tx.data[0] == 2^160: - contract.storage[2^256 - 1] = tx.data[1] - else: - if a == 0: - contract.storage[2^256 - 1] = tx.sender - o = array() - i = 0 - while i < tx.datan - 1: - o[i] = tx.data[i+1] - i = i + 1 - mktx(tx.data[0],tx.value - tx.basefee * 250,i,o) -``` -###Sintaxa alternativa: C++ style - -• `("seq" a...)` este implementat prin separarea afirmatiilor prin semicoloane. Randurile libere sunt ignorate. -• `("if" a b)` si `("while" a b)` vor fi reprezentate ca in C++, stocand `a` intre paranteze si `b` intre acolade. - -###Sintaxa alternativa: Lisp style - -AST este utilizat ca si cod direct , cu modificarea minora urmatoare:`("fun" a b...)`, `("pfun" a b...)` si `("mfun" a b...)` sunt inlocuite cu `(a b...)`. diff --git a/[Romanian]-Cuprins.md b/[Romanian]-Cuprins.md deleted file mode 100644 index 8ea88b630..000000000 --- a/[Romanian]-Cuprins.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -name: Cuprins -category: ---- - -### Ethereum este platforma pe care se vor dezvolta aplicatii descentralizate si noua generatie de smart-contracts. - -[Raportul Ethereum (whitepaper)](https://github.com/ethereum/wiki/wiki/%5BRomanian%5D-White-Paper) - -[RLP](https://github.com/ethereum/wiki/wiki/%5BRomanian%5D-RLP), specificatii pentru prefixul liniar recursiv, folosit pentru codificarea datelor in reteaua Ethereum. - -[Patricia Tree](https://github.com/ethereum/wiki/wiki/%5BRomanian%5D-Patricia-Tree) Specificatii pentru arborele Merkle Patricia (aka Trie), structura folosita pentru stocare si hashing necesare starii blockchainului ethereum. - -[Wire protocol](https://github.com/ethereum/wiki/wiki/%5BRomanian%5D-Wire-Protocol) Specificatii. - -[Serpent](https://github.com/ethereum/wiki/wiki/%5BRomanian%5D-Serpent-programming-language-operations), un limbaj de programare high-level folosit pentru scrierea de smart-contracts. Tutorial [aici](https://github.com/ethereum/wiki/wiki/%5BRomanian%5D-Serpent-programming-language-operations). - -[LLL](https://github.com/ethereum/cpp-ethereum/wiki/LLL), Specificatii pentru limbajul low-level "Lisp-like Language" , folosit pentru definirea contractelor in clientul ethereum incepand cu PoC-3. - -[Dagger](https://github.com/ethereum/wiki/wiki/%5BRomanian%5D-Dagger), Detalii despre algoritmul "proof-of-work". - -[Block Protocol 2.0](https://github.com/ethereum/wiki/wiki/%5BRomanian%5D-Block-Protocol-2.0) - -[Layers](https://github.com/ethereum/wiki/wiki/%5BRomanian%5D-Layers) - -[Clearinghouse](https://github.com/ethereum/wiki/wiki/%5BRomanian%5D-Clearinghouse) \ No newline at end of file diff --git a/[Romanian]-Dagger.md b/[Romanian]-Dagger.md deleted file mode 100644 index 89b6ec0eb..000000000 --- a/[Romanian]-Dagger.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -name: Dagger -category: ---- - -Pe parcursul a celor peste cinci ani de experienta cu Bitcoin si alte cryptocurrencies alternative, o proprietate importanta pentru functiile proof of work ce a fost descoperita este aceaa a “ duritatii memoriei” (memory-hardness)- calcularea unui proof of work valid ar trebui sa necesite nu doar un numar mare de calcule, dar si o memorie mare. Momentan, exista trei categorii majore de functii memory-hard folosite in mining : scrypt, Primecoin mining si the birthday problem. Cu toate acestea sunt imperfecte: nici una nu necesita cantitatea de memorie pe care o cere o functie memory-hard ideala, si supefa de atacuri time-memory tradeoff, unde functia poate fi calculata cu mult mai putina memorie decat este necesar, cu costul de a sacrifica din eficienta computationala. -Dagger este un algoritm proof of work care intentioneaza sa rezolve aceste probleme, furnizand un proof of work memory-hard bazat pe pe grafice aciclice dirijate (directed acyclic graphs –DAG) conectate moderat, care , desi departe de a fi optime, are proprietati de memory-hardness mult mai puternice decat orice alternativa folosita astazi. -Why Be Memory-Hard? -Principalul motiv pentru care memory hardness este importanta este acela de a face functia proof of work rezistenta la harware specializat. Cu Bitcoin, al carui algoritm de mining necesita doar un simplu calcul SHA256, companiile care au existat timp de un an, au creat "application-specific integrated circuits" (ASICs) specializate proiectate si configurate in silicon pentru singurul scop de a calcula milioane de hash-uri SHA256 intr-o incercare de a “mina” un block Bitcoin valid. Aceste cipuri (chips) nu au aplicatii legitime in afara minarii Bitcoin si crack-uirii parolelor, si prezenta acestora, care sunt de mii de ori mai eficiente per dolar si kilowatt/ora la calcularea hash-urilor fata de genericile CPU, fac imposibila o concurenta a utilizatorilor obisnuiti care folosesc hardware generic CPU si GPU. -Aceasta dominatie a hardware-ului specializat are cateva efecte daunatoare severe: -1. Neaga aspectul democratic al distributiei minarii cryptocurrency. Intr-un ecosistem dominat de hardvare generic, faptul ca toata lumea detine un computer garanteaza faptul ca toata lumea va avea sanse egale de a castiga cel putin o parte din oferta de bani initiala. Cu hardware-ul specializat, acest factor nu mai exista;potentialul de minare al fiecarui actor economic este linear (de fapt, usor superlinear) in cantitatea lor de capital pre-existent, poate chiar exacerband inegalitati deja existente in ceea ce priveste capitalul. -2. Creste risipa de resurse. Intr-o piata eficienta,venitul marginal se apropie de costul marginal. Cum venitul din minare este o functie liniara a banilor cheltuiti pe harware-ul de minare si electricitate, implicit venitul total se apropie de costul total. Prin urmare, intr-un ecosistem dominat de hardware specializat, cantitatea de resurse irosite se apropie de 100% din nivelul de securitate al retelei. Intr-un ecosistem dominat de CPU si GPU, deoarece deja toata lumea detine un computer, nimeni nu trebuie sa achizitioneze hardware specializat pentru primele cateva hash-uri pe secunda care detin putere de minare.Deci, venitul este sublinear in cost- toata lumea primeste o parte din venit “pe gratis”. Astfel, cantitatea de resurse irosita de retea este potential mai mica decat parametrul sau de securitate. -3. Centralizeaza minarea in mainile catorva actori. (ie. Producatorii ASIC), facand 51% din atacuri posibile si cu potentialul de a deschide reteaua pentru presiuni de reglementare. -Hardware-ul specializat este atat de puternic deoarece include mii de circuite create special pentru a calcula functia proof of work, permitand hardware-ului sa realizeze aceasta functie de mii de ori in paralel. l. Memory hardness atenueaza aceasta problema stabilind ca principal factor de limitare nu puterea CPU, ci memoria. Se poate face, deasemenea, o imbunatatire modesta prin orientarea clock speed a CPU, dar masura in care astfel de optimizari pot fi facute este fundamental limitata la o valoare foarte scazuta , din considerente tehnologice. Astfel, imbunatatirea prin paralelizare intampina un obstacol: efectuarea a zece calcule memory-hard in paralel nicesita de zece ori mai multa memorie. Producatorii hardware-ului specializat pot ambala cu siguranta terabytes de memorie in dispozitivele lor, insa efectul este atenuat de doi factori. In primul rand, neprofesionistii pot atinge acelasi efect doar prin achizitionarea unor memory cards, iar in al doile arand, memoria este mult mai scumpa ca productie (daca masuram in echivalentul unui laptop) decat SHA256 chips; RAM-ul folosit in computerele obisnuite este deja optim, in esenta. -Obiectii la Memory-Hardness -1. Toti algoritmii vor fi vulnerabili la ASICs, in cele din urma. Acest punct de vedere a devenit mai popular in special dupa recentul anunt al unei companii care produce ASICs pentru Scrypt, si afirma, in esenta, ca teoretic, orice algoritm poate fi facut mai bine cu hardware specializat, asa ca nu are rost sa se incerce directionarea algoritmilor spre hardware-ul general. Ce scapa din vedere acest argument, totusi, este ca speedup-ul din aplicarea hardware-ului specializat la Scrypt-ul moderat memory-hard, a fost demonstrat ca este mult mai jos decat Bitcoin-ul. Mai mult de atat, exista motive pentru a sugera ca acest trend va continua- dupa cum am descris mai sus, memoria din hardware-ul obisnuit este mult mai aproape de un nivel optim fata de circuitele de calcul. -2. Botnets vor prelua controlul asupra procesului de minare. Acest punct poate fi abordat din doua directii: empiric si teoretic. Empiric, botnets pana acum nu au fost implicati substantial in montarea a 51% din atacuri in altcoins, in general sunt multumiti cu extragerea venitului ca mineri “legitimi”. Teoretic, prezentarea publica a botnets ca amenintare este in mare sprijinita de performanta lor in network flooding/denial a service attacks- situatie unde fiecare computer dintr-un botnet este utilizat doar pentru numarul de conexiuni pe care le poate face. In contextul minarii totusi , computerele infectate cu botnet tind sa utilizeze sisteme de operare mai vechi si au specificatii mai slabe, insemnand ca vor avea o performanta mult mai scazuta, la fel ca si impactul asupra retelei, decat sugereaza initial marimea lor. -Alternative existente -Existenta fiecarui nou algoritm, protocol cryptografic primitiv, spre deosebire de tehnologii existente si mai bine testate trebuie sa aiba intotdeauna o justificare puternica; intr-o zona atat de delicata precum cryptocurrency, prudenta este foarte importanta, atat pentru ca sistemul se va ocupa de un capital de milioane de dolari, dar si pentru ca daca se face o singura greseala, nu exista nici o modalitate de upgrade la o versiune mai noua printr-un bugfix. Scopul acestei sectiuni va fi listarea a trei alternative existente si demonstrarea ineficientei lor. -Scrypt -Scrypt este algoritmul folosit de Litecoin, Dogecoin si de majoritatea noilor cryptocurrencies aparute. Odescriere simplificata a algoritmilor asemanatori Scrypt este urmatoarea: -1. Fie H[0] = D+N unde D sta la baza datelor iar N este nonce. -2. Pentru i de la 1 la N fie H[i] = f(H[0] ... H[i-1]) unde f este o functie asemanatoare hash-urilor care ia mai multe intrari, -3. Pentru i de la 1 la M fie R[i] = random([1 ... M]) -4. SCRYPT(D,N) = f(H[R[0]] ... H[R[M]]. Daca SCRYPT(D,N) este destul de scazut, atunci N este un nonce invalid. -Ideea este ca nu exista o modalitate de a calcula practic SCRYPT(D) fara a construi intreaga multime H si de a o pastra in memorie pentru ultimul pas. Totusi, algoritmii Scrypt au o proprietate care limiteaza, in mod inerent, cat de memory-hard pot fi: verificarea necesita calcularea unei runde a intregii functii, astfel ca functia este la fel de memory-hard de verificat pe cat este de calculat. Astfel, in timp ce scrypt poate fi viabil pentru atingerea memory-hardness in jurul a catorva megabytes per theread, este un non-starter pentru memory hardness in zona sutelor de megabytes per thread. De fapt, sute de megabytes per thread sunt discutabil necesari; deja exista companii http://www.cryptocoinsnews.com/2013/11/22/alpha-technologies-offer-scrypt-mining-asics/ care lucreaza pe ASICs pentru scrypt in ziua de astazi. -Primecoin -Algoritmul Primecoin nu este creat pentru a fi memory-hard, dar are aceasta proprietate intr-o anumita masura. Algoritmul cere minerilor sa gaseasca asa-numitele lanturi Cunningham de numere prime- lanturi de forma [ n+1, 2n+1, 4n+1 ... n*2^k+1 ] pentru un k suficient de mare. Dupa cum s-a dovedit, este foarte dificil sa se faca asta pentru orice lungime semnificativa fara a completa intai o data structure cunoscuta ca sita. Avantajul Primecoin este acela ca verificarea este aproape instanta si memory-cheap; tot ce trbuie sa fac utilizatorul este sa ruleze testul primality Fermat pentru a se asigura ca toate valorile sunt numere prime. Cu toate acestea, algoritmul Primecoin are doua slabiciuni in aceasta privinta: -1. '''Time-memory tradeoff''' – un ASIC are optiunea de a inlatura mare parte din memoria necesara prin sacrificarea eficientei de calcul; chiar si cu doar 100 KB per thread un miner poate fi destul de eficient. -2. '''All clear effect''' – dupa cum s-a dovedit, este posibil ca GPU si ASIC sa aiba thread-uri multiple care sa imparta aceeasi memorie. Cum minarea Primecoin necesita ca sita sa fie umpluta doar o singura data, un ASIC poate calcula o sita intai si apoi sa ruleze mii de thread-uri prin ea. -Birthday attack -Algoritmul birthday attack este ingenios, si functioneaza dupa cum urmeaza: -1. Fie H[i] = sha256(D + N + i) pentru i de la 0 la 232 - 1 cu data D si nonce N. -2. Daca abs(H[i] - H[j]) este suficient de scazuta, atunci (N,i,j) este o solutie tripla valida. -Ingenuitatea protocolului vine din faptul ca in timp ce calculeaza eficient, birthday attack necesita stocarea hash-urilor intr-o structura astfel incat fiecare hash nou sa poata fi comparat cu cele anterioare lui, verificarea solutiilor necesita doar checking two hashes. Algoritmul este rezistent impotriva efectelor all-clear deoarece memoria trebuie eliberata (flushed) la fiecare 232 runde. Cu toate acestea, sunt cateva shortcut-uri time-memory tradeoff attacks. In primul rand, se poate optimiza prin doar prin stocarea primilor cativa bytes ai fiecarui hash in loc de primul hash. In al doilea rand, se pot stoca doar hash-uri cu primii doi bits fiind 00; acest lucru scoate din discutie 75% din solutiile posibile, reducand time efficiency de 4x,dar crescand space efficiency de 4x. In cele din urma, exista potential pentru optimizare prin examinarea diferitelor optiuni intre stocarea hash-urilor intr-un sir mare, un arbore red-black sau bianr, si alte structuri mai complexe; algoritmul optim poate fi destul de complicat. - Dagger intentioneaza sa rezolve toate aceste probleme, are o valuta ce este memory-hard pentru computer, dar este memory-easy de verificat, nu are un efect clar , nu are time-memory tradeoff, chiar si la o ratie de 1:1, and for which a close-to-optimal algorithm is the naive one. -Algorithm specification: -Esential, algoritmul Dagger functioneaza prin crearea unui grafic aciclic directionat (termenul tehnic pentru un arbore in care fiecare nod poate avea mai multi parinti) cu un total de 223 - 1 de noduri intr-o secventa. Daca minerul gaseste un nod intre indexul 222 si 223 astfel incat hash-ul rezultat sa fie sub 2256 divizat de parametrul de dificultate, rezultatul este un proof of work valid. -Fie D data de baza (eg. In cazul Bitcoin-ului, header-ul block), N fie nonce si || operatorul concatenarii sirului (ie. 'foo' || 'bar' == 'foobar') . Intregul cod pentru algoritm se desfasoara dupa cum urmeaza: -D(data,xn,0) = sha3(data) -D(data,xn,n) = - with v = sha3(data + xn + n) - L = 2 if n < 2^21 else 11 if n < 2^22 else 3 - a[k] = floor(v/n^k) mod n for 0 <= k < 2 - a[k] = floor(v/n^k) mod 2^22 for 2 <= k < L - sha3(v ++ D(data,xn,a[0]) ++ D(data,xn,a[1]) ++ ... ++ D(data,xn,a[L-1])) -Proprietati: -Obiectiv: gasirea xn, n astfel incat n > 2^22 si D(data,xn,n) < 2^256 / diff -1. Cu 228 bytes (256 MB) de memorie, algoritmul optim trebuie sa administreze D de la start la finish. -2. O potentiala problema este evaluarea lenta; parti din arbore pot fi evaluate doar in masura in care se poate reduce numarul de hash-uri necesare. Cu toate acestea, din cauza unul nod (pseudo-) aleatoriu din 225 este luat de 228 ori, putem estima statistic ca fiecare nod are un 1 / e8 rest ramas nefolosit – doar in jur de 0.03%. Astfel, beneficiul de pe urma evaluarii lente nu este substantiala. -3. Este posibil ca algoritmul sa functioneze cu mult mai putina memorie folosindu-se evaluarea lenta.Totusi, testele empirice arata ca sunt necesare intre 3000 si 25000 de hash-uri pentru calcularea unui nonce. -4. Verificarea necesita, de asemenea 3000-25000 hash-uri. -5. Pentru ca fraza 2^21 to 2^22 necesita 11 parinti, atacurile time-memory-tradeoff sunt slabite destul de sever – incercarea de a stoca 2^21 noduri in loc de 2^23 reduce uzarea memoriei cu un factor de 4, dar incetineste calcularea cu un factor de 20. Astfel, nu exista nici un time-memory tradeoff attcal, sunt necesari aproape 256 MB pentru un nivel de eficienta rezonabil. -Concluzie -Acest algoritm ofera o functie de minare proof of work cu proprietati ale mamory hardness ce nu sunt ideale, dar cu toate acestea reprezinta o imbunatatire majora fata de orice algoritm anterior. Este nevoie de 512 M pentru evaluare, 112 KB si 4078 hash-uri pentru a verifica,It takes 512 MB to evaluate, 112 KB memory and 4078 hashes to verify, and even the tinest time-memory tradeoff is not worthwhile to implement because of the bottom-level branching adjustment. These parameters allow Dagger to be much more daring in its memory requirements than Primecoin or scrypt, asking for 512 MB of RAM for a single thread. Because the primary determinant of hardness is memory, and not computation, specialized hardware has only a tiny advantage; even an optimal Dagger mining ASIC would have little to offer over a hobbyist purchasing hundreds of gigabytes of memory cards off the shelf and plugging them into a medium-power GPU. And even in such an equilibrium, mining with ordinary CPUs will likely continue to be practical. -Acknowledgements -• Thanks to Adam Back and Charles Hoskinson, for discussion and critique of earlier drafts of the protocol -• See also: Fabien Coelho's paper, in which Fabien Coelho had independently discovered a similar algorithm in 2005. diff --git a/[Romanian]-Layers.md b/[Romanian]-Layers.md deleted file mode 100644 index 00c3a18fe..000000000 --- a/[Romanian]-Layers.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -name: Layers -category: ---- - -###Layers - -Networking daemon - -Scop:networking daemon trebuie sa se poata conecta la alte noduri Ethereum, si sa accepte si sa imparta datele, pentru a servi drept coloana de sprijin pentru reteaua Ethereum. Daemon-ul in sine trebuie sa fie cat mai neutru posibil; ideal ar trebui sa fie util ca parte a oricarei valute sau protocol cryptographic fara modificari. Trebuie sa includa trasaturi anti DDoS, si poate sa mentina un running score care sa previna orice IP singur de a face mai mult de un request pe secunda. -Interfata: -1. De fiecare data cand Daemon-ul primeste un nou mesaj (i.e. H(M) nu este egal cu H(Mprev) pentru orice Mprev primit anterior), ar trebui sa trimita o cerere POST la http://localhost: containing the data, unde outputport poate fi setat in fisierul ~/.ethereum/ethereum.conf (1242 implicit, in cazul in care nu este setat) -2. the daemon should listen on port, unde inputport poate fi setat in fisierul ~/.ethereum/ethereum.conf (1243 implicit, daca nu este setat), si daca primeste un mesaj intr-un post care il solicita ar trebui sa impinga datele spre toate nodurile conectate ale retelei. Dependente: internet, noduri bootstrapping - - -Ethereum Core - -Layer de comunicare (Communication Layer) - -1.Process_network_message(sir) -> msg sau tranzactie sau block -2.Create_network_message - -IO Layer (ie. De obicei baza de date) - -1. Insert object(value) (key = sha256(value)) -2. Get object (key) -> value -Data layer -1. get_transaction -2. get_block -3. get_address_balance / nonce -4. get_contract_memory_at_index -5. get_contract_root -6. get_object (Merkle trie nodes, etc) -7. block class -8. transaction class -Manager -1. get_latest_block -2. add_block (including validation and total difficulty calculation) -3. apply_transactions_to_block (for miners) -Application Layer -1. Wallet -2. Full -3. SPV -4. Graphical block explorer -5. Miner -Clase -Clasa Block -Scop: clasa block trebuia sa poata analiza block-uri, sa le serializeze si sa poata manipula anumite operatiuni de actualizare la block-uri. -Interfata: -Interface: -1. deserialize: string -> void (constructor) -2. get_balance: number address -> number -3. get_contract_state: number address, number index -> number -4. update_balance: number address, number newbalance -> void -5. update_contract_state: number address, number index, number newvalue -> void -6. get_contract_size: number address -> number -7. serialize: void -> string -Clasa Tranzactii -Scop: clasa tranzactii trebuie sa poata analiza tranzactiile, sa le semneze si sa le serializeze. Retineti ca metoda de serializare poate esua pentru tranzactii fara semnatura, tranzactiile care sunt create intr-un block si nu sunt deserializate nu ar trebui sa fie, de fapt, serializate sau stocate, in nici o forma. -Interfata: -1. deserialize: string -> void (constructor) -2. sign: privkey -> void -3. serialize: void -> string -4. create: number address, number value, number fee, array[number] data -> void (constructor) -5. hash: void -> number -6. to, from, value, fee, data (accessible and settable member variables) diff --git a/[Romanian]-Limbajul-de-programare-Serpent.md b/[Romanian]-Limbajul-de-programare-Serpent.md deleted file mode 100644 index 4e0ed3513..000000000 --- a/[Romanian]-Limbajul-de-programare-Serpent.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -name: Limbajul de Programare Serpent -category: ---- - -###Operatiile limbajului de programare Serpent - -Aritmetica - -• Aritmetica normala functioneaza dupa cum ne asteptam:: x = 20 + 7 * 5 fixeaza x ca 55 -• Numerele negative nu exista: x = 0 - 1 seteaza x la 115792089237316195423570985008687907853269984665640564039457584007913129639935 -• Decimalele nu exista: x = 7 / 4 seteaza x la 1 -• Se poate folosi #/ si #% pentru a se putea pretinde ca numerele sunt numere intregi: x = (0-9) #/ 3 + 5 seteaza x la 2, pe cand y = (0-9) / 3 + 5seteaza y la 38597363079105398474523661669562635951089994888546854679819194669304376546647 -• Aritmetica deviaza 2^256: x = 3 ^ (2 ^ 254) setand x la 1 (aceasta este o consecinta a Teoremei Euler) -• Folositi x = y | z, x = y & z si x = y xor z pentru operatii bitwise -Variable -• Variablele functioneaza ca orice fel de limbaj : x = 25 atunci y = x + 5 seteaza y la 30 -• Folositi x = array(n) pentru a initializa o multime de valori n 32-byte -• Folositi x[i] = v pentru a seta valori in multimi si v = x[i] pentru a obtine valori in multimi -• Folositi x = bytes(n) pentru a initializa un sir/multime de bytes de n bytes -• Folositi setch(x,i,v) pentru a seta to set and v = getch(x,i) to get -• Use array literals to declare arrays inline: x = [1,2,3] -Variables are encoded into EVM code by assigning a memory index to each variable, with 32 bytes of spacing between variables. In the last example, x literally is the memory index of the start of the array, which is itself stored in a dynamically allocated slice of memory. Note that bounds-checking is not performed; array(3)[5] = 10 will have completely unknown and likely compiler-dependent consequences on code execution. -Pseudovariables -Ethereum provides the following pseudovariables and pseudoarrays: -• block.prevhash - previous block hash -• block.number - block number -• block.timestamp - block timestamp -• block.difficulty - block difficulty -• block.coinbase - address of block miner -• block.gaslimit - maximum amount of gas that can be spent in the block -• tx.gasprice - amount paid by transaction for gas -• tx.origin - original sender of transaction (NOT the sender of the current message, which is different in a nested call situation) -• tx.gas - current amount of gas remaining -• msg.datasize - length of the data provided by the message, measured as the number of complete 32-byte chunks -• msg.sender - sender of the message -• msg.value - value of the message -• contract.balance - balance of the contract -• msg.data[i] - the ith 32-byte chunk in message data -• contract.storage[i] - the contract's long term storage, at index i -Functions -• send(to, value, gas) - sends value ether to to, allowing the computation the given amount of gas. -• x = msg(to, value, gas, datastart, datalen) - sends a message to to, using the data at memory indices datastart ... datastart+datalen*32-1, with the given amount of ether and gas, and sets x to the first 32 bytes of the result. -• msg(to, value, gas, datastart, datalen, outputstart, outputlen) - sends a message toto, using the data at memory indicesdatastart ... datastart+datalen*32-1, with the given amount of ether and gas, and pastes the result to memory indicesoutputstart ... outputstart+outputlen*32-1` -• x = create(endowment, gas, datastart, datalen) - creates a new contract using code from the given indices in memory as above, and return the address of the contract -• x = sha3(v) - returns the SHA3 of the given 32-byte value -• x = byte(y,z) - sets x to the zth byte of y -A lot of these commands require data to be loaded from memory; this is actually fairly easy to manage. Consider the following equivalent examples: -x = msg(0xf345747062de4d05d897d62c4696febbedcb36b8, 10^18, tx.gas - 100, [10,20,30], 3) -And: -a = array(3) -a[0] = 10 -a[1] = 20 -a[2] = 30 -y = array(1) -msg(0xf345747062de4d05d897d62c4696febbedcb36b8, 10^18, tx.gas - 100, a, 3, y, 1) -x = y[0] -Conditionals and Loops -Best to learn by example: -if x > 5: - y = 7 -And: -x = 248 -while x > 1: - if (x % 2) == 0: - x = x / 2 - else: - x = 3 * x + 1 -Note that if x > 5: y = 7 on one line is invalid. -Comments -x = 4 //this is a comment and does not appear in the compiled code - // this also is a comment on its own line - /* this style is not supported however */ -Halting -• stop - this keyword by itself on one line stops execution -• return(x) - returns the 32 bytes of value x -• return(memstart, len) - returns the memory at indices memstart ... memstart+32*len-1 -• suicide(a) - destroys the contract, sending all remaining balance to a -Last edited by vbuterin, 3 days ago diff --git a/[Romanian]-Wire-Protocol.md b/[Romanian]-Wire-Protocol.md deleted file mode 100644 index fdab9c747..000000000 --- a/[Romanian]-Wire-Protocol.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -name: Wire Protocol -category: ---- - -###Wire Protocol - -Comunicatiile peer-to-peer intre noduri care opereaza clienti Ethereum sunt create pentru a fi guvernate de un simplu protocol wire, care utilizeaza tehnologii si standarde Ethereum existente , cum ar fi RLP, care este practic oriunde. - -Acest document are ca scop explicarea acestui tip de protocol intr-un mod comprehensibil. - -###Low-level - -Nodurile Ethereum se pot conecta intre ele doar prin TCP.Perechile (peers) sunt libere sa promoveze si sa accepte conexiuni pe orice port/porturi doresc, cu toate acestea va exista un port default -30303; pe care conexiunea poate fi ascultata si facuta. -Desi TCP furnizeaza un mediu orientat spre conexiuni, nodurile Ethereum functioneaza in termeni de pachete. Aceste pachete sunt formate ca jetoane(token) de 4 biti de sincronizare (0x22400891), 4 biti de “sarcina utila”, pentru a fi interpretate ca un intreg endian si, finalmente, o structura de date N-byte serializata RLP, unde N este “sarcina utila” mentionata mai sus. Pentru a clarifica, sarcina utila specifica numarul de biti din pachetul care “urmeaza” dupa primii 8. -Continutul sarcinei utile -Exista un numar de diferite tipuri de sarcini utile care pot fi codate in RLP. Acest “tip” este intotdeauna determinat de prima intrare a RPL, interpretata ca un numar intreg: -Hello -• `[0x00, PROTOCOL_VERSION, NETWORK_ID, CLIENT_ID, CAPABILITIES, LISTEN_PORT, NODE_ID]` -• Primul pachet trimis prin conexiune, si trimis o data de ambele parti. Nici un alt mesaj nu poate fi trimis pana cand “Hello” este primit. -• PROTOCOL_VERSION este unul dintre: -o 0x00 pentru PoC-1; -o 0x01 pentru PoC-2; -o 0x07 pentru PoC-3. -• NETWORK_ID trebuie sa fie 0. -• CLIENT_ID Specifica identitatea software-ului clientului, ca un sir lizibil (e.x."Ethereum(++)/1.0.0"). -• LISTEN_PORT specifica portul pe care asculta clientul (pe interfata pe care se efectueaza conexiunea curenta). Daca se indica 0, clientul nu asculta. -• CAPABILITIES specifica capacitatile clientului ca un set de “flags”; in prezent sunt folositi trei biti: 0x01 pentru descoperirea perechilor, 0x02 pentru relocarea tranzactiilor, 0x04 pentru interogarea block-chain-ului. -• NODE_ID este optional si specifica un hash de 512 biti, (cu potential de a fi utilizat ca public key) care identifica acest nod. - -Disconnect -• `[0x01, REASON]` -• Informeaza perechea ca o deconectare este iminenta, daca se primeste acest mesaj, perechea trebuie sa se deconecteze automat. Cand se efectueaza operatiunea de trimitere, gazdele dau perechilor o sansa de lupta (a fighting chance) (a se citi: asteptati 2 secunde) pentru a se deconecta, inainte de a se deconecta ei insisi. -• REASON este un intreg optional care specifica unul dintr-un numar de motive pentru care se efectueaza deconectarea: -• 0x00 Deconectare solicitata; -• 0x01 eroare de sub-sistem TCP; -• 0x02 Protocol incorect; -• 0x03 Pereche inutila; -• 0x04 Prea multe perechi; -• 0x05 Deja conectat; -• 0x06 Bloc geneza incorect/gresit; -• 0x07 Protocoale de retea incompatibile; -• 0x08 Clientul a renuntat. -Ping -• `[0x02]` -• Solicita un raspuns imediat la Pong de la pereche. -Pong -• `[0x03]` -• Raspunde la pachetul Ping al perechii. -GetPeers -• `[0x10]` -• Solicita perechii sa enumere cateva alte perechi cunoscute pentru ca noi sa ne putem conecta la ele. Aceasta enumerare ar trebui sa contina si perechea solicitata. -Peers -• `[0x11, [IP1, Port1, Id1], [IP2, Port2, Id2], ... ]` -• Specifica un numar de perechi cunoscute. IP este o multime de 4 biti “ABCD” care trebuie interpretata ca adresa IP A.B.C.D. Port este o multime care trebuie intrepretata ca un intreg de 16 biti endian. Id este hash-ul de 512 biti care se comporta ca unicul identificator al nodului. - Tranzactii -• `[0x12, [nonce, receiving_address, value, ... ], ... ]` -• Specifica unei tranzactii(unor tranzactii) ca perechea trebuie sa se asigure ca este inclusa in sirul tranzactiei.Elementele din lista (cele care il urmeaza primul 0x12) sunt tranzactii in formatul descris in specificatiile Ethereum principale. - Blocks -• `[0x13, [block_header, transaction_list, uncle_list], ... ]` -• Specifica block-ului/-urilor ca perechea trebuie sa stie despre (atat scria, nu inteleg despre ce e vorba). Elementele din lista (cele care il urmeaza pe primul, 0x13) sunt blocks in formatul descris in specificatiile Ethereum principale. - GetChain -• [0x14, Parent1, Parent2, ..., ParentN, Count] -• Solicita perechii sa trimita Count (a se interpreta ca numar) block-uri in block chain-ul canonic curent, care sunt copii ai Parent1 (a se interpreta ca SHA3 block hash). Daca Parent1 nu este prezent in block chain, ar trebui sa actionezeca si cum solicitarea ar fi facuta pentru Parent2 &c. pana la ParentN. Daca parintele desemnat este capul block chain-ului actual, un rapuns gol trebuie trimis.Daca nici unul dintre parinti nu sunt in block chain-ul canonic curent, NotInChain trebuie trimis impreuna cu ParentN (i.e. ultimul Parent din lista de parinti). Daca nu sunt trecuti parinti, atunci nu este necesar un raspuns. - NotInChain -• [0x15, Hash] -• Comunica perechii ca un anume hash nu a fost gasit in block chain-ul sau. - GetTransactions -• [0x16] -• Solicita perechii sa trimita toate tranzactiile aflate in acel moment in sir. Vedeti in sectiunea “Tranzactii”. -Exemple de pachete -0x22400891000000088400000043414243 -Un pachet Hello care mentioneaza ca id-ul clientului este “ABC”. -Peer 1: 0x22400891000000028102 -Peer 2: 0x22400891000000028103 -Un Ping si Pong-ul returnat. -Managementul sesiunii -Dupa conectare, toti clientii(i.e. de ambele parti ale conexiunii) trebuie sa trimita un mesaj Hello. Dupa primirea mesajului Hello si dupa verificarea compatibilitatii retelei si versiunilor, o sesiune este activa si orice alte mesaje pot fi trimise. -In orice moment, un mesaj Disconnect poate fi trimis. - - - diff --git "a/[\344\270\255\346\226\207]-Serpent\346\214\207\345\215\227.md" "b/[\344\270\255\346\226\207]-Serpent\346\214\207\345\215\227.md" deleted file mode 100644 index 347d9c706..000000000 --- "a/[\344\270\255\346\226\207]-Serpent\346\214\207\345\215\227.md" +++ /dev/null @@ -1,487 +0,0 @@ ---- -name: Serpent -category: ---- - -译者: jan - -**更多以太坊信息请访问[EthFans.org](http://ethfans.org)** - -有关Serpent 1.0的信息请查阅: https://github.com/ethereum/wiki/wiki/Serpent-1.0-(old) - -Serpent是一种用来编写以太坊合约(Ethereum Contract)的高级编程语言。Serpent翻译成中文意思是"大蛇",如这个名字所示,这是一种与Python类似的编程语言。Serpent在兼顾底层语言效率与良好编程风格的同时尽可能的追求简洁,还加入了一些针对合约编程的特性。Serpent编译器由C++实现,因此可以被轻松打包进任何客户端,最新版本可以在[Github](http://github.com/ethereum/serpent)上找到。 - -以下内容需要读者对以太坊的工作原理有一个基本认识,包括区块,交易,合约和消息的概念,以及合约是如何通过读入字节数组和输出字节数组工作的。读者可以通过阅读[以太坊开发指南](https://github.com/ethereum/wiki/wiki/Ethereum-Development-Tutorial)得到这些知识。 - -### Serpent与Python的区别 - -Serpent与Python之间的主要区别有: - -* Python中的数字类型没有大小限制,Serpent的数字类型则会在2256溢出。例如,在Serpent中计算`3^(2^254)`的结果是1,虽然事实上这是一个天文数字。 -* Serpent没有Decimal类型。 -* Serpent没有list comprehensions (例如`[x**2 for x in my_list]`这样的表达式),字典(Hash/Map),和其它一些高级特性。 -* Serpent没有first-class函数的概念。虽然合约中可以定义函数, 合约也可以调用这些函数,但是在两次函数调用之间变量(除了持久变量)是会丢失的。 -* Serpent有一个被称作”持久变量“(persistent storage variables)的概念。 -* 在Serpent中可以使用`extern`语句来调用其他合约中定义的函数。 - -### 安装 - -我们可以通过pip来安装Serpent的python库和可执行文件 (注:译者使用的Python版本为2.7): - - sudo pip install ethereum-serpent - -如果想要一个在C++中可以直接调用的库,可以自行编译Serpent: - - git clone http://github.com/ethereum/serpent - cd serpent - make - sudo make install - -### 指南 - -现在开始编写我们的第一个合约吧! - -首先创建一个叫做"mul2.se"的文件,内容如下: - - def double(x): - return(x * 2) - -这是一个非常简单的只有两行代码的合约,它定义了一个函数。一份Serpent合约通过函数向其他合约或者交易(transaction)提供”接口“(interface),合约定义的函数即可以被交易也可以被其他合约调用。例如一份定义货币的合约可能会定义类似`send(to,value)`和`check_balance(address)`的函数。 - -现在让我们来编译这份代码。在命令行中输入: - -``` -> serpent compile mul2.se -604380600b600039604e567c01000000000000000000000000000000000000000000000000000000006000350463eee9720681141560415760043560405260026040510260605260206060f35b505b6000f3 -``` - -执行成功后就得到了一串可以放入交易执行的16进制编码的字符串。如果你想要的是机器指令(opcodes),可以使用`pretty_compile`来编译: - - > serpent pretty_compile mul2.se - [PUSH1, 67, DUP1, PUSH1, 11, PUSH1, 0, CODECOPY, PUSH1, 78, JUMP, PUSH29, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, PUSH1, 0, CALLDATALOAD, DIV, PUSH4, 238, 233, 114, 6, DUP2, EQ, ISZERO, PUSH1, 65, JUMPI, PUSH1, 4, CALLDATALOAD, PUSH1, 64, MSTORE, PUSH1, 2, PUSH1, 64, MLOAD, MUL, PUSH1, 96, MSTORE, PUSH1, 32, PUSH1, 96, RETURN, JUMPDEST, POP, JUMPDEST, PUSH1, 0, RETURN] - -使用`compile_to_lll`可以查看LLL形式的中间编译结果: - -``` -> serpent compile_to_lll mul2.se -(return 0 - (lll - (with '__funid - (div (calldataload 0) - 26959946667150639794667015087019630673637144422540572481103610249216 - ) - (unless (iszero (eq (get '__funid) 4008276486)) - (seq - (set 'x (calldataload 4)) - (seq - (set '_temp_521 (mul (get 'x) 2)) - (return (ref '_temp_521) 32) - ) - ) - ) - ) - 0 - ) -) -``` - -让我们来理解一下上面编译结果的含义。与大多数合约一样,代码最外一层的目的仅仅是在合约初始化阶段将合约内部的代码复制并作为运算结果返回。初始化阶段返回的代码将会在每次调用合约的时候被执行。因此在EVM (Ethereum Virtual Machine)执行的代码中你可以看到`CODECOPY`指令, 在LLL表达式中对应的则是`lll`元操作。在`lll`元操作内部,首先是一段获取保存在合约数据头四个字节的函数ID(function ID)的代码(也就是`(div (calldataload 0) 26959946667150639794667015087019630673637144422540572481103610249216)`这一段,我们通过先读入32个字节,再将其除以2^224得到头四个字节)。再往下,则会将获得的函数ID与该合约支持的所有函数ID逐一比较。在我们的例子中,如果函数ID是4008276486,则会将消息数据中的4到35字节的数据赋值给一个名为`'x`的变量(对应的代码是`(calldataload 4)`),然后将`2 * x`的结果赋值给一个临时变量`'_temp_521`,最后将这个临时变量对应的内存地址中存放的32字节长的数据作为结果返回。 - -函数ID通过计算函数名字和参数的哈希值(Hash)的头四个字节得到。在我们的例子中,定义了一个名字为”double“,接受一个整型数作为参数的函数,因此可以通过如下命令得到其对应的函数ID: - - > serpent get_prefix double i - 4008276486 - -定义接受不同参数列表的同名函数是允许的。例如,我们可以定义一个接受三个整型数为参数的”double“函数,它会将每一个参数翻倍然后以数组形式返回。这个函数会有一个不同的函数ID (或者说前缀,prefix): - - > serpent get_prefix double iii - 1142360101 - -字母`i`代表整型或者定长字符串(32字节,在Serpern和EVM中与整型等价)参数,字母`s`代表变长字符串参数,而字母`a`代表数组参数。后文会对此做更详细的介绍。 - -那么如何运行这份合约呢?这时候我们需要使用[pyethereum](https://github.com/ethereum/pyethereum)。先通过pip(环境是python 2.7)安装pyethereum: - - > sudo pip install pyethereum - -在合约代码所在目录中打开Python控制台,输入: - - > from pyethereum import tester as t - > s = t.state() - > c = s.abi_contract('mul2.se') - > c.double(42) - [84] - -第二行创建了一个初始化的状态(类似于创世块, genesis block)。第三行创建了一个Python对象,代表mul2.se这个合约。你可以用`c.address`来查看这份合约存放的地址。第四行调用这个合约,传入参数42,然后我们看到这份合约返回给我们结果84。 - -如果要在testnet或者livenet上调用这样一份合约,你需要打包一个内容为”以整型参数42作为输入调用函数double“的消息发送给这份合约。使用下面的命令可以得到消息对应的字节码: - - > serpent encode_abi double i 42 - eee97206000000000000000000000000000000000000000000000000000000000000002a - -### 另一个实例:名称注册合约 (Name Registry) - -读者一定觉得在区块链上跑一个”乘以2“的函数略显无聊吧... 接下来让我们来实现一个更有趣的合约:名称注册。这个合约的主要接口是一个`register(key, value)`函数。通过这个接口可以检查给定的key是否已经被使用/注册了;如果没有,则将这个key注册为指定的键值然后返回1;如果已经被使用则直接返回0。这个合约还提供另外一个接口用来获取指定key对应的键值。下面就是合约代码: - - def register(key, value): - # Key not yet claimed - if not self.storage[key]: - self.storage[key] = value - return(1) - else: - return(0) # Key already claimed - - def ask(key): - return(self.storage[key]) - -这份合约首先定义了`register`函数,这个函数接受`key`和`value`变量作为参数。第二行是注释,以`#`开头,注释会被编译器忽略,仅仅用来帮助程序员更好的理解程序。然后是一个标准的if/else条件语句:先检查`self.storage[key]`是否为0(即表明这个key没有被使用),如果是0则执行赋值`self.storage[key] = value`然后返回1,否则直接返回0。`self.storage`是一个伪数组,有和数组类似的行为但是实际上没有一块内存与之对应。 - -让我们把这段代码放入一个名为"namecoin.se"的文件,然后在pyethereum中试试: - - > from pyethereum import tester as t - > s = t.state() - > c = s.abi_contract('namecoin.se') - > c.register(0x67656f726765, 45) - [1] - > c.register(0x67656f726765, 20) - [0] - > c.register(0x6861727279, 65) - [1] - > c.ask(0x6861727279) - [65] - -如果我们想要把上面的第一次调用写成消息的形式: - -``` -> serpent encode_abi register ii 0x67656f726765 45 -d66d6c10000000000000000000000000000000000000000000000000000067656f726765000000000000000000000000000000000000000000000000000000000000002d -``` - -### 引用代码和调用其他合约 - -当你的项目越来越大时把所有代码放在一个文件里面就很不科学了,所幸的是把合约代码分开保存在多个文件中是一件很容易的事情。假设我们创建了如下两个文件: - -mul2.se: - - def double(x): - return(x * 2) - -returnten.se: - - extern mul2: [double] - - MUL2 = create('mul2.se') - def returnten(): - return(MUL2.double(5, as=mul2)) - -现在打开Python,执行以下代码: - - > from pyethereum import tester as t - > s = t.state() - > c = s.abi_contract('returnten.se') - > c.returnten() - [10] - -通过这个例子我们可以看到一些新特性: - -* 使用`create`方法可以从文件中读入代码创建合约 -* 使用`extern`关键字可以声明一个合约类(class of contract),通过这个类可以知道合约中的函数名 -* 用来调用其他合约的编程接口 - -`create`方法很容易理解 - 使用它可以创建一份合约,返回值是这份合约的地址(address)。`extern`后面先是声明了合约类的名字,例子中是`mul2`,然后用一个数组声明了这个合约类中的所有方法名,例子中是`[double]`。声明之后,对于任何地址变量x(变量的值是一个地址),都可以通过`x.double(arg1, as=mul2)`来调用该地址中保存的合约。合约类通过`as`关键字提供(合约类用来确定`double`对应的函数ID;另一个合约类中如果`double`函数可能对应不同的ID)。`as`关键字是可选的,但是在两个合约类包含同名函数时会产生歧义。`arg1`是传给`double`函数的参数,如果传入的参数个数比函数声明需要的参数少,缺少的参数会以'0'补上;如果传入的参数比声明需要的参数多,多余的参数会被忽略。函数调用还支持一些其他的可选参数: - -* `gas=12414` - 设置函数执行可用的gas上限 (默认是所有gas,即合约可用gas上限)。 -* `value=10^19` - 随调用消息转账10^19 wei(10 ether) -* `data=x`, `datasz=5` - 用数组x中的头5个值作为参数调用函数;之前传入的参数会被覆盖掉;只指定data而不指定datasz会导致非法调用。 -* `outsz=7` - Serpent在默认情况下取运算结果的头32字节作为函数返回值,通过`outsz`可以要求函数通过数组返回更多的值。例如执行`y = x.fun(arg1, outsz=7)`之后你可以通过`y[0]`, `y[1]`等等操作返回值。 - -和`create`类似的一个操作是`inset('filename')`,它的作用是用文件中的代码替换调用的那一行,而不是创建一个合约。 - -### 持久化保存结构化数据 - -(注:原文用词是data structure,直译应为数据结构,但例子中定义的更像是数据而不是数据结构,因此翻译为结构化数据。) - -在更复杂的场景中,我们经常需要将结构化数据持久的保存。例如一份去中心话的交易所合约,既需要保存用户各种资金的余额,也需要保存待成交的包含了价格和数量信息的买单和卖单。因此Serpent内建支持自定义数据结构。以去中心化交易所合约为例,其中可能需要定义这样的结构化数据: - - data user_balances[][] - data orders[](buys[](user, price, quantity), sells[](user, price, quantity)) - -接下来可以使用这些定义好的数据: - - def fill_buy_order(currency, order_id): - # Available amount buyer is willing to buy - q = self.orders[currency].buys[order_id].quantity - # My balance in the currency - bal = self.user_balances[msg.sender][currency] - # The buyer - buyer = self.orders[currency].buys[order_id].user - if q > 0: - # The amount we can actually trade - amount = min(q, bal) - # Trade the currency against the base currency - self.user_balances[msg.sender][currency] -= amount - self.user_balances[buyer][currency] += amount - self.user_balances[msg.sender][0] += amount * self.orders[currency].buys[order_id].price - self.user_balances[buyer][0] -= amount * self.orders[currency].buys[order_id].price - # Reduce the remaining quantity on the order - self.orders[currency].buys[order_id].quantity -= amount - -请注意我们是如何先在顶部定义结构化数据,然后在合约中使用它们的。对这些结构化数据的读和写都会被转化成在持久化存储上的读写,因此这些结构化数据是持久保存的。 - -定义结构化数据的语法很简单。首先可以定义最简单的变量: - - data blah - - x = self.blah - self.blah = x + 1 - -还可以定义定长数组和不定长数组: - - data blah[1243] - data blaz[] - - x = self.blah[505] - y = self.blaz[3**160] - self.blah[125] = x + y - -我们应该优先考虑使用定长数组,因为在计算数组元素(array index)对应的存储位置(storage index)的时候,定长数组消耗的gas更少。 - -也可以定义元组(tuple),元组的元素也可以是结构化数据: - - data body(head(eyes[2], nose, mouth), arms[2], legs[2]) - - x = self.body.head.nose - y = self.body.arms[1] - -然后是元组数组(array of tuples): - - data bodies[100](head(eyes[2], nose, mouth), arms[2](fingers[5], elbow), legs[2]) - - x = self.bodies[45].head.eyes[1] - y = self.bodies[x].arms[1].fingers[3] - -注意下面这样的写法是不行的: - - data body(head(eyes[2], nose, mouth), arms[2], legs[2]) - - x = self.body.head - y = x.eyes[0] - -也就是说对结构化数据内部元素的存取必须在一行语句中完成。 - -还是以名称注册表(name registry)为例,让我们来看看具体如何使用结构化数据。我们要实现一个增强版的名称注册表,当用户注册key成功时他会成为key的所有者,key的所有者可以 (1) 转移所有权,以及(2) 改变key对应的键值(value)。为了简洁函数不再返回1或者0。 - - data registry[](owner, value) - - def register(key): - # Key not yet claimed - if not self.registry[key].owner: - self.registry[key].owner = msg.sender - - def transfer_ownership(key, new_owner): - if self.registry[key].owner == msg.sender: - self.registry[key].owner = new_owner - - def set_value(key, new_value): - if self.registry[key].owner == msg.sender: - self.registry[key].value = new_value - - def ask(key): - return([self.registry[key].owner, self.registry[key].value], items=2) - -最后定义的ask函数返回一个长度为2的数组。通过调用ask函数,例如`o = registry.ask(key, outsz=2)`,我们可以通过返回值`o[1]`和`o[1]`获取key对应的所有者和键值。 - -### 内存中的数组 - -使用内存中的数组有一套不同的语法。内存数组只能是定长数组,也不能有元组(tuple)或者更复杂的数组元素。例如: - - def bitwise_or(x, y): - blah = array(1243) - blah[567] = x - blah[568] = y - blah[569] = blah[567] | blah[568] - return(blah[569]) - -Serpent还定义了两个常用的数组操作: - - len(x) - -用于查询数组的长度。 - - slice(x, start, end) - -用于截取从start开始到end结束范围内数组元素,注意end必须大于等于start,否则执行是会出错。 - -### 数组与函数 - -函数可以接受数组作为参数,也可以返回一个数组: - - def compose(inputs:arr): - return(inputs[0] + inputs[1] * 10 + inputs[2] * 100) - - def decompose(x): - return([x % 10, (x % 100) / 10, x / 100]:arr) - -在参数定义后面加`:arr`表示这个参数是一个数组;而在返回值后面加`:arr`表示返回一个数组(如果不加`:arr`只写`return([x,y,z])`,函数的返回值将会是这个数组的内存地址)。 - -当合约调用自己定义的函数的时候,数组参数会被自动识别出来正确处理,例如: - - def compose(inputs:arr, radix): - return(inputs[0] + inputs[1] * radix + inputs[1] * radix ** 2) - - def main(): - return self.compose([1,2,3,4,5], 100) - -但是当合约需要调用另一份接受数组参数的合约时,你需要通过`extern`声明这一点,加入数组签名到函数签名中: - - extern composer: [compose:ai, main] - -这里`ai`的意思是“一个数组参数后面跟着一个整型参数”。同理,如果签名是`iiaa`,则代表“两个整型参数后面跟着两个数组参数”,而`iss`表示“一个整型参数,后面是两个字符串做参数”。如果函数名后面没有跟冒号(:),如本例中`main` 所示,则表示这个函数不接受参数。如果你想知道一个文件中定义了哪些函数签名,执行下面的命令即可: - - > serpent mk_signature compose_test.se - extern compose_test: [compose:ai, main] - -### 字符串 - -Serpent中有两种字符串:短字符串(short strings),例如`"george"`,以及长字符串(long strings),例如`text("afjqwhruqwhurhqkwrhguqwhrkuqwrkqwhwhrugquwrguwegtwetwet")`.用双引号括起来的短字符串和数字类型是等价的;用`text`关键字定义的长字符串则是类似与数组的对象。我们可以使用`getch(str, index)`和`setch(str, index)`方法来操作字符串中的字符。`str[0]`这样的写法则会将字符串当作数组处理,将字符当作数字返回。 - -将字符串用作函数参数或者返回值时,需要在函数签名中使用字符串标记`str`,类似使用`arr`来标记数组。使用`len(s)`方法可以得到字符串的长度,而`slice(s)`方法可以用来裁剪字符串。 - -下面是一个用字符串做参数和返回值的例子: - -``` -data str - -def t2(): - self.str = text("01") - log(data=self.str) - return(self.str, chars=2) - -def runThis(): - s = self.t2(outsz=2) - log(data=s) -``` - -### Macros (宏) - -**警告:这是新加入的未经测试的特性,大蛇出没注意!** - -通过macro我们可以创造重写规则,极大的增强程序的表达能力。例如,假设我们想写一条计算三个数字的中位数的命令: - - macro median($a, $b, $c): - min(min(max($a, $b), max($a, $c)), max($b, $c)) - -现在我们可以使用这个新定义的macro: - - x = median(5, 9, 7) - -接下来看另一个例子,一个查找数组中最大元素的macro: - - macro maxarray($a:$asz): # search pattern. below is substitution pattern - $m = 0 - $i = 0 - while i < $asz: - $m = max($m, $a[i]) - $i += 1 - $m - - x = maxarray([1, 9, 5, 6, 2, 4]:6) - -点击下面的链接可以看到更多展示macros牛逼用法的例子: - -https://github.com/ethereum/serpent/blob/poc7/examples/peano.se - -这里要提醒读者注意的是:macros不是函数(functions)。每次调用macro的时候,macro的定义都会被文本复制到调用的地方(宏展开)。因此当macro的定义变得很长时,请考虑定义一个函数替代它。还要注意的是占位符前面的$符号非常重要:如果$a前少了$符号,实际上是在使用名字为a的变量。我们也可以在替换模式(substitution pattern, 指宏的定义体)而不是搜索模式(search pattern,指宏定义的第一行)中使用$占位符,这样在每一次宏展开时会产生一个名字为随机前缀的变量。在替换模式中也可以使用普通变量(变量名前面没有$),结果就是所有宏展开使用的是同一个变量,而且该变量可能在宏展开之外的地方也会用到。 - -### 类型 - -**警告:这是新加入的未经测试的特性,大蛇出没注意!** - -Serpent中的穷人版类型系统是体现macros威力的绝佳例子,和macros一起使用时能产生非常有趣的结果。直接上例子: - - type float: [a, b, c] - - macro float($x) + float($y): - float($x + $y) - - macro float($x) - float($y): - float($x - $y) - - macro float($x) * float($y): - float($x * $y / 2^32) - - macro float($x) / float($y): - float($x * 2^32 / $y) - - macro unfloat($x): - $x / 2^32 - - macro floatfy($x): - float($x * 2^32) - - macro float($x) = float($y): - $x = $y - - macro with(float($x), float($y), $z): - with($x, $y, $z) - - a = floatfy(25) - b = a / floatfy(2) - c = b * b - return(unfloat(c)) - -这段代码的返回值是156,即12.5^2的整数部分。如果只用整型计算,结果将是144。这个技巧可以用来重写[椭圆曲线签名的公钥复原代码](https://github.com/ethereum/serpent/blob/df0aa0e1285d7667d4a0cc81b1e11e0abb31fff3/examples/ecc/jacobian_add.se),类型系统可以让里面的加法和乘法隐式的做模运算(modulo P),从而是代码更精巧;我们也可以利用[长整形](https://github.com/ethereum/serpent/blob/poc7/examples/long_integer_macros.se)来处理RSA以及其他基于大数的加密算法中的计算。 - -### 其他 - -更多的Serpent代码示例请参阅:https://github.com/ethereum/serpent/tree/master/examples - -pyethereum tester的一些有用技巧: - -* 区块数据 - 你可以通过`s.block`查看区块数据。例如,`s.block.number`, `s.block.get_balance(addr)`, `s.block.get_storage_data(addr, index)`等等。 -* 快照 - 通过`x = s.snapshot()`和`s.revert(x)`可以创建和恢复快照。 -* 挖矿 - 调用`s.mine(100)`会挖出100个块,块之间间隔60秒。通过`s.mine(100, addr)`可以指定获得挖矿收益的地址。 -* Dump所有区块数据 - `s.block.to_dict()` - -Serpent还提供了许多特别变量(special variables),以下是完整列表: - -* `tx.origin` - 交易的发送者 -* `tx.gas` - 剩余gas -* `tx.gasprice` - 交易包含的gasprice(油价) -* `msg.sender` - 消息的发送者 -* `msg.value` - 通过消息转移的wei(以太坊中最小的价值单位)的数量 -* `self` - 合约自身的地址 -* `self.balance` - 合约自身的余额(拥有多少wei) -* `x.balance` (对于任意的x) - x的账户余额 -* `block.coinbase` - 挖出当前块的矿工的收益地址(coinbase) -* `block.timestamp` - 当前块的时间戳 -* `block.prevhash` - 前一个块的hash -* `block.difficulty` - 当前的挖矿难度 -* `block.number` - 当前块的编号 -* `block.gaslimit` - 当前块的可用gas上限 - -Serpent支持以下特别函数(special functions): - -* `init` - 在创建合约时执行 -* `shared` - 在执行`init`和用户函数之前执行 -* `any` - 在用户函数之前执行 - -此外还提供了几个加密操作: - -* `addr = ecrecover(h, v, r, s)` - determines the address that produced the elliptic curve signature `v, r, s` of the hash `h` -* `x = sha256(a, items=4)` - 返回数组a中头4个元素构成的128字节的SHA256 hash。 -* `x = ripemd160(a, items=4)` - same as above but for ripemd160 -* 使用字符语法(chars syntax)可以计算任意数量字节的hash。例如:`x = sha256([0xf1fc122bc7f5d74df2b9441a42a1469500000000000000000000000000000000], chars=16)` - 返回的是头16个字节的hash。注意最后用0对齐,否则头16个字节会是0(因为一个word是32字节),计算的是16个0字节的hash。 - -### 小提示 - -* 如果函数的返回值和你预计的不同,仔细检查所有的变量名 - 使用没有声明过的变量是不会产生错误信息的。 - -* `Invalid argument count or LLL function`通常表示你将`self.foo()`写成了`foo()`。 - -* 有时你需要的是无符号运算符,例如div()和lt()而不是'/'和'<'。 - -* 升级Serpent的时候,需要先`pip uninstall ethereum-serpent`然后`python setup.py install`。避免使用`pip install ethereum-serpent`,因为pypi上的包八成已经过时了。 - -* 在调用abi_contract()时如果你遇到`Exception: Error (file "main", line 1, char 5): Invalid object member (ie. a foo.bar not mapped to anything)`这样的错误,确认你要编译的文件所在路径写对了。 - -* 如果在调用abi_contract()的时候遇到core dump,确认你没有定义同名函数。 diff --git "a/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212Wiki\347\233\256\345\275\225.md" "b/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212Wiki\347\233\256\345\275\225.md" deleted file mode 100644 index d9344f794..000000000 --- "a/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212Wiki\347\233\256\345\275\225.md" +++ /dev/null @@ -1,11 +0,0 @@ -中文读者可以在[以太坊爱好者社区](http://ethfans.org)获知最新信息。 - -白皮书:[以太坊(Ethereum ):下一代智能合约和去中心化应用平台](https://github.com/ethereum/wiki/blob/master/%5B%E4%B8%AD%E6%96%87%5D-%E4%BB%A5%E5%A4%AA%E5%9D%8A%E7%99%BD%E7%9A%AE%E4%B9%A6.md) - -[Serpent语言指南](https://github.com/ethereum/wiki/blob/master/%5B%E4%B8%AD%E6%96%87%5D-Serpent%E6%8C%87%E5%8D%97.md) - -[以太坊开发计划](https://github.com/ethereum/wiki/blob/master/%5B%E4%B8%AD%E6%96%87%5D-%E4%BB%A5%E5%A4%AA%E5%9D%8A%E5%BC%80%E5%8F%91%E8%AE%A1%E5%88%92.md) - -[术语表](https://github.com/ethereum/wiki/blob/master/%5B%E4%B8%AD%E6%96%87%5D-%E4%BB%A5%E5%A4%AA%E5%9D%8A%E6%9C%AF%E8%AF%AD%E8%A1%A8.md) - -[网络状态监控](https://github.com/ethereum/wiki/blob/master/%5B%E4%B8%AD%E6%96%87%5D-%E7%BD%91%E7%BB%9C%E7%8A%B6%E6%80%81.md) diff --git "a/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\345\274\200\345\217\221\350\256\241\345\210\222.md" "b/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\345\274\200\345\217\221\350\256\241\345\210\222.md" deleted file mode 100644 index 555f733d3..000000000 --- "a/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\345\274\200\345\217\221\350\256\241\345\210\222.md" +++ /dev/null @@ -1,278 +0,0 @@ ---- -name: 以太坊开发计划 -category: ---- - -翻译:Andy - -介绍 - - - -以太坊是一个开源平台,可以创建和发布去中心化的应用程序。 - -欲了解更多信息,请参阅 - -白皮书(内有关于以太坊平台的概述,并包括平台发布), - -黄皮书(内有关于以太坊技术的实现规范), - -官方网站[https://www.ethereum.org/](https://www.ethereum.org/) 里面有关于包括介绍的视频等以太坊的简要概述, - -本文档介绍了ĐΞV计划如何制定以太坊的软件平台,在以太坊项目的大背景下ĐΞV计划的定位。 - - - -历史与愿景 - - - -在2013年11月创始人Vitalik Buterin对以太坊的核心理念开始有一个明确的看法。动机是为了创建一个有内置的编程语言的加密平台,试图归纳成以下的概念,比如取款限额的存储钱包,多重签名托管,投注,差价合约等。“合同”这个全方位的概念将允许用户用任意算术公式的复杂组合和嵌套的if-then语句来设定资金使用的条件。 - -为了简单和易于开发,项目在质数币的基础上建立元币(为了不激怒比特币的开发者们,因为他们担心以比特币为基础的的已有的元币将会使得块链表不断膨胀),并定于在2014年1月的月底开始发布。在2013年12月Vitalik私下散发了原始的概念白皮书,后来白皮书随着时间的推移被散发到了更广泛的圈子里。 - -此后,该项目的范围已被大大扩展了。早在十二月中旬,随着大量的且出乎意外的爱好者被吸引进来,该项目第一次扩展,具体化成一个独立的块链。然后逐渐扩展到其他的副项目,例如抗集中化的POW算法,一个加密货币研究小组,在美国和瑞士的法务经营,以及以太浏览器的最终理念,还有目前处于概念阶段的代号为“细语(whisper)”和“蜂群(swarm)”的辅助协议。此外,为了有一些重要的基础级应用,真正让以太坊的生态系统大放异彩的要求越来越清晰:一个智能合约和分散式应用程序(Đapps)的开发和调试环境,一个能加强经济和社交互动的信誉系统,一个能公平地分配应用子符号的身份制度,智能合约和网页的的大量域名注册,钱包,当然还有一个应用程序的商店本身(但要注意,下载的应用程序将是免费的)。 - -当然,ĐΞV并不打算开发一切。利用这个技术,目前的贡献者,以及数百位其他加密学家和之前的开发者已经开发并将其应用于解决一系列困难的领域的问题,如消费者保护,公民自由,国际金融和合同,法律,分布式治理,并且可在漫长而艰苦的旅程中保持持续发展。尽管在每一个领域都已经有组织开始行动了。 在一个因为利用加密方式而变得可能的开放,透明,分布式的未来里,ĐΞV只希望并且成为一个小小的但很重要的部分。 - - - -组织结构 - - - -以太坊项目将由以下3个组织组成 - -![](http://bitcoin8btc.qiniudn.com/wp-content/uploads/2014/11/file0002.jpg) - -以太坊基金会: - -总部设在瑞士楚格州的非营利基金会,这个基金是负责为未来加密货币研发和推进开发的其他机构分配资源的伞形公司。该基金会的董事会由Vitalik Buterin(主席),Mihai Alisie(副主席),Taylor Gerring, Stephan Tual, Joseph Lubin, Jeffrey Wilcke 还有 Gavin Wood组成。该基金会将重点放在首要的“使命”上,即,使运营机构来完成每天的日常工作。 - -以太坊瑞士有限公司: - -总部设在瑞士的一家公司,为了领导创世块链的发行,将负责运营2014年度的一部分工作。该公司由以太坊基金会100%控制,计划在创世块链发行后停止运作。 - -ĐΞV: - -将得到两档基金来专门建立的一个非营利性组织,优化和推广以太坊1.0版本。主导开发者Vitalik Buterin,Gavin Wood 和 Jeffrey Wilcke为董事。 - -其他组织: - -包括自律组织(SRO)和非营利性研究机构,这些组织可能会同时得到资助。根据预计,以太坊瑞士有限公司将会协助这些研究机构的起步,以太坊基金会可能将会监督SRO的活动。最终,以太坊基金会还将监督研究机构本身。 - -资助优先顺序: - -以太坊瑞士有限公司将从以太币预售里获得的利润,按照盈利用途资料(其它帖中有解释)中描述一样进行分配。但它保留在必要时修改盈利用途的权利。 - - - -以太坊1.0 - - - -以太坊1.0代表了ĐΞV和以太坊瑞士有限公司和的首要目标。以太坊基金会则将会把兴趣放在促进整个加密空间的发展上。在此时(2014年8月份),以太坊平台发展的状态可以被预计为处于从开始到结束中的中途状态,预计1.0版在2014年末2015年初的期间被发行。 - -自2014年1月份项目成立以来,自愿贡献的开发人员已经完成了以下功能: - -黄皮书中说明的完整的以太坊协议4个近乎兼容的以太坊客户端,分别由C+ +,Go,Python和Java构成Serpent, LLL 和 Mutan的3种编程语言,以及完全正常工作的编译器, 一个可用的JavaScript API ,一个块链协议的概念,允许有12秒的阻塞时间,马上就要被实现建立在经过数个月的对挖矿和POS的研究上的概念=阿尔法版本POW - -由于上述的努力,第三方开发者已经可以并且建成功能完备的分布式应用(“Đapps”),如域名注册,货币,彩票,众筹应用程序和去中心化治理的实用程序,例如由社区建立的“DOUG人民共和国“。 然而,许多困难的工作,包括安全审计,优化策略的即时编译,建立在浏览器上的用户界面和集成开发环境尚未完成。具体的进度请参阅网站上的以太坊1.0开发路线图。 - - - -以太坊客户端 - - - -目前有四个可运行的,分别由C+ +,Go,Python和Java实现的几乎全兼容以太坊协议的客户端。C + +和Go实现的客户端目前完全兼容。 - -Go专用客户端开发 - - ![](http://bitcoin8btc.qiniudn.com/wp-content/uploads/2014/11/file0003.jpg) - -![](http://bitcoin8btc.qiniudn.com/wp-content/uploads/2014/11/file0001.jpg) - - 以太坊浏览器 - -ĐΞV有意使Go客户端成为以太浏览器(EtherBrowser),作为最基本的客户端被个人用户用以访问建立在以太坊上的Đapps。这个客户端正如其所建议的名字的一样,将会成为基于WebKit和Qt的一个全功能的类Web浏览器。我们有意使用同一个应用程序同时浏览传统的集中式网络以及去中心的,更“以太”的网站。目前,这一功能的基本实现已经存在。也可以写一个标准的HTML/ CSS/ JavaScript的网页,使用以ETH对象为JS API与blockchain交互,用户可以使用Go客户端访问该页面以使用Đapp。用QML写Đapps也是一个选项。 还有若干有待完成的重要任务,主要是在提高用户界面体验上。还有一个需要架构和ĐΞV建成的重要组成部分是一个多重钱包和权限制度,为用户提供一个简单而直观的方式来准确地限制Đapps在个人账户上的活动和消费。 - -C++专用客户端开发 - -![](http://bitcoin8btc.qiniudn.com/wp-content/uploads/2014/11/file0004.jpg) - -ĐΞV定义C + +客户端为最基本的开发客户端,允许人们轻松的建立和调试智能合约和Dapp,包括面向合约编程语言和javascrip的语法树意识代码编辑工具,库和软件开发工具包和其他齐全功能。 - -C + +客户端作为以太坊的全功能客户端,包括对以太坊虚拟机(EVM)与块链协议的完全支持,并且包括一个双向步进调试器以帮助开发人员编写智能合同。然而,仍有待做的为去中心化应用提供完整的,产品级的开发环境,全部内容包括JavaScript/ QML和智能合同,集成测试,完整的多语言支持,语法意识的代码编辑器,和其他组件和工具。 - -其他客户端 - -其他三个基准客户端用Python,Java和JavaScript编写。 - -Python的客户端是易于安装,易于使用,多功能的,对开发人员友好的命令行客户端,有可能但不一定会带有最简单的图形用户界面,但功能基本能满足类似pybitcointools库的角色。 - -JavaScript的客户端将会一个简单而简约的装置,主要用于在浏览器中的教学功能,但它最终可能会被用在基于浏览器扩展的客户端。 - -Java客户端可作为特殊硬件的后台程序和Android智能手机。 - -维护在多样化的客户端上的连接和以太坊网络运行强制一个更加整洁的协议的开发和文档备案,并且增加整个系统的健壮性:假设其他的客户端的实现不被影响的前提下,一个问题的客户端的实现不会的话可能会导致整个网络崩溃。 - -扩展性团体目前正在开发其他客户端,包括例如Clojure的,Objective C和node.js。 - - - ![](http://bitcoin8btc.qiniudn.com/wp-content/uploads/2014/11/file0005.jpg) - -共识和安全性测试 - - - -在ĐΞV的努力下,以太坊虚拟机(EVM)的开发者正在试图解决一个非常困难的挑战:用多种实现方式,创建一个递归的,图灵完备的,可以定量计算的虚拟机的规范。每个实现都能对每个程序和输入数据进行同样的处理。因为模型的简约性,在模型中,使用一个自定义,重度封装的虚拟机语言,除非交易允许否则没有网络处理,文件系统访问,直接存储器操作或任何种类的I/O处理。太多的复杂性被大大降低,即便如此仍然需要一个非常广泛的测试套件,以确保错误是尽可能不存在的。 - -另一个重要问题是安全性,在以太坊中有两种类型的的潜在安全问题。首先是虚拟机的安全问题:经常被关注的安全性问题是针对某种缓冲区的溢出攻击是否可能。我们针对这种攻击的防御是简约性,正如之前关于共识的讨论,事实上,共识机制的脆弱性本身就是一个上面提到的非常有效的早期预警系统。如果有一种方法可以在EVM中从“外面的世界”获取数据,那么只要这种方法被利用,无论是故意或由随机的尝试,不同的用户将以不同的方式处理代码,因为它们具有不同的外部状态,将导致可被检测到的即时共识失败。如果研究和协商的结果使得ĐΞV相信,这些论据不足够的话,正式的沙箱的附加层可能会被添加。 - -第二个安全问题是恶意的误导用户的智能合同或Đapps(隐藏其处理的真实理)。为了解决此问题,一个结合权限系统,合同认证和在Đapp商店的信誉系统的多层次方法还有正式的证据将会被使用。合同认证不是必要的,针对某种特殊类型的Dapp,会增加一层监督和保证以确认。当然,任何开发人员可以自由地创建自己的认证系统。 - -共识和安全是主要关键路径项目,没有共识和安全,以太坊1.0将无法发布。 如下图所示,ĐΞV预计,重要的项目大致时间表如下: - -1,开发一个庞大而最大可能完整的测试库,并确保每个EVM通过所有这些测试(4-8周)。 - -2,确保测试继续通过,同时实现即时编译,字典树存储优化和轻客户端的协议(1-4个月)。 - -3,持续的安全审查和测试(最多3个月)。 - -![](http://bitcoin8btc.qiniudn.com/wp-content/uploads/2014/11/file0006.jpg) - - - -细语(Whisper)与蜂群(Swarm)协议 - - - -细语(Whisper)是ĐΞV目前正在开发的一个处于概念阶段的协议,计划成为一个通用的点到点(P2P)通信协议。在以太坊的每个节点可以为自己生成一个基于公钥的地址。细语可让客户端将消息发送给某个特定的接收者,或者通过附加到信息里的描述性标签或“主题“,将消息广播给多个接收者。 节点会聪明的利用尽可能多的有效信息,在彼此之间的路由消息。信息包括已知的有趣的话题(节点可以自由的用广播过滤他们对之感兴趣的话题),以及消息的生存时间(短的消息往往有更高的优先级)。所有的信息都含有生存时间,这样即使接收者处于离线状态,消息可最终通过。 - -细语可能需要1-2周的时间来研究适当的协议规范,然后一个专门的团队在2-4周的时间来实现最初的原型(可能与其他开发并行进行)。我们会持续的把原型改进成一个成熟的实现。 - -![](http://bitcoin8btc.qiniudn.com/wp-content/uploads/2014/11/file0007.jpg) - -蜂群(Swarm) - -蜂群目前是一个处于概念阶段的文件存储和传输协议,专门针对静态网页内容的托管。在峰群里的每一块内容将被存储在P2P网络并通过其哈希值寻址。这样做的目的为了让细语,蜂群和以太坊协议一起被实现,并且可从以太浏览器上访问的,最终成为几乎所有的理论上可以分散的应用程序的的骨干。例如,一个分散的消息系统,它使用户能够即时和异步发送140个文字的消息给其客户,将使用以太坊的名称登记,映射人类可读的帐户的用户名到系统识别的基于公钥的身份认证,因为你肯定不喜欢发送decentralized-blast@ cd2a3d9f938e13cd947ec05abc7fe734df8dd826。这种类型的分散式消息服务将采用细语来发送消息,并用蜂群来存储包括HTML/JS/CSS网页的静态内容。 - -轻量级实现与移动实现 - -自从以太坊项目成立以来,包容性一直是其指导性原则。这意味着努力使以太坊平台向所有人开放。 ĐΞV将努力使轻量级客户端适用于iPhone,安卓以及其它的智能手机用户,无法使用旧笔记电脑处理下载完整区块链的用户,不能做任何实质性的加密技术的特殊手机的用户。在前者的场合,以太坊协议包括一个强壮的轻量级客户端,使轻量级客户端能够取得正确的区块链数据,提供至少一个诚实的充分验证的节点(是单个诚实的节点,而不是多个)。ĐΞV打算用多种编程语言来实现这个协议,以便包容跨平台手机。咋后者场合,可能需要做出一个基于服务器的更集中的的钱包,因为所有的用户都应该得到最好的体验。 - -挖矿算法的研究与发展 - -中本聪原本​​打算让每个人都具有用台式电脑来挖采比特币的能力,从而形成高度分散的共识和平等分配方案。今天的比特币挖矿是一个高度集中的行业。大约有一半的矿工通过两个大型矿池在挖矿,几乎所有的挖矿都由少数几家公司生产的高度专业化的硬件来完成。深圳的一个工厂目前占了几乎所有新的被添加到系统中的哈希力的25%。找出一个更分散的,公平的挖矿算法是困难的但重要的任务,从2013年12月开始已经有不同的人在实现这个任务。 - -有2个挖矿想法被证明是死路,正处在开发的中途阶段的是一个基于更严格的数学策略,随机生成哈希函数的想法,这个想法看起来可以通过初次审核 。 ĐΞV打算开发这个算法,也许会另外加入股权证明(POS),来作为以太坊1.0的共识算法。剩下的主要行动项目是来自学术界和加密货币社区内的专业评审,这一过程很可能会大大的改变算法,还有就是许多重要参数的指导选择(如包含哪些操作,是否要让它内存困难,如何平衡回路的长度和宽度)。 - -![](http://bitcoin8btc.qiniudn.com/wp-content/uploads/2014/11/file0008.jpg) - -分布式应用开发 - -在过去的几年里加密货币技术的发展已逐渐让人们更容易的构建分布式应用。以太坊的区块链和以太浏览器是帮助推动这一趋势的重要工具。然而,还可以建立其它的组件来帮助让Đapps充分发挥其潜力。从本质上说,我们的意图是要建立一套核心应用程序,将提供必要的实用功能,比如说钱包和消息,具体关注“元Đapps”ー帮助其他Đapps的Dapps。这方面的一些例子包括Đapp商店(当然其本身就是Đapp),名称登记(一个或几个),信誉系统,防女巫攻击系统(理想就是在高信任度的场合,让这最后的组件强大到足以作为护照的功能性替代品)和分权治理的工具。以下的列出来的是有可能需要建设和支持的重要的核心Đapps。 - -钱包 - -在加密货币平台最基本的一个应用是钱包。但是,今天能看到的基本的比特币钱包,除了像BitGo一样的创新者以外,在面对可用性和安全性的平衡的挑战上大多数相当薄弱。以太坊平台允许,以先进的取款策略,模仿银行式的保护措施,比如取款限额和不需要信任何来自第三方的单方监管或取款权的双重身份验证,的钱包简单开发出来。建立一个结合上述策略,同时为10美元,1000美元到10万美元提供安全性和便利性之间的最佳平衡的钱包是一项重要的任务。同时拥有使用以太币以及基于以太坊的子货币甚至有可能其他加密货币的能力的钱包将是生态系统的重要福利。 - -细语(Whisper) - -消息平台 – 加密货币的用户喜欢分权和喜欢Skype一样多。但因为以太坊将有细语,还有基于区块链的账户名字登记。为什么不拿出一些资源,创造一个能替代现有的群文本聊天系统的平台?这个平台既是开源的又是点对点的,能使用以太浏览器及相关工具,在一个庞大而成熟的社区形成后启动以太坊平台。随着时间的推移,这样的平台也可以扩展到音频,视频和甚至异步通信,例如电子邮件。细语说明图 - -http://bitcoin8btc.qiniudn.com/wp-content/uploads/2014/11/file0009.jpg - -声望系统 - -为了让电子商务获得成功,在很多情况下,人们必须能够知道谁值得信赖。在某些情况下,你需要分辨诚实的人和骗子。在有些情况下,你要分辨专家的和新手。还有一些时候,它不只是关系到一个人的当前声望是什么,还有他们是如何快速的提高了当前声望,这样你可以确定的,他们不能通过一拍子买卖来欺骗大家获利。即使在现代社会的今天,线上和线下,这些问题是很难解决。在分散自律组织的情况下,这些问题变得更加困难。搞清楚什么可以做,什么应该做的,还有考虑到不同的形式Đapps彼此之间的信任关系,有效的信誉基础设施而言将会是关键问题。 - -身份系统 - -有一种特殊的声望,它涉及一个具体的问题:某个账号是真实存在的人吗?还是由一个人或一个自动化的系统创建的5000个帐户之一。解决这个问题要搞清楚,如何公平地分配应用程序代币或应用程序的使用优先权,即使没有花钱也要让每个人都可以有限的访问生态系统,等事情的关键。一个有趣的建议是,用准分散的方式实现的话,可以用“非女巫式代币”的投机市场。任何人都可以创建一个“完全自动化的公共图灵测试来分辨计算机和人类”(简称CAPTCHA)方案(理论上可以包括抄写一些字母和数字,玩游戏,证明社会关系,或者比较传统的像手机号码或护照),但只有在公开的情况下否则违反任何个人方案都会非常有利可图的。任意一个ĐAO/Đapp可以观察一下整个系统,看看哪些CAPTCHA机制仍然是安全的,并自动使用这些安全的机制。 - -分散的挖矿池基础设施 - -如果区块链变得非常大,挖矿变得普及起来话,那么就像比特币的情况一样,矿池可能会变得有必要。然而,在这种情况下,ĐΞV决心要最大限度地让分散式的代替方案更有利,比如说P2P矿池而不是集中式解决方案。即便要求必须要用集中式的解决方案,保守的预计我们会建立一个“制作自己矿池”的工具,使市场更具流动性,减少因为矿工规模大小而导致的支付差异,降低入门门槛。 - -除了这些重要的核心应用,如果在被给予足够多的资源的前提下,也有一些是ĐΞV可以选择参与建立的其他应用程序。包括: - -1、分散式交易所(基于以太币的资产和不同的加密货币之间) -2、分散式市场 -3、众筹 -4、托管,消费者保护和仲裁 -5、内容发布(包括激励内容创作者) -6、金融应用(例如对冲,先令美元,保险) -7、分散的广告协议 -8、分散的组织管理 - -虽然ĐΞV打算在“核心”的应用程序上努力,但我们可能会有以下几种形式来参与更多外围Đapps上的开发:在某个项目上ĐΞV可以完全靠自己的努力,ĐΞV可以简单地建立某解决方案的核心部分,并允许其他人继续完成其他部分。或者ĐΞV可以从向社区中的已经接受任务的外部团体提供资金,技术或开发支持给。 - -社区推广以及教育 - -虽然推动以太坊发展的底层的技术可以说相当先进,我们的主要目标一直是让广大的开发者能够接触到以太坊平台的强大功能。 HTML的技能,再加上一些JavaScript的知识是建立大多数分散型应用的全部知识。底层的“加密”层被巧妙的抽象到了面对用户友好的API的背后。对于终端用户而言,如果他们愿意使用Web浏览器,他们肯定会喜欢上使用以太浏览器的。 - -一个无需开发人员和终端用户的以太坊平台,将看到朝着分散式网络努力已经是徒劳的。因此ĐΞV需要确保(1)人们了解以太坊和(2)人们都知道如何利用它。为此,该项目的一个重要组成部分,是维护我们的在线和离线的存在,帮助支持世界各地的中心和社区,并最终组织或合作组织会议(无论是专门针对以太坊,还是针对分散式网络这个整体)。 - -这一努力的另一个重要组成部分是教育,包括发布易于使用的在线教程和为了理解以太坊平台的网络大学Udemy的课程,以及智能合约/Đapp编程研讨会。黑客马拉松也可能属于这一类。 - -网上开放课程 - -海量的网络公开课 – 从头到尾的完整的以太坊和智能合约/Dapp开发的在线课程已经被指定开发了。课程将会包括视频,文字材料,练习和人们可以很容易地尝试编写以太坊代码的编程环境。这个课程的目的是能对任何想学习以太坊平台使用的人有用处。ĐΞV也可能,或者是靠自己或者依靠协同合作,来创造不同的难度/深度/水平或不同学科领域的多种课程(如经济学,加密学,社会理论,计算机科学和编程)。 - -开放教程 - -教程和文档 – 对于那些没有耐心去通过完整课程的人,需要有描述以太坊平台的高层次和低层次的所有组成部分,还有解释如何执行作为一个开发者想做的的所有常见的操作(如写智能合同,开发Đapp,发布Đapp,发送交易,使用蜂群Swarm,使用细语Whisper),并且容易理解的文档。此外,还有可能需要用户的教程,虽然首要任务是使分散的Web像传统的,现时的浏览器一样简单和随便。 - -开放交流 - -在线交流 – 这包括继续对我们的公共博客,论坛,维基渠道,以及任何其他第三方渠道(比如Facebook,Twitter,Google+,Reddit)的交流进行维护。主要目的是确保每个人都可以很简单的获得最新和准确的关于对以太坊计划中的所有部分的状态和信息 - -开放社区 - -离线交流 – 这主要包括全世界各地支持以太坊和关注于分散式网络的群体的聚会,这最终可能会扩展到成完全成熟的会议。 ĐΞV打算在世界上尽可能多的地方设立代表,包括北美洲,中/南美洲,欧洲,亚洲和非洲。我们目前的聚会地点的人脉网络将成为这一工作的中坚力量。 - -开放访问性 - -翻译 – 国际化的一个重要组成部分是支持多种语言的使用。目前已经有部分中文翻译,以及一些德语和西班牙语的翻译,但最终所有的以太坊平台的客户端,文档和在线课程材料都必须被翻译成多国语言。 ĐΞV总是在寻找的各种语言的具有技术常识的翻译者。 - -加密经济学研究和继续开发 - -以太坊的当前状态是很强大的,1.0版本发布后也会如此,但是这离完美还远远不够。挖矿算法可能不会坚持分散性这个目标,也许计算生态系统作为一个整体可能会非常严重地转向瘦客户机,作为一个整体的,分散性的计算能力可能会成为一个无法实现的理想。它的可扩展性目前与比特币相比较也好不到哪里去,因为每个节点仍然必须处理每笔交易。比如PeterTodd的树链,超立方体链,资源证明,还有如Eli Ben-Sasson的 的简洁计算完整性和保密性协议(简称SCIP,也被称为PCP或ZK-SNARK)等可能的“月亮数学”加密,之类的新概念可能不会被包含在以太坊1.0版本中。 - -由于加密货币将来的发展有很多可能的方向,没有人能预测在遥远的将来正确的决定是什么,所以在以太坊1.0发布后,不能做出任何关于开发可能性的细节承诺。但是,关于目前加密货币研究的一个大方向,已经有一个相当不错的愿景已经浮现了。 - -扩展性 – 这里的主要挑战是要拿出一个区块链设计来打破现在的区块链的扩展性的障碍。事实上现在,每一个充分验证的节点必须处理每一笔交易。已经有主要是关于比特币的一些想法被发展起来,如合并挖矿的超立方体链,Peter Todd’s的树连锁的想法,还有基于先进的加密技术(SCIP/zk-SNARK)的策略,但仍有很多研究需要做。一个成功的有扩展性的解决方案将需要处理跨越不同的实体存储在不同国家的货币,不能牺牲(太多)挖矿的安全,即使有些数据不可用,必须保证该协议继续工作。运气好的话,一个解决方案将在2014年和2015年期间被完成。 - -共识 – 正如上面所讨论的,共识算法是远远不够完善的。计划里,用基于区块链的POW,还有随机计算树,似乎很有希望来解决这个问题。但最终的这种形式的以太坊1.0版本很可能无法承受长期的攻击。一个理想的算法,同时具有对社会的无成本和负成本,促进高水平的分权和安全性,可能会需要新颖的下列方法的组合,如交易的POS(股权证明),委托POS(DPOS),有用的POW(工作证明),新一代抗集中/ ASIC的POS和更奇特的涉及带宽和存储的策略。开发这样的算法,并确保它确实可行,是确保明天的区块链安全的一个重要的优先事项。 - -隐私保护 – 区块链的极不完善的隐私性是非常有名的。到今日的以太坊平台的设计,在这方面也是公认的没有特别的有效方案。然而,未来的提高隐私的开发,如基于SCIP/zk-SNARK的算法都将来临,有的一些基于如CryptoNote和CoinJoin的技术已经存在了。 - -语言和开发工具的设计 – 从以太坊平台早期的讨论和规划中涌现出的另一个重要的子交付是完全确定计算量的,状态散列的多个完全可互相操作的虚拟机的实现。以太坊虚拟机(EVM)无论是在区块链还是对手的,资源受限的环境中都非常有用,并会从不断开发中就其本身受益。如果多区块链架构成为主流范式,EVM还可能需要被更新,以处理诸如不同步的情况。除了EVM本身,有Serpent, LLL and Mutan的高级语言,为了建立分布式应用ĐΞV已经开始致力于建立专门的开发环境。 - -后量子加密 – 如果量子计算机变的普及起来。那目前以太坊平台上的签名交易,依赖的椭圆曲线签名算法,会被破坏。然而,确实存在着一类签名算法,它们能够抵抗量子计算的攻击,最著名的是Lamport签名。Lamport签名在其构建时候除了一个哈希算法外没有使用任何其它东西,但它占用上千字节的,且仅限于一次性使用。被改善的称为Merkle签名树和哈希阶梯将解决这些问题,但还是不完美的。这些算法改善得越多,更多的人就可以对量子计算到来的那一天不会出现问题而感到自如。 - -月亮数学加密(Moon-math cryptography) -在纯加密科学界最令人振奋的开发围绕着3个圣杯。 第一个是完全同态加密:在不知道数据是什么的情况下,能够对加密数据运行函数来得到一个加密的结果,这将允许云计算做到几近完全的隐私。二是上面提到的SCIP,有效简洁的可验证的证明允许一个特定的长的计算有一个给定的结果。最后一个是困惑:能够在不知道函数是什么的情况下,运行数据加密功能,它允许使用带有私有数据的脚本在区块链上运行。所有这些问题都有从开发的早期到中期阶段的解决方案,但解决方案目前不是在效率就是在信任要求上有大量的缺点。如果解决方案能够完善或至少改进到有生存能力的那点的话(SCIP是非常接近了),加密经济协议可能会变得更加强大。 - -DAO化 – 可以建立在以太坊上的事情的想法中,最令人兴奋的是去中心化自治组织(DAO)的概念。传统的组织,无论是企业还是非营利性,无非是一套人马,一组资源和一套管理谁可以使用资源的规则。在DAO里,规则并不是如同在现实世界里的被强制执行的和司法系统,而是在区块链上以分散和透明的方式强制执行。比如说不同于传统的现代跨国公司,那里是核心的智能化和外围的自动化,在一个DAO里,核心是自动化,外围是人类智慧来提供创意输入。DAO的主要的中期吸引人的地方在(1)消除员工,投资者,客户和非雇员之间的严重差别的梦想,让DAO促进更细致的,更活跃的关系,并充分利用人类贡献的全部幂律曲线以及(2)尝试新的​​组织管理机制,如流动体民主主义和部分被投机市场控制的理论上的政府。最后,DAO,工厂自动化和AI的概念甚至可能完全合并。 - -CCRG – 为了专门推动加密货币研究,ĐΞV正在推出一个叫作加密货币研究小组的机构。这个机构正处于开发的早期阶段。它的领域活动包括加密技术,加密货币,经济,金融,法律,政治及其他,在未来数个月内将会大幅加速发展。预计它会成长为一个从其他加密货币空间的团体,以及高新技术企业和慈善家来吸取资金,完全或很大程度上自治的组织。可能会创建独立的机构来专门开发协议。如果要想知道加密货币研究的更多的全面的意义,请读正在写作中的“加密经济难题”论文。 - -自律组织 – 从技术的角度来看或许是乏味的,实现接受分散式技术的一般使命的重要部分就是就是参与合法的流程,并帮助开拓一个合法的环境,在这个环境里一些项目,例如以太坊平台,建立在以太坊平台上的Dapp,还有其它的加密货币/基于Web的初步的分散式网络,可以安全地茁壮成长而不受过分的限制。其中,以太坊瑞士有限公司正在进行的初步行动是,与OpenTransactions,比特币瑞士等进行协作,为了这个目的在其家乡瑞士开发一个自律组织。以太坊瑞士有限公司正在与有自律组织的建成经验的当地律师事务所一起紧密合作,并且最小的自律组织可以用低于10万美元来维持运营。额外的资金可以让自律组织扩大其范围和影响力,也迟早会让这些工作超越瑞士。 - -其他项目 - -当然,上面只是一个向导,ĐΞV可以选择不追求上面的一些或者采用超出上述类别的其他项目。一些特定的可能性包括: - -DAO化 – 虽然DAO化肯定会是加密货币的一个主要的研究重点,长期的计划总是把不同的以太坊组织变成DAO,通过建立一个长期的管理平台,可以用于继续研究和开发来作为一个驱动社区发展的活动。 - -会议 – ĐΞV可以选择,无论是单方还是在与业内其他团体协调,来组织与分散网络相关的技术,法律,社会可能性的会议。这样的会议可以是以营利为目的获得持续收入来源或非营利但以收回成本的原则运行。除了会议,还有组织以开发人员为中心的教育研究会的可能。 - -中心 – 在比特币社区有一个流行的想法,即创建特定的比特币中心。在设施中,比特币用户可以正常工作,可能生活和互动。在蒙特利尔和特拉维夫的比特币大使馆,在多伦多的比特币非中心和在纽约的比特币中心都是突出的例子。 ĐΞV不妨为社区建设活动而协助建立更多这类中心。 - -本文供参考。 - - - - diff --git "a/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\346\234\257\350\257\255\350\241\250.md" "b/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\346\234\257\350\257\255\350\241\250.md" deleted file mode 100644 index 787cf22e5..000000000 --- "a/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\346\234\257\350\257\255\350\241\250.md" +++ /dev/null @@ -1,128 +0,0 @@ ---- -name: 术语表 -category: ---- - -翻译:Andy - -关于加密货币以及任何新的技术的令人不爽的一件事,就是其用于描述所有新概念的词汇的绝对数量。只要不是临时的,最基本的处理的情况,任何与在点对点互联网软件打交道的人都需要与加密的概念打交道,包括散列,签名,公钥,私钥,对称和不对称加密,服务保护拒绝,还有例如分布式哈希表,信任网络之类的神秘的构造。新的比特币用户被迫与学习加密的基本常识而奋斗,还有额外的内部术语,如“区块”,“确认”,“挖矿”,“SPV客户”和“51%的攻击”,以及经济概念,如激励相容和集权与分权的微妙差别。以太坊,作为一个基于加密货币的泛化的分散的应用开发平台,必然既包含这些概念的集合,也增加了许多自身的概念。为了帮助新来以太坊的人,无论他们是加密货币爱好者,企业家,社会或政治愿景家,Web开发人员或只是看看这项技术能如何改善生活的普通人,下面的列表的目的是为了提供一个以太坊用户常常使用的词汇的基本总结: - -密码学 - -另请参阅:http://en.wikipedia.org/wiki/Public-key_cryptography - -计算上不可行:一个处理被称为是计算上不可行,如果有人想有兴趣完成一个处理但是需要采取一种不切实际的长的时间来做到这一点的(如几十亿年)。通常,2的80次方的计算步骤被认为是计算上不可行的下限。 - -散列:一个散列函数(或散列算法)是一个处理,依靠这个处理,一个文档(比如一个数据块或文件)被加工成看起来完全是随机的小片数据(通常为32个字节),从中没有意义的数据可以被复原为文档,并且最重要的性能是散列一个特定的文档的结果总是一样的。 - -此外,极为重要的是,找到具有相同散列的两个文件在计算上是不可能的。一般情况下,即使改变文件的一个字母也将完全打乱散列;例如,“ Saturday”的SHA3散列为c38bbc8e93c09f6ed3fe39b5135da91ad1a99d397ef16948606cdcbd14929f9d,而Caturday的SHA3散列是b4013c0eed56d5a0b448b02ec1d10dd18c1b3832068fbbdc65b98fa9b14b6dbf。散列值经常被用作以下用途:为无法伪造的特定文档而创建的全局商定标识符。 - -加密:与被称为钥匙(例如c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4)的短字符串的数据相结合,对文档(明文)所进行的处理。加密会产生一个输出(密文),这个密文可以被其他掌握这个钥匙的人“解密”回原来的明文,但是对于没有掌握钥匙的人来说是解密是费解的且计算上不可行。 - -公钥加密:一种特殊的加密,具有在同一时间生成两个密钥的处理(通常称为私钥和公钥),使得利用一个钥匙对文档进行加密后,可以用另外一个钥匙进行解密。一般地,正如其名字所建议的,个人发布他们的公钥,并给自己保留私钥。 - -数字签名:数字签名算法是一种用户可以用私钥为文档产生一段叫做签名的短字符串数据的处理,以至于任何拥有相应公钥,签名和文档的人可以验证(1)该文件是由特定的私钥的拥有者“签名”的,(2)该文档在签名后没有被改变过。请注意,这不同于传统的签名,在传统签名上你可以在签名后涂抹多余的文字,而且这样做无法被分辨;在数字签名后任何对文档的改变会使签名无效。 - -区块链 - -也可参考:https://bitcoin.org/zh_CN/vocabulary - -地址:一个地址本质上是属于特定用户的公钥的表现;例如,与上面给出的私钥的相关联的地址是cd2a3d9f938e13cd947ec05abc7fe734df8dd826。注意,在实际中,地址从技术上来说是一个公钥的散列值,但为了简单起见,最好忽略这种区别。 - -交易:一个交易是一个文档,授权与区块链相关的一些特定的动作。在一种货币里,主要的交易类型是发送的货币单位或代币给别人;在其他系统,如域名注册,作出和完成报价和订立合约的行为也是有效的交易类型。 - -区块:一个区块是一个数据包,其中包含零个或多个交易,前块(“父块”)的散列值,以及可选的其它数据。除了初始的“创世区块”以外每个区块都包含它父块的散列值,区块的全部集合被称为区块链,并且包含了一个网络里的全部交易历史。注意有些基于区块链的加密货币使用“总账”这个词语来代替区块链。这2者的意思是大致相同的,虽然在使用“总账”这个术语的系统里,每个区块都通常包括每个账户的目前状态(比如货币余额,部分履行的合约,注册)的全部拷贝,并允许用户抛弃过时的历史数据。 - -帐户:帐户是在总账中的记录,由它的地址来索引,总账包含有关该帐户的状态的完整的数据。在一个货币系统里,这包含了货币余额,或许未完成的的交易订单;在其它情况下更复杂的关系可以被存储到账户内。 - -工作证明:在比特币,以太坊和许多其他加密总账里的一个重要特性,意思是在区块中的散列值必须比某个目标值小。这个必要的原因是,在分散式系统中任何人可以产生区块,因此为了防止网络中区块泛滥,并提供一种方法来衡量在区块链的一个特定版本后有多少共识,使得产生一个区块非常艰难。由于散列值是伪随机的,找一个散列值比0000000100000000000000000000000000000000000000000000000000000000还小的区块,平均需要43亿次尝试。在所有这些系统中,目标值进行自我调整以便在网络上的一个节点平均每N分钟(例如,比特币N =10,以太坊N=1)发现一个区块, - -随机数:在一个区块里的一个无意义的值,为了努力满足工作证明的条件来进行调整。 - -挖矿:挖矿是反复总计交易,构建区块,并尝试不同的随机数,直到找到一个随机数可以符合工作证明的条件的过程。如果一个矿工走运并产生一个有效的区块的话,会被授予的一定数量的币(区块中的交易全部费用)作为奖励。而且所有的矿工开始尝试创建新的区块,这个新区块包含作为父块的最新的区块的散列。 - -陈腐区块:对于同一个父块,已经有另外一个区块被创建出来之后,又被创建的区块;陈旧区块通常被丢弃,是精力的浪费。 - -分叉:指向同一个父块的2个区块被同时生成的情况,某些部分的矿工看到其中一个区块,其他的矿工则看到另外一个区块。这导致2种区块链同时增长。通常来说,随着在一个链上的矿工得到幸运并且那条链增长的话,所有的矿工都会转到那条链上,数学上分几乎会在4个区块内完结自己。 - -双重花费:是一个故意的分叉,当一个有着大量挖矿能力的用户发送一个交易来购买产品,在收到产品后又做出另外一个交易把相同量的币发给自己。攻击者创造一个区块,这个区块和包含原始交易的区块在同一个层次上,但是包含并非原始交易而是第二个交易,并且开始在这个分叉上开始挖矿。如果攻击者有超过50%的挖矿能力的话,双重花费最终可以在保证在任何区块深度上成功。低于50%的话,有部分可能性成功。但是它经常在深度2-5上有唯一显著的可能。因此在大多数的加密货币交易所,博彩站点还有金融服务在接受支付之前需要等待6个区块被生产出来(也叫“6次确认”)。 - -SPV客户端(或轻客户端):一个只下载一小部分区块链的客户端,使拥有像智能手机和笔记本电脑之类的低功率或低存储硬件的用户能够保持几乎相同的安全保证,这是通过有时选择性的下载的小部分的状态,而在区块链验证和维护时,不需要花费兆字节的带宽或者千兆字节的存储空间。 - -以太坊区块链 - -也可参考: http://1tf.org/index.php?p=/discussion/71/ - -序列化:将一个数据结构转换成一个字节序列的过程。以太坊在内部使用的编码格式称为递归长度前缀编码(RLP),在这里有描述 - -帕特里夏树:一种数据结构,它会存储每个帐户的状态。这个树的建立是通过从每个节点开始,然后将节点分成多达16个组,然后散列每个组,然后对散列结果继续散列,直到整个树有一个最后的“根散列”。该树具有重要的特性:(1)只有正好一个可能的树,因此,每个数据集对应一个可能的根散列(2)很容易的更新,添加,或者删除树节点,以及生成新的根散列,(3)不改变根散列的话没有办法修改树的任何部分,所以如果根散列被包括在签名的文档或有效区块中话,签名或工作证明可以担保整个树( 4)任何人只可以提供一个下到特定节点的分支,可以加密得证明拥有确切内容的节点的确是在树里。帕特里夏树也被用来存储账户,交易已经叔块的内部存储。在这里能看到更详细的说明。 - -幽灵(Ghost):幽灵是一个协议,通过这个协议,区块可以包含不只是他们父块的散列值,也散列父块的父块的其他子块(被称为叔块)的陈腐区块。这确保了陈腐区块仍然有助于区块链的安全性,并减轻了大型矿工在快速区块链上的有优势的问题,因为他们能够立即得知自己的区块,因此不太可能产生陈腐区块。 - -叔块:是父区块的父区块的子区块,但不是自个的父区块,或更一般的说是祖先的子区块,但不是自己的祖先。如果A是B的一个叔区块,那B是A的侄区块。 - -帐户随机数:每个账号的交易计数。这样可以防止重放攻击,其中一个交易发送比如 20个币从A到B,并可以被B重放一遍又一遍,直到不断抽干A的账户余额。 - -EVM代码:以太坊虚拟机代码,以太坊的区块链可以包含的编程语言的代码。与帐户相关联的EVM代码在每次消息被发到这个账户的时候被执行,并且具有读/写存储和自身发送消息的能力。 - -消息:一种由EVM代码从一个账户发送到另一个账户的“虚拟交易”。需要注意的是“交易”和“消息”在以太坊种是不同的;在以太坊用语的“交易”具体指的是物理的数字签名的一串数据,并且每个交易触发相关联的消息,但消息也可以通过EVM代码发送,在这种情况下,它们从不表示成任何数据。 - -储存:包含在每个帐户里的键/值数据库,其中键和值都是32个字节的字符串,但可以以其他方式包含任何东西。 - -外部拥有账户:通过私钥控制的账户。外部拥有账户不能包含EVM代码。 - -合约:一个包含并且受EVM的代码控制的账户。合约不能通过私钥直接进行控制,除非被编译成EVM代码,一旦合约被发行就没有所有者。 - -以太(Ether):以太坊网络的内部基础的加密代币。以太是用来支付交易和以太坊交易的计算费用。 - -瓦斯:大致相当于计算步骤的计量。每一笔交易需要包括瓦斯的限制,还有愿意为每瓦斯支付的费用;矿工可以选择是否收录交易和收集费用。由包括原始消息以及任何可能被触发的子消息的交易产生的计算所使用的瓦斯总量,如果大于或者等于瓦斯的限制,则交易被处理。除非交易仍然有效并且费用仍然被矿工收集,否则瓦斯的总量小于限制则所有变更被还原。每一个操作都有瓦斯支出;对于大多数操作,花费是1瓦斯,尽管一些昂贵的操作会支出高达100瓦斯,交易本身会有500瓦斯的支出。 - -非区块链 - -以太浏览器(Mist):即将到来的以太坊基础客户端,会以Web浏览器的形式存在,可被用来访问正常的网站以及建立在以太坊平台上的应用程序。 - -耳语(Whisper):即将到来的点到点信息协议,将会被整合到以太浏览器。 - -蜂群(Swarm):即将到来的,为静态web托管而优化的点到点数据存储协议,将被整合到以太浏览器。 - -LLL,Serpent和Mutan:为编写合约代码的编程语言,可被编译成EVM代码。serpent可以被编译为LLL。 - -PoC:概念证明(proof-of-concept)的英文缩写,预发布版的另一个称呼。 - -周边概念:应用程序和治理 - -分散化应用程序:为了某些特定目的(如:在某些市场上连接买家和卖家,共享文件,网络文件存储,维持货币),无论是使用还是创建一个分散的网络,由许多人来运行的程序。基于以太坊的分散式的应用程序(也称为Đapps,其中Đ为北欧字母“eth”)通常包括一个HTML/ JavaScript的网页,并且如果在以太浏览器内部查看的话,可识别特殊的Javascript的API,用于发送交易数据到区块链,从区块链读取数据,和耳语,蜂群交互数据。一个Đapp通常在区块链上有特定的相关合约,但有利于创造许多合约的Đapps是完全可能的。 - -分散化组织(GDO):一个没有中央领导,而是使用正式民主投票进程和共识主动性自我组织的结合来作为其基本操作原则。一个不太令人印象深刻,但有时混淆的概念是“地理上的分散化组织”(GDO),组织里人在相距甚远的地方工作,甚至可能都没有办公室; GDOs可能会有正式的中央领导。 - -忒修斯标准:用于查明一个组织的分散化程度的测试。测试如下:假设组织有N个人,然后外星人一次从组织中(比如每周一次)挑选K个人出来,摧毁他们存在,在每个群里以K个对组织不了解的新人来代替。现在为了让组织起作用,K可以高达多少人呢?在独裁政权里,当K=1即独裁者被摧毁后就会失败。美国政府稍微好一点,但如果参议院和国会的所有638成员突然消失了的话,仍然会有很大的问题。但像比特币或BitTorrent即便对极高的K值也具有复原性,因为新的代理人可以简单地根据自己的经济动机来填补缺失的角色。还有一个更严格的测试,拜占庭忒修斯标准,它包含同一时间内随机的用恶意行为者取代K个用户一段时间,之后再替换成新用户。 - -委任式民主(或流动式民主):一个对于DOs(分散式组织)和DAO(分散式自治组织)的治理机制,在默认情况下每个人对每件事情都投票,但在某些特定的问题上个人可以选择特定的他人为他们投票。这个想法概括了以下2种民主的权衡,完全直接民主(每个人都有相同的权力)和专家意见/有某些特定人提供的快速决策能力(允许人们自己顺从朋友,政治家,领域专家或者自己选择的任何人)。 - -部分被投机市场控制的理论上的政府:最初是由Robin Hanson提出的,为了管理政治组织治理机制。但它实际上是非常适用DOs和DAO的:通过预测市场来管理。从根本上,一些易于衡量成功的标准被选择,还有发行由成功标准的值来决定的代币,这些代币将在未来的某个时间(例如,1年后)被支付,对于每个可能要采取的行动都用一个这样的代币。这些代币都被兑换为相应的美元代币,如果相应的措施被执行,正好1美元会被支付 (如果相应的措施没有被执行,这两种类型的代币支付0美元,所以正在被执行的行动的概率不会影响价格)。市场预计的行动将有最好的结果,当其代币在市场上有高价格时会被执行。这提供了另一种自治的,选择机制,同时奖励专家的意见。 - -经济学 - -代币制度:本质上是可以交易的虚拟代替物。更正式地说,代币制度是一个数据库,它映射地址到数字,并具有以下属性,基本允许的操作是把N个代币从A转给B,条件是N是非负,且N不小于A的当前余额,授权该转账的证件由A进行数字签名。二次“发行”和“消费”的操作也可以存在,交易费用也可以被收集,许多当事人同时进行转账也是可能的。典型应用案例,包括货币,网络加密代币,公司的股份和数字礼品卡。 - -命名空间:一个映射名字到值的数据库。举个最简单的例子,如果名称尚未被占有的话(也许可以在支付一些费用之后)任何人可以注册一个条目。如果名称已经被占有了,那么就只能被改变(如果有的话),由作出原始注册的账户(在许多系统中,所有权也转移)。命名空间可以用来存储用户名,公钥,互联网域名,代币制度或其他命名空间,和许多其他应用。 - -身份:一组可以加密验证的互动,具有同一个人创建的的属性。 - -唯一的身份:一组可以加密验证的互动,具有以下属性:同一个人创建的。再加上一个人不能有多个唯一身份的约束。 - -激励相容:如果每个人都更好的“遵守规则”而不是试图欺骗,除非至少要大量的人都同意同时一起欺骗,那么协议是激励相容的。 - -基本收入:每隔一段时间(比如几个月)就给每一个唯一的身份发送一定量的代币的想法。其最终目的是为了让不愿意工作或者不能工作的人能够依靠这份津贴活下来。这些代币可以简单的凭空制作出来,或者来自收益流(比如来自创收实体或政府)。为了单靠基本收入使人能够生活,可能会用到多个收益流的组合。 - -公益:一个为非常多的人提供了一个非常小的好处的服务。这样就没有任何个体对是否进行生产有影响力,因此也没有人有动力来支付。 - -声誉:身份的一个属性,其他实体认为这个身份可以(1)胜任一些特定的任务,或(2)在一些情况下是值得信赖。比如说不太可能因为短期的获利而出卖别人。 - -信任网络:如下的想法,如果A高度信任B,B高度信任C,则A可能是信任C的。为决定特定个体在特定概念下的可靠性的复杂而有力的机制,理论上可以由这个原则推断出来。 - -第三方托管:如果两个低信誉的实体所从事的贸易时,付款人可能希望把钱留在具有高信誉的第三方,并指示只有在产品交付后,才让第三方把钱发给收款人。这减少了付款人或收款人欺诈的风险。 - -保证金:放入合约里的涉及另外一方的数字资产,如果某些条件不满足时,该资产会自动被对方没收。 - -抵押:放入合约里的涉及另外一方的数字资产,如果某些条件不满足时,该资产会自动被销毁或据献给慈善或者基本收入基金。也许可以让利益广泛分配,但必须让特定的个人不能显著的受益。 diff --git "a/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\347\231\275\347\232\256\344\271\246.md" "b/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\347\231\275\347\232\256\344\271\246.md" deleted file mode 100644 index a2e59f48e..000000000 --- "a/[\344\270\255\346\226\207]-\344\273\245\345\244\252\345\235\212\347\231\275\347\232\256\344\271\246.md" +++ /dev/null @@ -1,475 +0,0 @@ -### 以太坊(Ethereum ):下一代智能合约和去中心化应用平台 - -翻译:巨蟹 、少平 - -译者注:中文读者可以到[以太坊爱好者社区](http://www.ethfans.org)获取最新的以太坊信息。 - -当中本聪在2009年1月启动比特币区块链时,他同时向世界引入了两种未经测试的革命性的新概念。第一种就是比特币(bitcoin),一种去中心化的点对点的网上货币,在没有任何资产担保、内在价值或者中心发行者的情况下维持着价值。到目前为止,比特币已经吸引了大量的公众注意力, 就政治方面而言它是一种没有中央银行的货币并且有着剧烈的价格波动。然而,中本聪的伟大试验还有与比特币同等重要的一部分:基于工作量证明的区块链概念使得人们可以就交易顺序达成共识。作为应用的比特币可以被描述为一个先申请(first-to-file)系统:如果某人有50BTC并且同时向A和B发送这50BTC,只有被首先被确认的交易才会生效。没有固有方法可以决定两笔交易哪一笔先到,这个问题阻碍了去中心化数字货币的发展许多年。中本聪的区块链是第一个可靠的去中心化解决办法。现在,开发者们的注意力开始迅速地转向比特币技术的第二部分,区块链怎样应用于货币以外的领域。 - -常被提及的应用包括使用链上数字资产来代表定制货币和金融工具(彩色币),某种基础物理设备的所有权(智能资产),如域名一样的没有可替代性的资产(域名币)以及如去中心化交易所,金融衍生品,点到点赌博和链上身份和信誉系统等更高级的应用。另一个常被问询的重要领域是“智能合约”- 根据事先任意制订的规则来自动转移数字资产的系统。例如,一个人可能有一个存储合约,形式为“A可以每天最多提现X个币,B每天最多Y个,A和B一起可以随意提取,A可以停掉B的提现权”。这种合约的符合逻辑的扩展就是去中心化自治组织(DAOs)-长期的包含一个组织的资产并把组织的规则编码的智能合约。以太坊的目标就是提供一个带有内置的成熟的图灵完备语言的区块链,用这种语言可以创建合约来编码任意状态转换功能,用户只要简单地用几行代码来实现逻辑,就能够创建以上提及的所有系统以及许多我们还想象不到的的其它系统。 - -### 目录 - -* 历史 - * 作为状态转换系统的比特币 - * 挖矿 - * 默克尔树 - * 替代区块链应用 - * 脚本 -* 以太坊 - * 以太坊账户 - * 消息和交易 - * 以太坊状态转换功能 - * 代码执行 - * 区块链和挖矿 -* 应用 - * 令牌系统 - * 金融衍生品 - * 身份和信誉系统 - * 去中心化文件存储 - * 去中心化自治组织 - * 进一步的应用 -* 杂项和关注 - * 改进版幽灵协议的实施 - * 费用 - * 计算和图灵完备 - * 货币和发行 - * 挖矿的中心化 - * 扩展性 -* 综述:去中心化应用 -* 结论 - * 注解和进阶阅读 - -### 历史 - -去中心化的数字货币概念,正如财产登记这样的替代应用一样,早在几十年以前就被提出来了。1980和1990年代的匿名电子现金协议,大部分是以乔姆盲签技术(Chaumian blinding)为基础的。这些电子现金协议提供具有高度隐私性的货币,但是这些协议都没有流行起来,因为它们都依赖于一个中心化的中介机构。1998年,戴伟(Wei Dai)的b-money首次引入了通过解决计算难题和去中心化共识创造货币的思想,但是该建议并未给出如何实现去中心化共识的具体方法。2005年,芬尼(Hal Finney)引入了“可重复使用的工作量证明机制”(reusable proofs of work)概念,它同时使用b-money的思想和Adam Back提出的计算困难的哈希现金(Hashcash)难题来创造密码学货币。但是,这种概念再次迷失于理想化,因为它依赖于可信任的计算作为后端。 - -因为货币是一个先申请应用,交易的顺序至关重要,所以去中心化的货币需要找到实现去中心化共识的方法。比特币以前的所有电子货币协议所遇到的主要障碍是,尽管对如何创建安全的拜占庭问题容错(Byzantine-fault-tolerant)多方共识系统的研究已经历时多年,但是上述协议只解决了问题的一半。这些协议假设系统的所有参与者是已知的,并产生如“如果有N方参与到系统中,那么系统可以容忍N/4的恶意参与者”这样形式的安全边界。然而这个假设的问题在于,在匿名的情况下,系统设置的安全边界容易遭受女巫攻击,因为一个攻击者可以在一台服务器或者僵尸网络上创建数以千计的节点,从而单方面确保拥有多数份额。 - -中本聪的创新是引入这样一个理念:将一个非常简单的基于节点的去中心化共识协议与工作量证明机制结合在一起。节点通过工作量证明机制获得参与到系统的权利,每十分钟将交易打包到“区块”中,从而创建出不断增长的区块链。拥有大量算力的节点有更大的影响力,但获得比整个网络更多的算力比创建一百万个节点困难得多。尽管比特币区块链模型非常简陋,但是实践证明它已经足够好用了,在未来五年,它将成为全世界两百个以上的货币和协议的基石。 - -### 作为状态转换系统的比特币 - -![](https://camo.githubusercontent.com/e7a1fc59abdd42654fa8c54c0f847eb2c8fda72e/687474703a2f2f766974616c696b2e63612f66696c65732f73746174657472616e736974696f6e2e706e673f32) - -从技术角度讲,比特币账本可以被认为是一个状态转换系统,该系统包括所有现存的比特币所有权状态和“状态转换函数”。状态转换函数以当前状态和交易为输入,输出新的状态。例如,在标准的银行系统中,状态就是一个资产负债表,一个从A账户向B账户转账X美元的请求是一笔交易,状态转换函数将从A账户中减去X美元,向B账户增加X美元。如果A账户的余额小于X美元,状态转换函数就会返回错误提示。所以我们可以如下定义状态转换函数: - - APPLY(S,TX) ­> S' or ERROR - -在上面提到的银行系统中,状态转换函数如下: - - APPLY({ Alice: $50, Bob: $50 },"send $20 from Alice to Bob") = { Alice: $30,Bob: $70 } - -但是: - - APPLY({ Alice: $50, Bob: $50 },"send $70 from Alice to Bob") = ERROR - -比特币系统的“状态”是所有已经被挖出的、没有花费的比特币(技术上称为“未花费的交易输出,unspent transaction outputs 或UTXO”)的集合。每个UTXO都有一个面值和所有者(由20个字节的本质上是密码学公钥的地址所定义[1])。一笔交易包括一个或多个输入和一个或多个输出。每个输入包含一个对现有UTXO的引用和由与所有者地址相对应的私钥创建的密码学签名。每个输出包含一个新的加入到状态中的UTXO。 - -在比特币系统中,状态转换函数`APPLY(S,TX)->S’`大体上可以如下定义: - -1. 交易的每个输入: - * 如果引用的UTXO不存在于现在的状态中(`S`),返回错误提示 - * 如果签名与UTXO所有者的签名不一致,返回错误提示 -2. 如果所有的UTXO输入面值总额小于所有的UTXO输出面值总额,返回错误提示 -3. 返回新状态`S’`,新状态`S`中移除了所有的输入UTXO,增加了所有的输出UTXO。 - -第一步的第一部分防止交易的发送者花费不存在的比特币,第二部分防止交易的发送者花费其他人的比特币。第二步确保价值守恒。比特币的支付协议如下。假设Alice想给Bob发送11.7BTC。事实上,Alice不可能正好有11.7BTC。假设,她能得到的最小数额比特币的方式是:6+4+2=12。所以,她可以创建一笔有3个输入,2个输出的交易。第一个输出的面值是11.7BTC,所有者是Bob(Bob的比特币地址),第二个输出的面值是0.3BTC,所有者是Alice自己,也就是找零。 - -### 挖矿 - -![](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/block.png) - -如果我们拥有可信任的中心化服务机构,状态转换系统可以很容易地实现,可以简单地将上述功能准确编码。然而,我们想把比特币系统建成为去中心化的货币系统,为了确保每个人都同意交易的顺序,我们需要将状态转换系统与一个共识系统结合起来。比特币的去中心化共识进程要求网络中的节点不断尝试将交易打包成“区块”。网络被设计为大约每十分钟产生一个区块,每个区块包含一个时间戳、一个随机数、一个对上一个区块的引用(即哈希)和上一区块生成以来发生的所有交易列表。这样随着时间流逝就创建出了一个持续增长的区块链,它不断地更新,从而能够代表比特币账本的最新状态。 - -依照这个范式,检查一个区块是否有效的算法如下: - -1. 检查区块引用的上一个区块是否存在且有效。 -2. 检查区块的时间戳是否晚于以前的区块的时间戳,而且早于未来2小时[2]。 -3. 检查区块的工作量证明是否有效。 -4. 将上一个区块的最终状态赋于`S[0]`。 -5. 假设TX是区块的交易列表,包含n笔交易。对于属于0……n-1的所有i,进行状态转换`S[i+1] = APPLY(S[i],TX[i])`。如果任何一笔交易i在状态转换中出错,退出程序,返回错误。 -6. 返回正确,状态`S[n]`是这一区块的最终状态。 - -本质上,区块中的每笔交易必须提供一个正确的状态转换,要注意的是,“状态”并不是编码到区块的。它纯粹只是被校验节点记住的抽象概念,对于任意区块都可以从创世状态开始,按顺序加上每一个区块的每一笔交易,(妥妥地)计算出当前的状态。另外,需要注意矿工将交易收录进区块的顺序。如果一个区块中有A、B两笔交易,B花费的是A创建的UTXO,如果A在B以前,这个区块是有效的,否则,这个区块是无效的。 - -区块验证算法的有趣部分是“工作量证明”概念:对每个区块进行SHA256哈希处理,将得到的哈希视为长度为256比特的数值,该数值必须小于不断动态调整的目标数值,本书写作时目标数值大约是2^190。工作量证明的目的是使区块的创建变得困难,从而阻止女巫攻击者恶意重新生成区块链。因为SHA256是完全不可预测的伪随机函数,创建有效区块的唯一方法就是简单地不断试错,不断地增加随机数的数值,查看新的哈希数值是否小于目标数值。如果当前的目标数值是2^192,就意味着平均需要尝试2^64次才能生成有效的区块。一般而言,比特币网络每隔2016个区块重新设定目标数值,保证平均每十分钟生成一个区块。为了对矿工的计算工作进行奖励,每一个成功生成区块的矿工有权在区块中包含一笔凭空发给他们自己25BTC的交易。另外,如果交易的输入大于输出,差额部分就作为“交易费用”付给矿工。顺便提一下,对矿工的奖励是比特币发行的唯一机制,创世状态中并没有比特币。 - -为了更好地理解挖矿的目的,让我们分析比特币网络出现恶意攻击者时会发生什么。因为比特币的密码学基础是非常安全的,所以攻击者会选择攻击没有被密码学直接保护的部分:交易顺序。攻击者的策略非常简单: - -1. 向卖家发送100BTC购买商品(尤其是无需邮寄的电子商品)。 -2. 等待直至商品发出。 -3. 创建另一笔交易,将相同的100BTC发送给自己的账户。 -4. 使比特币网络相信发送给自己账户的交易是最先发出的。 - -一旦步骤(1)发生,几分钟后矿工将把这笔交易打包到区块,假设是第270000个区块。大约一个小时以后,在此区块后面将会有五个区块,每个区块间接地指向这笔交易,从而确认这笔交易。这时卖家收到货款,并向买家发货。因为我们假设这是数字商品,攻击者可以即时收到货。现在,攻击者创建另一笔交易,将相同的100BTC发送到自己的账户。如果攻击者只是向全网广播这一消息,这一笔交易不会被处理。矿工会运行状态转换函数`APPLY(S,TX)`,发现这笔交易将花费已经不在状态中的UTXO。所以,攻击者会对区块链进行分叉,将第269999个区块作为父区块重新生成第270000个区块,在此区块中用新的交易取代旧的交易。因为区块数据是不同的,这要求重新进行工作量证明。另外,因为攻击者生成的新的第270000个区块有不同的哈希,所以原来的第270001到第270005的区块不指向它,因此原有的区块链和攻击者的新区块是完全分离的。在发生区块链分叉时,区块链长的分支被认为是诚实的区块链,合法的的矿工将会沿着原有的第270005区块后挖矿,只有攻击者一人在新的第270000区块后挖矿。攻击者为了使得他的区块链最长,他需要拥有比除了他以外的全网更多的算力来追赶(即51%攻击)。 - -### 默克尔树 - -![比特币中的简化支付确认](https://raw.githubusercontent.com/ethereum/www/master-postsale/src/extras/gh_wiki/spv_bitcoin.png) - -左:仅提供默克尔树(Merkle tree)上的少量节点已经足够给出分支的合法证明。 -右:任何对于默克尔树的任何部分进行改变的尝试都会最终导致链上某处的不一致。 - -比特币系统的一个重要的可扩展特性是:它的区块存储在多层次的数据结构中。一个区块的哈希实际上只是区块头的哈希,区块头是包含时间戳、随机数、上个区块哈希和存储了所有的区块交易的默克尔树的根哈希的长度大约为200字节的一段数据。 - -默克尔树是一种二叉树,由一组叶节点、一组中间节点和一个根节点构成。最下面的大量的叶节点包含基础数据,每个中间节点是它的两个子节点的哈希,根节点也是由它的两个子节点的哈希,代表了默克尔树的顶部。默克尔树的目的是允许区块的数据可以零散地传送:节点可以从一个源下载区块头,从另外的源下载与其有关的树的其它部分,而依然能够确认所有的数据都是正确的。之所以如此是因为哈希向上的扩散:如果一个恶意用户尝试在树的下部加入一个伪造的交易,所引起的改动将导致树的上层节点的改动,以及更上层节点的改动,最终导致根节点的改动以及区块哈希的改动,这样协议就会将其记录为一个完全不同的区块(几乎可以肯定是带着不正确的工作量证明的)。 - -默克尔树协议对比特币的长期持续性可以说是至关重要的。在2014年4月,比特币网络中的一个全节点-存储和处理所有区块的全部数据的节点-需要占用15GB的内存空间,而且还以每个月超过1GB的速度增长。目前,这一存储空间对台式计算机来说尚可接受,但是手机已经负载不了如此巨大的数据了。未来只有商业机构和爱好者才会充当完整节点。简化支付确认(SPV)协议允许另一种节点存在,这样的节点被成为“轻节点”,它下载区块头,使用区块头确认工作量证明,然后只下载与其交易相关的默克尔树“分支”。这使得轻节点只要下载整个区块链的一小部分就可以安全地确定任何一笔比特币交易的状态和账户的当前余额。 - -### 其它的区块链应用 - -将区块链的思想应用到其它领域的想法早就出现了。在2005年,尼克萨博提出了“用所有权为财产冠名”的概念,文中描述了复制数据库技术的发展如何使基于区块链的系统可以应用于登记土地所有权,创建包括例如房产权、违法侵占和乔治亚州土地税等概念的详细框架。然而,不幸的是在那时还没有实用的复制数据库系统,所以这个协议被没有被付诸实践。不过,自2009年比特币系统的去中心化共识开发成功以来,许多区块链的其它应用开始快速出现。 - -* **域名币(namecoin)**- 创建于2010年,被称为去中心化的名称注册数据库。像Tor、Bitcoin和BitMessage这样的去中心化协议,需要一些确认账户的方法,这样其他人才能够与用户进行交互。但是,在所有的现存的解决方案中仅有的可用的身份标识是象`1LW79wp5ZBqaHW1jL5TciBCrhQYtHagUWy`这样的伪随机哈希。理想的情况下,人们希望拥有一个带有象“george”这样的名称的账户。然而,问题是如果有人可以创建“george”账户,那么其他人同样也可以创建“george”账户来假扮。唯一的解决方法是先申请原则(first-to-file),只有第一个注册者可以成功注册,第二个不能再次注册同一个账户。这一问题就可以利用比特币的共识协议。域名币是利用区块链实现名称注册系统的最早的、最成功的系统。 -* **彩色币(Colored coins)**- 彩色币的目的是为人们在比特币区块链上创建自己的数字货币,或者,在更重要的一般意义上的货币 – 数字令牌提供服务。依照彩色币协议,人们可以通过为某一特别的比特币UTXO指定颜色,发行新的货币。该协议递归地将其它UTXO定义为与交易输入UTXO相同的颜色。这就允许用户保持只包含某一特定颜色的UTXO,发送这些UTXO就像发送普通的比特币一样,通过回溯全部的区块链判断收到的UTXO颜色。 -* **元币(Metacoins)**- 元币的理念是在比特币区块链上创建新的协议,利用比特币的交易保存元币的交易,但是采用了不同的状态转换函数APPLY’。因为元币协议不能阻止比特币区块链上的无效的元币交易,所以增加一个规则如果APPLY'(S,TX)返回错误,这一协议将默认APPLY'(S,TX) = S。这为创建任意的、先进的不能在比特币系统中实现的密码学货币协议提供了一个简单的解决方法,而且开发成本非常低,因为挖矿和网络的问题已经由比特币协议处理好了。 - -因此,一般而言,建立共识协议有两种方法:建立一个独立的网络和在比特币网络上建立协议。虽然像域名币这样的应用使用第一种方法已经获得了成功,但是该方法的实施非常困难,因为每一个应用需要创建独立的区块链和建立、测试所有状态转换和网络代码。另外,我们预测去中心化共识技术的应用将会服从幂律分布,大多数的应用太小不足以保证自由区块链的安全,我们还注意到大量的去中心化应用,尤其是去中心化自治组织,需要进行应用之间的交互。 - -另一方面,基于比特币的方法存在缺点,它没有继承比特币可以进行简化确认支付(SPV) 的特性。比特币可以实现简化确认支付,因为比特币可以将区块链深度作为有效性确认代理。在某一点上,一旦一笔交易的祖先们距离现在足够远时,就可以认为它们是合法状态的一部分。与之相反,基于比特币区块链的元币协议不能强迫区块链不包括不符合元币协议的交易。因此,安全的元币协议的简化支付确认需要后向扫描所有的区块,直到区块链的初始点,以确认某一交易是否有效。目前,所有基于比特币的元币协议的“轻”实施都依赖可信任的服务器提供数据,这对主要目的之一是消除信任需要的密码学货币而言,只是一个相当次优的结果。 - -### 脚本 - -即使不对比特币协议进行扩展,它也能在一定程度上实现”智能合约”。比特币的UTXO可以被不只被一个公钥拥有,也可以被用基于堆栈的编程语言所编写的更加复杂的脚本所拥有。在这一模式下,花费这样的UTXO,必须提供满足脚本的数据。事实上,基本的公钥所有权机制也是通过脚本实现的:脚本将椭圆曲线签名作为输入,验证交易和拥有这一UTXO的地址,如果验证成功,返回1,否则返回0。更加复杂的脚本用于其它不同的应用情况。例如,人们可以创建要求集齐三把私钥中的两把才能进行交易确认的脚本(多重签名),对公司账户、储蓄账户和某些商业代理来说,这种脚本是非常有用的。脚本也能用来对解决计算问题的用户发送奖励。人们甚至可以创建这样的脚本“如果你能够提供你已经发送一定数额的的狗币给我的简化确认支付证明,这一比特币UTXO就是你的了”,本质上,比特币系统允许不同的密码学货币进行去中心化的兑换。 - -然而,比特币系统的脚本语言存在一些严重的限制: - -* **缺少图灵完备性** – 这就是说,尽管比特币脚本语言可以支持多种计算,但是它不能支持所有的计算。最主要的缺失是循环语句。不支持循环语句的目的是避免交易确认时出现无限循环。理论上,对于脚本程序员来说,这是可以克服的障碍,因为任何循环都可以用多次重复if 语句的方式来模拟,但是这样做会导致脚本空间利用上的低效率,例如,实施一个替代的椭圆曲线签名算法可能将需要256次重复的乘法,而每次都需要单独编码。 -* **价值盲(Value-blindness)**。UTXO脚本不能为账户的取款额度提供精细的的控制。例如,预言机合约(oracle contract)的一个强大应用是对冲合约,A和B各自向对冲合约中发送价值1000美元的比特币,30天以后,脚本向A发送价值1000美元的比特币,向B发送剩余的比特币。虽然实现对冲合约需要一个预言机(oracle)决定一比特币值多少美元,但是与现在完全中心化的解决方案相比,这一机制已经在减少信任和基础设施方面有了巨大的进步。然而,因为UTXO是不可分割的,为实现此合约,唯一的方法是非常低效地采用许多有不同面值的UTXO(例如对应于最大为30的每个k,有一个2^k的UTXO)并使预言机挑出正确的UTXO发送给A和B。 -* **缺少状态** – UTXO只能是已花费或者未花费状态,这就没有给需要任何其它内部状态的多阶段合约或者脚本留出生存空间。这使得实现多阶段期权合约、去中心化的交换要约或者两阶段加密承诺协议(对确保计算奖励非常必要)非常困难。这也意味着UTXO只能用于建立简单的、一次性的合约,而不是例如去中心化组织这样的有着更加复杂的状态的合约,使得元协议难以实现。二元状态与价值盲结合在一起意味着另一个重要的应用-取款限额-是不可能实现的。 -* **区块链盲(Blockchain-blindness)**- UTXO看不到区块链的数据,例如随机数和上一个区块的哈希。这一缺陷剥夺了脚本语言所拥有的基于随机性的潜在价值,严重地限制了博彩等其它领域应用。 - -我们已经考察了在密码学货币上建立高级应用的三种方法:建立一个新的区块链,在比特币区块链上使用脚本,在比特币区块链上建立元币协议。建立新区块链的方法可以自由地实现任意的特性,成本是开发时间和培育努力。使用脚本的方法非常容易实现和标准化,但是它的能力有限。元币协议尽管非常容易实现,但是存在扩展性差的缺陷。在以太坊系统中,我们的目的是建立一个能够同时具有这三种模式的所有优势的通用框架。 - -## 以太坊 - -以太坊的目的是基于脚本、竞争币和链上元协议(on-chain meta-protocol)概念进行整合和提高,使得开发者能够创建任意的基于共识的、可扩展的、标准化的、特性完备的、易于开发的和协同的应用。以太坊通过建立终极的抽象的基础层-内置有图灵完备编程语言的区块链-使得任何人都能够创建合约和去中心化应用并在其中设立他们自由定义的所有权规则、交易方式和状态转换函数。域名币的主体框架只需要两行代码就可以实现,诸如货币和信誉系统等其它协议只需要不到二十行代码就可以实现。智能合约-包含价值而且只有满足某些条件才能打开的加密箱子-也能在我们的平台上创建,并且因为图灵完备性、价值知晓(value-awareness)、区块链知晓(blockchain-awareness)和多状态所增加的力量而比比特币脚本所能提供的智能合约强大得多。 - -### 以太坊账户 - -在以太坊系统中,状态是由被称为“账户”(每个账户由一个20字节的地址)的对象和在两个账户之间转移价值和信息的状态转换构成的。以太坊的账户包含四个部分: - -* 随机数,用于确定每笔交易只能被处理一次的计数器 -* 账户目前的以太币余额 -* 账户的合约代码,如果有的话 -* 账户的存储(默认为空) - -以太币(Ether)是以太坊内部的主要加密燃料,用于支付交易费用。一般而言,以太坊有两种类型的账户:外部所有的账户(由私钥控制的)和合约账户(由合约代码控制)。外部所有的账户没有代码,人们可以通过创建和签名一笔交易从一个外部账户发送消息。每当合约账户收到一条消息,合约内部的代码就会被激活,允许它对内部存储进行读取和写入,和发送其它消息或者创建合约。 - -### 消息和交易 - -以太坊的消息在某种程度上类似于比特币的交易,但是两者之间存在三点重要的不同。第一,以太坊的消息可以由外部实体或者合约创建,然而比特币的交易只能从外部创建。第二,以太坊消息可以选择包含数据。第三,如果以太坊消息的接受者是合约账户,可以选择进行回应,这意味着以太坊消息也包含函数概念。 - -以太坊中“交易”是指存储从外部账户发出的消息的签名数据包。交易包含消息的接收者、用于确认发送者的签名、以太币账户余额、要发送的数据和两个被称为STARTGAS和GASPRICE的数值。为了防止代码的指数型爆炸和无限循环,每笔交易需要对执行代码所引发的计算步骤-包括初始消息和所有执行中引发的消息-做出限制。STARTGAS就是限制,GASPRICE是每一计算步骤需要支付矿工的费用。如果执行交易的过程中,“用完了瓦斯”,所有的状态改变恢复原状态,但是已经支付的交易费用不可收回了。如果执行交易中止时还剩余瓦斯,那么这些瓦斯将退还给发送者。创建合约有单独的交易类型和相应的消息类型;合约的地址是基于账号随机数和交易数据的哈希计算出来的。 - -消息机制的一个重要后果是以太坊的“头等公民”财产-合约与外部账户拥有同样权利,包括发送消息和创建其它合约的权利。这使得合约可以同时充当多个不同的角色,例如,用户可以使去中心化组织(一个合约)的一个成员成为一个中介账户(另一个合约),为一个偏执的使用定制的基于量子证明的兰波特签名(第三个合约)的个人和一个自身使用由五个私钥保证安全的账户(第四个合约)的共同签名实体提供居间服务。以太坊平台的强大之处在于去中心化的组织和代理合约不需要关心合约的每一参与方是什么类型的账户。 - -### 以太坊状态转换函数 - -![以太坊交易.png](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/ethertransition.png) - -以太坊的状态转换函数:`APPLY(S,TX) -> S'`,可以定义如下: - -1. 检查交易的格式是否正确(即有正确数值)、签名是否有效和随机数是否与发送者账户的随机数匹配。如否,返回错误。 -2. 计算交易费用:`fee=STARTGAS * GASPRICE`,并从签名中确定发送者的地址。从发送者的账户中减去交易费用和增加发送者的随机数。如果账户余额不足,返回错误。 -3. 设定初值`GAS = STARTGAS`,并根据交易中的字节数减去一定量的瓦斯值。 -4. 从发送者的账户转移价值到接收者账户。如果接收账户还不存在,创建此账户。如果接收账户是一个合约,运行合约的代码,直到代码运行结束或者瓦斯用完。 -5. 如果因为发送者账户没有足够的钱或者代码执行耗尽瓦斯导致价值转移失败,恢复原来的状态,但是还需要支付交易费用,交易费用加至矿工账户。 -6. 否则,将所有剩余的瓦斯归还给发送者,消耗掉的瓦斯作为交易费用发送给矿工。 -例如,假设合约的代码如下: - -```python -if !self.storage[calldataload(0)]: - self.storage[calldataload(0)] = calldataload(32) -``` - -需要注意的是,在现实中合约代码是用底层以太坊虚拟机(EVM)代码写成的。上面的合约是用我们的高级语言Serpent语言写成的,它可以被编译成EVM代码。假设合约存储器开始时是空的,一个值为10以太,瓦斯为2000,瓦斯价格为0.001以太并且64字节数据,第一个三十二字节的块代表号码2和第二个代表词`CHARLIE`。的交易发送后,状态转换函数的处理过程如下: - -1. 检查交易是否有效、格式是否正确。 -2. 检查交易发送者至少有2000*0.001=2个以太币。如果有,从发送者账户中减去2个以太币。 -3. 初始设定gas=2000,假设交易长为170字节,每字节的费用是5,减去850,所以还剩1150。 -4. 从发送者账户减去10个以太币,为合约账户增加10个以太币。 -5. 运行代码。在这个合约中,运行代码很简单:它检查合约存储器索引为2处是否已使用,注意到它未被使用,然后将其值置为CHARLIE。假设这消耗了187单位的瓦斯,于是剩余的瓦斯为1150 - 187 = 963。 -6. 向发送者的账户增加963*0.001=0.963个以太币,返回最终状态。 -如果没有合约接收交易,那么所有的交易费用就等于GASPRICE乘以交易的字节长度,交易的数据就与交易费用无关了。另外,需要注意的是,合约发起的消息可以对它们产生的计算分配瓦斯限额,如果子计算的瓦斯用完了,它只恢复到消息发出时的状态。因此,就像交易一样,合约也可以通过对它产生的子计算设置严格的限制,保护它们的计算资源。 - -### 代码执行 - -以太坊合约的代码是使用低级的基于堆栈的字节码的语言写成的,被称为“以太坊虚拟机代码”或者“EVM代码”。代码由一系列字节构成,每一个字节代表一种操作。一般而言,代码执行是无限循环,程序计数器每增加一(初始值为零)就执行一次操作,直到代码执行完毕或者遇到错误,`STOP`或者`RETURN`指令。操作可以访问三种存储数据的空间: - -* **堆栈**,一种后进先出的数据存储,32字节的数值可以入栈,出栈。 -* **内存**,可无限扩展的字节队列。 -* **合约的长期存储**,一个秘钥/数值的存储,其中秘钥和数值都是32字节大小,与计算结束即重置的堆栈和内存不同,存储内容将长期保持。 - -代码可以象访问区块头数据一样访问数值,发送者和接受到的消息中的数据,代码还可以返回数据的字节队列作为输出。 - -EVM代码的正式执行模型令人惊讶地简单。当以太坊虚拟机运行时,它的完整的计算状态可以由元组`(block_state, transaction, message, code, memory, stack, pc, gas)`来定义,这里`block_state`是包含所有账户余额和存储的全局状态。每轮执行时,通过调出代码的第`pc`(程序计数器)个字节,当前指令被找到,每个指令都有定义自己如何影响元组。例如,`ADD`将两个元素出栈并将它们的和入栈,将`gas`(瓦斯)减一并将`pc`加一,`SSTORE`将顶部的两个元素出栈并将第二个元素插入到由第一个元素定义的合约存储位置,同样减少最多200的gas值并将`pc`加一,虽然有许多方法通过即时编译去优化以太坊,但以太坊的基础性的实施可以用几百行代码实现。 - -### 区块链和挖矿 - -虽然有一些不同,但以太坊的区块链在很多方面类似于比特币区块链。它们的区块链架构的不同在于,以太坊区块不仅包含交易记录和最近的状态,还包含区块序号和难度值。以太坊中的区块确认算法如下: - -1. 检查区块引用的上一个区块是否存在和有效。 -2. 检查区块的时间戳是否比引用的上一个区块大,而且小于15分钟。 -3. 检查区块序号、难度值、 交易根,叔根和瓦斯限额(许多以太坊特有的底层概念)是否有效。 -4. 检查区块的工作量证明是否有效。 -5. 将`S[0]`赋值为上一个区块的`STATE_ROOT`。 -6. 将`TX`赋值为区块的交易列表,一共有`n`笔交易。对于属于`0……n-1`的`i`,进行状态转换`S[i+1] = APPLY(S[i],TX[i])`。如果任何一个转换发生错误,或者程序执行到此处所花费的瓦斯(gas)超过了`GASLIMIT`,返回错误。 -7. 用`S[n]`给`S_FINAL`赋值, 向矿工支付区块奖励。 -8. 检查`S-FINAL`是否与`STATE_ROOT`相同。如果相同,区块是有效的。否则,区块是无效的。 - -这一确认方法乍看起来似乎效率很低,因为它需要存储每个区块的所有状态,但是事实上以太坊的确认效率可以与比特币相提并论。原因是状态存储在树结构中(tree structure),每增加一个区块只需要改变树结构的一小部分。因此,一般而言,两个相邻的区块的树结构的大部分应该是相同的,因此存储一次数据,可以利用指针(即子树哈希)引用两次。一种被称为“帕特里夏树”(“Patricia Tree”)的树结构可以实现这一点,其中包括了对默克尔树概念的修改,不仅允许改变节点,而且还可以插入和删除节点。另外,因为所有的状态信息是最后一个区块的一部分,所以没有必要存储全部的区块历史-这一方法如果能够可以应用到比特币系统中,经计算可以对存储空间有10-20倍的节省。 - -## 应用 - -一般来讲,以太坊之上有三种应用。第一类是金融应用,为用户提供更强大的用他们的钱管理和参与合约的方法。包括子货币,金融衍生品,对冲合约,储蓄钱包,遗嘱,甚至一些种类的全面的雇佣合约。第二类是半金融应用,这里有钱的存在但也有很重的非金钱的方面,一个完美的例子是为解决计算问题而设的自我强制悬赏。最后,还有在线投票和去中心化治理这样的完全的非金融应用。 - -### 令牌系统 - -链上令牌系统有很多应用,从代表如美元或黄金等资产的子货币到公司股票,单独的令牌代表智能资产,安全的不可伪造的优惠券,甚至与传统价值完全没有联系的用来进行积分奖励的令牌系统。在以太坊中实施令牌系统容易得让人吃惊。关键的一点是理解,所有的货币或者令牌系统,从根本上来说是一个带有如下操作的数据库:从A中减去X单位并把X单位加到B上,前提条件是(1)A在交易之前有至少X单位以及(2)交易被A批准。实施一个令牌系统就是把这样一个逻辑实施到一个合约中去。 - -用Serpent语言实施一个令牌系统的基本代码如下: - -```python -def send(to, value): - if self.storage[from] >= value: - self.storage[from] = self.storage[from] value - self.storage[to] = self.storage[to] + value -``` - -这从本质上来说是本文将要进一步描述的“银行系统”状态转变功能的一个最小化实施。需要增加一些额外的代码以提供在初始和其它一些边缘情况下分发货币的功能,理想情况下会增加一个函数让其它合约来查询一个地址的余额。就足够了。理论上,基于以太坊的充当子货币的令牌系统可能包括一个基于比特币的链上元币所缺乏的重要功能:直接用这种货币支付交易费的能力。实现这种能力的方法是在合约里维护一个以太币账户以用来为发送者支付交易费,通过收集被用来充当交易费用的内部货币并把它们在一个不断运行的拍卖中拍卖掉,合约不断为该以太币账户注资。这样用户需要用以太币“激活”他们的账户,但一旦账户中有以太币它将会被重复使用因为每次合约都会为其充值。 - -### 金融衍生品和价值稳定的货币 - -金融衍生品是“智能合约”的最普遍的应用,也是最易于用代码实现的之一。实现金融合约的主要挑战是它们中的大部分需要参照一个外部的价格发布器;例如,一个需求非常大的应用是一个用来对冲以太币(或其它密码学货币)相对美元价格波动的智能合约,但该合约需要知道以太币相对美元的价格。最简单地方法是通过由某特定机构(例如纳斯达克)维护的“数据提供“合约进行,该合约的设计使得该机构能够根据需要更新合约,并提供一个接口使得其它合约能够通过发送一个消息给该合约以获取包含价格信息的回复。 - -当这些关键要素都齐备,对冲合约看起来会是下面的样子: - -1. 等待A输入1000以太币。. -2. 等待B 输入1000以太币。 -3. 通过查询数据提供合约,将1000以太币的美元价值,例如,x美元,记录至存储器。 -4. 30天后,允许A或B“重新激活“合约以发送价值x美元的以太币(重新查询数据提供合约以获取新价格并计算)给A并将剩余的以太币发送给B。 -这样的合约在密码学商务中有非同寻常的潜力。密码学货币经常被诟病的一个问题就是其价格的波动性;虽然大量的用户和商家可能需要密码学资产所带来的安全和便利,可他们不太会乐意面对一天中资产跌去23%价值的情形。直到现在,最为常见的推荐方案是发行者背书资产;思想是发行者创建一种子货币,对此种子货币他们有权发行和赎回,给予(线下)提供给他们一个单位特定相关资产(例如黄金,美元)的人一个单位子货币。发行者承诺当任何人送还一个单位密码学资产时。发还一个单位的相关资产。这种机制能够使任何非密码学资产被“升级“为密码学资产,如果发行者值得信任的话。 -然而实践中发行者并非总是值得信任的,并且一些情况下银行体系太脆弱,或者不够诚实守信从而使这样的服务无法存在。金融衍生品提供了一种替代方案。这里将不再有提供储备以支撑一种资产的单独的发行者,取而代之的是一个由赌一种密码学资产的价格会上升的投机者构成的去中心化市场。与发行者不同,投机者一方没有讨价还价的权利,因为对冲合约把他们的储备冻结在了契约中。注意这种方法并非是完全去中心化的,因为依然需要一个可信任的提供价格信息的数据源,尽管依然有争议这依然是在降低基础设施需求(与发行者不同,一个价格发布器不需要牌照并且似乎可归为自由言论一类)和降低潜在欺诈风险方面的一个巨大的进步。 - -### 身份和信誉系统 - -最早的替代币,域名币,尝试使用一个类比特币块链来提供一个名称注册系统,在那里用户可以将他们的名称和其它数据一起在一个公共数据库注册。最常用的应用案例把象“bitcoin.org“(或者再域名币中,”bitcoin.bit“)一样的域名与一个IP地址对应的域名系统。其它的应用案例包括电子邮件验证系统和潜在的更先进的信誉系统。这里是以太坊中提供与域名币类似的的名称注册系统的基础合约: - -```python -def register(name, value): - if !self.storage[name]: - self.storage[name] = value -``` - -合约非常简单;就是一个以太坊网络中的可以被添加但不能被修改或移除的数据库。任何人都可以把一个名称注册为一个值并永远不变。一个更复杂的名称注册合约将包含允许其他合约查询的“功能条款“,以及一个让一个名称的”拥有者“(即第一个注册者)修改数据或者转让所有权的机制。甚至可以在其上添加信誉和信任网络功能。 - -### 去中心化存储 - -在过去的几年里出现了一些大众化的在线文件存储初创公司,最突出的是Dropbox,它寻求允许用户上传他们的硬盘备份,提供备份存储服务并允许用户访问从而按月向用户收取费用。然而,在这一点上这个文件存储市场有时相对低效;对现存服务的粗略观察表明,特别地在“神秘谷“20-200GB这一既没有免费空间也没有企业级用户折扣的水平上,主流文件存储成本每月的价格意味着支付在一个月里支付整个硬盘的成本。以太坊合约允许去中心化存储生态的开发,这样用户通过将他们自己的硬盘或未用的网络空间租出去以获得少量收益,从而降低了文件存储的成本。 - -这样的设施的基础性构件就是我们所谓的“去中心化Dropbox合约“。这个合约工作原理如下。首先,某人将需要上传的数据分成块,对每一块数据加密以保护隐私,并且以此构建一个默克尔树。然后创建一个含以下规则的合约,每N个块,合约将从默克尔树中抽取一个随机索引(使用能够被合约代码访问的上一个块的哈希来提供随机性), 然后给第一个实体X以太以支撑一个带有类似简化验证支付(SPV)的在树中特定索引处的块的所有权证明。当一个用户想重新下载他的文件,他可以使用微支付通道协议(例如每32k字节支付1萨博)恢复文件;从费用上讲最高效的方法是支付者不到最后不发布交易,而是用一个略微更合算的带有同样随机数的交易在每32k字节之后来代替原交易。 - -这个协议的一个重要特征是,虽然看起来象是一个人信任许多不准备丢失文件的随机节点,但是他可以通过秘密分享把文件分成许多小块,然后通过监视合同得知每个小块都还被某个节点的保存着。如果一个合约依然在付款,那么就提供了某个人依然在保存文件的证据。 - -### 去中心化自治组织 - -通常意义上“去中心化自治组织(DAO, decentralized autonomous organization)”的概念指的是一个拥有一定数量成员或股东的虚拟实体,依靠比如67%多数来决定花钱以及修改代码。成员会集体决定组织如何分配资金。分配资金的方法可能是悬赏,工资或者更有吸引力的机制比如用内部货币奖励工作。这仅仅使用密码学块链技术就从根本上复制了传统公司或者非营利组织的法律意义以实现强制执行。至此许多围绕DAO的讨论都是围绕一个带有接受分红的股东和可交易的股份的“去中心化自治公司(DAC,decentralized autonomous corporation)”的“资本家”模式;作为替代者,一个被描述为“去中心化自治社区(decentralized autonomous community)”的实体将使所有成员都在决策上拥有同等的权利并且在增减成员时要求67%多数同意。每个人都只能拥有一个成员资格这一规则需要被群体强制实施。 - -下面是一个如何用代码实现DO的纲要。最简单地设计就是一段如果三分之二成员同意就可以自我修改的代码。虽然理论上代码是不可更改的,然而通过把代码主干放在一个单独的合约内并且把合约调用的地址指向一个可更改的存储依然可以容易地绕开障碍而使代码变得可修改,在一个这样的DAO合约的简单实现中有三种交易类型,由交易提供的数据区分: - -* `[0,i,K,V]` 注册索引为i 的对存储地址索引为K 至 v 的内容的更改建议。 -* `[0,i]` 注册对建议i 的投票。 -* `[2,i]` 如有足够投票则确认建议i。 - -然后合约对每一项都有具体的条款。它将维护一个所有开放存储的更改记录以及一个谁投票表决的表。还有一个所有成员的表。当任何存储内容的更改获得了三分之二多数同意,一个最终的交易将执行这项更改。一个更加复杂的框架会增加内置的选举功能以实现如发送交易,增减成员,甚至提供委任制民主一类的投票代表(即任何人都可以委托另外一个人来代表自己投票,而且这种委托关系是可以传递的,所以如果A委托了B然后B委托了C那么C将决定A的投票)。这种设计将使DAO作为一个去中心化社区有机地成长, 使人们最终能够把挑选合适人选的任务交给专家,与当前系统不同,随着社区成员不断改变他们的站队假以时日专家会容易地出现和消失。 -一个替代的模式是去中心化公司,那里任何账户可以拥有0到更多的股份,决策需要三分之二多数的股份同意。一个完整的框架将包括资产管理功能-可以提交买卖股份的订单以及接受这种订单的功能(前提是合约里有订单匹配机制)。代表依然以委任制民主的方式存在,产生了“董事会”的概念。 - -更先进的组织治理机制可能会在将来实现;现在一个去中心化组织(DO)可以从去中心化自治组织(DAO)开始描述。DO和DAO的区别是模糊的,一个大致的分割线是治理是否可以通过一个类似政治的过程或者一个“自动”过程实现,一个不错的直觉测试是“无通用语言”标准:如果两个成员不说同样的语言组织还能正常运行吗?显然,一个简单的传统的持股式公司会失败,而象比特币协议这样的却很可能成功,罗宾·汉森的“futarchy”,一个通过预测市场实现组织化治理的机制是一个真正的说明“自治”式治理可能是什么样子的好例子。注意一个人无需假设所有DAO比所有DO优越;自治只是一个在一些特定场景下有很大优势的,但在其它地方未必可行的范式,许多半DAO可能存在。 - -### 进一步的应用 - -1. **储蓄钱包**。 假设Alice想确保她的资金安全,但她担心丢失或者被黑客盗走私钥。她把以太币放到和Bob签订的一个合约里,如下所示,这合同是一个银行: - * Alice单独每天最多可提取1%的资金。 - * Bob单独每天最多可提取1%的资金,但Alice可以用她的私钥创建一个交易取消Bob的提现权限。 - * Alice 和 Bob 一起可以任意提取资金。 -一般来讲,每天1%对Alice足够了,如果Alice想提现更多她可以联系Bob寻求帮助。如果Alice的私钥被盗,她可以立即找到Bob把她的资金转移到一个新合同里。如果她弄丢了她的私钥,Bob可以慢慢地把钱提出。如果Bob表现出了恶意,她可以关掉他的提现权限。 - -2. **作物保险**。一个人可以很容易地以天气情况而不是任何价格指数作为数据输入来创建一个金融衍生品合约。如果一个爱荷华的农民购买了一个基于爱荷华的降雨情况进行反向赔付的金融衍生品,那么如果遇到干旱,该农民将自动地收到赔付资金而如果有足量的降雨他会很开心因为他的作物收成会很好。 - -3. **一个去中心化的数据发布器**。 对于基于差异的金融合约,事实上通过过“谢林点”协议将数据发布器去中心化是可能的。谢林点的工作原理如下:N方为某个指定的数据提供输入值到系统(例如ETH/USD价格),所有的值被排序,每个提供25%到75%之间的值的节点都会获得奖励,每个人都有激励去提供他人将提供的答案,大量玩家可以真正同意的答案明显默认就是正确答案,这构造了一个可以在理论上提供很多数值,包括ETH/USD价格,柏林的温度甚至某个特别困难的计算的结果的去中心化协议。 - -5.**云计算**。EVM技术还可被用来创建一个可验证的计算环境,允许用户邀请他人进行计算然后选择性地要求提供在一定的随机选择的检查点上计算被正确完成的证据。这使得创建一个任何用户都可以用他们的台式机,笔记本电脑或者专用服务器参与的云计算市场成为可能,现场检查和安全保证金可以被用来确保系统是值得信任的(即没有节点可以因欺骗获利)。虽然这样一个系统可能并不适用所有任务;例如,需要高级进程间通信的任务就不易在一个大的节点云上完成。然而一些其它的任务就很容易实现并行;SETI@home, folding@home和基因算法这样的项目就很容易在这样的平台上进行。 - -6.**点对点赌博**。任意数量的点对点赌博协议都可以搬到以太坊的区块链上,例如Frank Stajano和Richard Clayton的Cyberdice。 最简单的赌博协议事实上是这样一个简单的合约,它用来赌下一个区块的哈稀值与猜测值之间的差额, 据此可以创建更复杂的赌博协议,以实现近乎零费用和无欺骗的赌博服务。 - -7.**预测市场**。 不管是有神谕还是有谢林币,预测市场都会很容易实现,带有谢林币的预测市场可能会被证明是第一个主流的作为去中心化组织管理协议的“futarchy”应用。 - -8.链上去中心化市场,以身份和信誉系统为基础。 - -## 杂项和关注 - -### 改进版幽灵协议的实施 - - “幽灵“协议("Greedy Heaviest Observed Subtree" (GHOST) protocol)是由Yonatan Sompolinsky 和 Aviv Zohar在2013年12月引入的创新。幽灵协议提出的动机是当前快速确认的块链因为区块的高作废率而受到低安全性困扰;因为区块需要花一定时间(设为t)扩散至全网,如果矿工A挖出了一个区块然后矿工B碰巧在A的区块扩散至B之前挖出了另外一个区块,矿工B的区块就会作废并且没有对网络安全作出贡献。此外,这里还有中心化问题:如果A是一个拥有全网30%算力的矿池而B拥有10%的算力,A将面临70%的时间都在产生作废区块的风险而B在90%的时间里都在产生作废区块。因此,如果作废率高,A将简单地因为更高的算力份额而更有效率,综合这两个因素,区块产生速度快的块链很可能导致一个矿池拥有实际上能够控制挖矿过程的算力份额。 - -正如Sompolinsky 和 Zohar所描述的,通过在计算哪条链“最长”的时候把废区块也包含进来,幽灵协议解决了降低网络安全性的第一个问题;这就是说,不仅一个区块的父区块和更早的祖先块,祖先块的作废的后代区块(以太坊术语中称之为“叔区块”)也被加进来以计算哪一个区块拥有支持其的最大工作量证明。我们超越了Sompolinsky 和 Zohar所描述的协议以解决第二个问题 – 中心化倾向,以太坊付给以“叔区块”身份为新块确认作出贡献的废区块87.5%的奖励,把它们纳入计算的“侄子区块”将获得奖励的12.5%,不过,交易费用不奖励给叔区块。 -以太坊实施了一个只下探到第五层的简化版本的幽灵协议。其特点是,废区块只能以叔区块的身份被其父母的第二代至第五代后辈区块,而不是更远关系的后辈区块(例如父母区块的第六代后辈区块,或祖父区块的第三代后辈区块)纳入计算。这样做有几个原因。首先,无条件的幽灵协议将给计算给定区块的哪一个叔区块合法带来过多的复杂性。其次,带有以太坊所使用的补偿的无条件的幽灵协议剥夺了矿工在主链而不是一个公开攻击者的链上挖矿的激励。最后,计算表明带有激励的五层幽灵协议即使在出块时间为15s的情况下也实现了了95%以上的效率,而拥有25%算力的矿工从中心化得到的益处小于3%。 - -### 费用 - -因为每个发布的到区块链的交易都占用了下载和验证的成本,需要有一个包括交易费的规范机制来防范滥发交易。比特币使用的默认方法是纯自愿的交易费用,依靠矿工担当守门人并设定动态的最低费用。因为这种方法是“基于市场的”,使得矿工和交易发送者能够按供需来决定价格,所以这种方法在比特币社区被很顺利地接受了。然而,这个逻辑的问题在于,交易处理并非一个市场;虽然根据直觉把交易处理解释成矿工给发送者提供的服务是很有吸引力的,但事实上一个矿工收录的交易是需要网络中每个节点处理的,所以交易处理中最大部分的成本是由第三方而不是决定是否收录交易的矿工承担的。于是,非常有可能发生公地悲剧。 - -然而,当给出一个特殊的不够精确的简化假设时,这个基于市场的机制的漏洞很神奇地消除了自己的影响。论证如下。假设: - -1. 一个交易带来 k 步操作, 提供奖励 kR给任何收录该交易的矿工,这里 R 由交易发布者设定, k 和 R 对于矿工都是事先(大致上)可见的。 -2. 每个节点处理每步操作的成本都是 C (即所有节点的效率一致)。 -3. 有 N 个挖矿节点,每个算力一致(即全网算力的1/N)。 -4. 没有不挖矿的全节点。 - -当预期奖励大于成本时,矿工愿意挖矿。这样,因为矿工有1/N 的机会处理下一个区块,所以预期的收益是 kR/N , 矿工的处理成本简单为 kC. 这样当 kR/N > kC, 即 R > NC时。矿工愿意收录交易。注意 R 是由交易发送者提供的每步费用,是矿工从处理交易中获益的下限。 NC 是全网处理一个操作的成本。所以,矿工仅有动机去收录那些收益大于成本的交易。 -然而,这些假设与实际情况有几点重要的偏离: - -1. 因为额外的验证时间延迟了块的广播因而增加了块成为废块的机会,处理交易的矿工比其它的验证节点付出了更高的成本。 -2. 不挖矿的全节点是存在的。 -3. 实践中算力分布可能最后是极端不平均的。 -4. 以破坏网络为己任的投机者,政敌和疯子确实存在,并且他们能够聪明地设置合同使得他们的成本比其它验证节点低得多。 -上面第1点驱使矿工收录更少的交易,第2点增加了 NC; 因此这两点的影响至少部分互相抵消了. 第3点和第4点是主要问题;作为解决方案我们简单地建立了一个浮动的上限:没有区块能够包含比BLK_LIMIT_FACTOR 倍长期指数移动平均值更多的操作数。具体地: - -`blk.oplimit = floor((blk.parent.oplimit * (EMAFACTOR - 1) + floor(parent.opcount * BLK_LIMIT_FACTOR)) /EMA_FACTOR)` - -BLK_LIMIT_FACTOR 和 EMA_FACTOR 是暂且被设为 65536 和 1.5 的常数,但可能会在更深入的分析后调整。 -回复 - -### 计算和图灵完备 - -需要强调的是以太坊虚拟机是图灵完备的; 这意味着EVM代码可以实现任何可以想象的计算,包括无限循环。EVM代码有两种方式实现循环。首先, JUMP 指令可以让程序跳回至代码前面某处,还有允许如 `while x < 27: x = x * 2 ` 一样的条件语句的JUMPI 指令实现条件跳转。其次,合约可以调用其它合约,有通过递归实现循环的潜力。这很自然地导致了一个问题:恶意用户能够通过迫使矿工和全节点进入无限循环而不得不关机吗? 这问题出现是因为计算机科学中一个叫停机问题的问题:一般意义上没有办法知道,一个给定的程序是否能在有限的时间内结束运行。 - -正如在状态转换章节所述,我们的方案通过为每一个交易设定运行执行的最大计算步数来解决问题,如果超过则计算被恢复原状但依然要支付费用。消息以同样的方式工作。为显示这一方案背后的动机,请考虑下面的例子: - -* 一个攻击者创建了一个运行无限循环的合约,然后发送了一个激活循环的交易给矿工,矿工将处理交易,运行无限循环直到瓦斯耗尽。即使瓦斯耗尽交易半途停止,交易依然正确(回到原处)并且矿工依然从攻击者哪里挣到了每一步计算的费用。 -* 一个攻击者创建一个非常长的无限循环意图迫使矿工长时间内一直计算致使在计算结束前若干区块已经产生于是矿工无法收录交易以赚取费 用。然而,攻击者需要发布一个 STARTGAS 值以限制可执行步数,因而矿工将提前知道计算将耗费过多的步数。 -* 一个攻击者看到一个包含诸如 send(A,self.storage); self.storage = 0格式的合约然后发送带有只够执行第一步的费用的而不够执行第二步的交易(即提现但不减少账户余额)。合约作者无需担心防卫类似攻击,因为如果执行中途停止则所有变更都被回复。 -* 一个金融合约靠提取九个专用数据发布器的中值来工作以最小化风险,一个攻击者接管了其中一个数据提供器,然后把这个按DAO章节所述的可变地址调用机制设计成可更改的数据提供器转为运行一个无限循环,以求尝试逼迫任何从此金融合约索要资金的尝试都会因瓦斯耗尽而中止。然而,该金融合约可以在消息里设置瓦斯限制以防范此类问题。 -图灵完备的替代是图灵不完备,这里 JUMP 和 JUMPI 指令不存在并且在某个给定时间每个合约只允许有一个拷贝存在于调用堆栈内。在这样的系统里,上述的费用系统和围绕我们的方案的效率的不确定性可能都是不需要的,因为执行一个合约的成本将被它的大小决定。此外,图灵不完备甚至不是一个大的限制,在我们内部设想的所有合约例子中,至今只有一个需要循环,而且即使这循环也可以被26个单行代码段的重复所代替。考虑到图灵完备带来的严重的麻烦和有限的益处,为什么不简单地使用一种图灵不完备语言呢?事实上图灵不完备远非一个简洁的解决方案。为什么?请考虑下面的合约: - -```python -C0: call(C1); call(C1); -C1: call(C2); call(C2); -C2: call(C3); call(C3); -... -C49: call(C50); call(C50); -C50: (作一个图灵机的步计算和记录结果在合约的长期存储) -``` - -现在,发送一个这样的交易给A,这样,在51个交易中,我们有了一个需要花费2^50 步计算的合约,矿工可能尝试通过为每一个合约维护一个最高可执行步数并且对于递归调用其它合约的合约计算可能执行步数从而预先检测这样的逻辑炸弹,但是这会使矿工禁止创建其它合约的合约(因为上面26个合约的创建和执行可以很容易地放入一个单独合约内)。另外一个问题点是一个消息的地址字段是一个变量,所以通常来讲可能甚至无法预先知道一个合约将要调用的另外一个合约是哪一个。于是,最终我们有了一个惊人的结论:图灵完备的管理惊人地容易,而在缺乏同样的控制时图灵不完备的管理惊人地困难- 那为什么不让协议图灵完备呢? - -### 货币和发行 - -以太坊网络包含自身的内置货币以太币,以太币扮演双重角色,为各种数字资产交易提供主要的流动性,更重要的是提供了了支付交易费用的一种机制。为便利及避免将来的争议期间(参见当前的mBTC/uBTC/聪的争论),不同面值的名称将被提前设置: - -* 1: 伟 -* 10^12: 萨博 -* 10^15: 芬尼 -* 10^18: 以太 - -这应该被当作是“元”和“分”或者“比特币”和“聪”的概念的扩展版,在不远的将来,我们期望“以太”被用作普通交易,“芬尼”用来进行微交易,“萨博”和“伟”用来进行关于费用和协议实施的讨论。 - -发行模式如下: - -* 通过发售活动,以太币将以每BTC 1337-2000以太的价格发售,一个旨在为以太坊组织筹资并且为开发者支付报酬的机制已经在其它一些密码学货币平台上成功使用。早期购买者会享受较大的折扣,发售所得的BTC将完全用来支付开发者和研究者的工资和悬赏,以及投入密码学货币生态系统的项目。 -* 0.099x (x为发售总量)将被分配给BTC融资或其它的确定性融资成功之前参与开发的早期贡献者,另外一个0.099x将分配给长期研究项目。 -* 自上线时起每年都将有0.26x(x为发售总量)被矿工挖出。 - -### 发行分解 -永久线性增长模型降低了在比特币中出现的财富过于集中的风险,并且给予了活在当下和将来的人公平的机会去获取货币,同时保持了对获取和持有以太币的激励,因为长期来看“货币供应增长率”是趋于零的。我们还推断,随着时间流逝总会发生因为粗心和死亡等原因带来的币的遗失,假设币的遗失是每年货币供应量的一个固定比例,则最终总的流通中的货币供应量会稳定在一个等于年货币发行量除以遗失率的值上(例如,当遗失率为1%时,当供应量达到30x时,每年有0.3x被挖出同时有0.3x丢失,达到一个均衡)。 - -![](http://bitcoin8btc.qiniudn.com/wp-content/uploads/2014/10/table.png) -除了线性的发行方式外,和比特币一样以太币的的供应量增长率长期来看也趋于零。 - -![](http://bitcoin8btc.qiniudn.com/wp-content/uploads/2014/10/supply.png) - -### 挖矿的中心化 - -比特币挖矿算法基本上是让矿工千万次地轻微改动区块头,直到最终某个节点的改动版本的哈希小于目标值(目前是大约2190)。然而,这种挖矿算法容易被两种形式的中心化攻击。第一种,挖矿生态系统被专门设计的因而在比特币挖矿这一特殊任务上效率提高上千倍的ASICs(专用集成电路)和电脑芯片控制。这意味着比特币挖矿不再是高度去中心化的和追求平等主义的,而是需要巨额资本的有效参与。第二种,大部分比特币矿工事实上不再在本地完成区块验证;而是依赖中心化的矿池提供区块头。这个问题可以说很严重:在本文写作时,最大的两个矿池间接地控制了大约全网50%的算力,虽然当一个矿池或联合体尝试51%攻击时矿工可以转换到其它矿池这一事实减轻了问题的严重性。 - -以太坊现在的目的是使用一个基于为每1000个随机数随机产生唯一哈希的函数的挖矿算法,用足够宽的计算域,去除专用硬件的优势。这样的策略当然不会使中心化的收益减少为零,但是也不需要。注意每单个用户使用他们的私人笔记本电脑或台式机就可以几乎免费地完成一定量的挖矿活动,但当到了100%的CPU使用率之后更多地挖矿就会需要他们支付电力和硬件成本。ASIC挖矿公司需要从第一个哈希开始就为电力和硬件支付成本。所以,如果中心化收益能够保持在(E + H) /E 以下,那么即使ASICs被制造出来普通矿工依然有生存空间。另外,我们计划将挖矿算法设计成挖矿需要访问整个区块链,迫使矿工存储完成的区块链或者至少能够验证每笔交易。这去除了对中心化矿池的需要;虽然矿池依然可以扮演平滑收益分配的随机性的角色,但这功能可以被没有中心化控制的P2P矿池完成地同样好。这样即使大部分普通用户依然倾向选择轻客户端,通过增加网络中的全节点数量也有助于抵御中心化。 - -### 扩展性 - -扩展性问题是以太坊常被关注的地方,与比特币一样,以太坊也遭受着每个交易都需要网络中的每个节点处理这一困境的折磨。比特币的当前区块链大小约为20GB,以每小时1MB的速度增长。如果比特币网络处理Visa级的2000tps的交易,它将以每三秒1MB的速度增长(1GB每小时,8TB每年)。以太坊可能也会经历相似的甚至更糟的增长模式,因为在以太坊区块链之上还有很多应用,而不是像比特币只是简单的货币,但以太坊全节点只需存储状态而不是完整的区块链历史这一事实让情况得到了改善。 - -大区块链的问题是中心化风险。如果块链大小增加至比如100TB,可能的场景将是只有非常小数目的大商家会运行全节点,而常规用户使用轻的SPV节点。这会增加对全节点合伙欺诈牟利(例如更改区块奖励,给他们自己BTC)的风险的担忧。轻节点将没有办法立刻检测到这种欺诈。当然,至少可能存在一个诚实的全节点,并且几个小时之后有关诈骗的信息会通过Reddit这样的渠道泄露,但这时已经太晚:任凭普通用户做出怎样的努力去废除已经产生的区块,他们都会遇到与发动一次成功的51%攻击同等规模的巨大的不可行的协调问题。在比特币这里,现在这是一个问题,但Peter Todd建议的一个改动可以缓解这个问题。 - -近期,以太坊会使用两个附加的策略以应对此问题。首先,因为基于区块链的挖矿算法,至少每个矿工会被迫成为一个全节点,这保证了一定数量的全节点。其次,更重要的是,处理完每笔交易后,我们会把一个中间状态树的根包含进区块链。即使区块验证是中心化的,只要有一个诚实的验证节点存在,中心化的问题就可以通过一个验证协议避免。如果一个矿工发布了一个不正确的区块,这区块要么是格式错,要么状态S[n]是错的。因为S[0]是正确的,必然有第一个错误状态S[i]但S[i-1]是正确的,验证节点将提供索引i,一起提供的还有处理APPLY(S[i-1],TX[i]) -> S[i]所需的帕特里夏树节点的子集。这些节点将受命进行这部分计算,看产生的S[i]与先前提供的值是否一致。 - -另外,更复杂的是恶意矿工发布不完整区块进行攻击,造成没有足够的信息去确定区块是否正确。解决方案是质疑-回应协议:验证节点对目标交易索引发起质疑,接受到质疑信息的轻节点会对相应的区块取消信任,直到另外一个矿工或者验证者提供一个帕特里夏节点子集作为正确的证据。 - -## 综述:去中心化应用 - - - -上述合约机制使得任何一个人能够在一个虚拟机上建立通过全网共识来运行命令行应用(从根本上来说是),它能够更改一个全网可访问的状态作为它的“硬盘”。然而,对于多数人来说,用作交易发送机制的命令行接口缺乏足够的用户友好使得去中心化成为有吸引力的替代方案。最后,一个完整的“去中心化应用”应该包括底层的商业逻辑组件【无论是否在以太坊完整实施,使用以太坊和其它系统组合(如一个P2P消息层,其中一个正在计划放入以太坊客户端)或者仅有其它系统的方式】和上层的图形用户接口组件。以太坊客户端被设计成一个网络浏览器,但包括对“eth” Javascript API对象的支持,可被客户端里看到的特定的网页用来与以太坊区块链交互。从“传统”网页的角度看来,这些网页是完全静态的内容,因为区块链和其它去中心化协议将完全代替服务器来处理用户发起的请求。最后,去中心化协议有希望自己利用某种方式使用以太坊来存储网页。 - -## 结论 - - - -以太坊协议最初是作为一个通过高度通用的语言提供如链上契约,提现限制和金融合约,赌博市场等高级功能的升级版密码学货币来构思的。以太坊协议将不直接“支持”任何应用,但图灵完备编程语言的存在意味着理论上任意的合约都可以为任何交易类型和应用创建出来。然而关于以太坊更有趣的是,以太坊协议比单纯的货币走得更远,围绕去中心化存储,去中心化计算和去中心化预测市场以及数十个类似概念建立的协议和去中心化应用,有潜力从根本上提升计算行业的效率,并通过首次添加经济层为其它的P2P协议提供有力支撑,最终,同样会有大批与金钱毫无关系的应用出现。 - -以太坊协议实现的任意状态转换概念提供了一个具有独特潜力的平台;与封闭式的,为诸如数据存储,赌博或金融等单一目的设计的协议不同,以太坊从设计上是开放式的,并且我们相信它极其适合作为基础层服务于在将来的年份里出现的极其大量的金融和非金融协议。 - -## 注解与进阶阅读 - -### 注解 - -1.一个有经验的读者会注意到事实上比特币地址是椭圆曲线公钥的哈希,而非公钥本身,然而事实上从密码学术语角度把公钥哈希称为公钥完全合理。这是因为比特币密码学可以被认为是一个定制的数字签名算法,公钥由椭圆曲线公钥的哈希组成,签名由椭圆曲线签名连接的椭圆曲线公钥组成,而验证算法包括用作为公钥提供的椭圆曲线公钥哈希来检查椭圆曲线公钥,以及之后的用椭圆曲线公钥来验证椭圆曲线签名。 - -2.技术上来说,前11个区块的中值。 - -3.在内部,2和“CHARLIE”都是数字,后一个有巨大的base256编码格式,数字可以从0到2^256-1。 - -### 进阶阅读 - -1. Intrinsic value: https://tinyurl.com/BitcoinMag-IntrinsicValue - -2. Smart property: https://en.bitcoin.it/wiki/Smart_Property - -3. Smart contracts: https://en.bitcoin.it/wiki/Contracts - -4. B-money: http://www.weidai.com/bmoney.txt - -5. Reusable proofs of work: http://www.finney.org/~hal/rpow/ - -6. Secure property titles with owner authority: http://szabo.best.vwh.net/securetitle.html - -7. Bitcoin whitepaper: http://bitcoin.org/bitcoin.pdf - -8. Namecoin: https://namecoin.org/ - -9. Zooko’s triangle: http://en.wikipedia.org/wiki/Zooko’s_triangle - -10. Colored coins whitepaper: https://tinyurl.com/coloredcoin-whitepaper - -11. Mastercoin whitepaper: https://github.com/mastercoin-MSC/spec - -12. Decentralized autonomous corporations, Bitcoin Magazine: https://tinyurl.com/Bootstrapping-DACs - -13. Simplified payment verification:https://en.bitcoin.it/wiki/Scalability#Simplifiedpaymentverification - -14. Merkle trees: http://en.wikipedia.org/wiki/Merkle_tree - -15. Patricia trees: http://en.wikipedia.org/wiki/Patricia_tree - -16. GHOST: http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf - -17. StorJ and Autonomous Agents, Jeff Garzik: https://tinyurl.com/storj-agents - -18. Mike Hearn on Smart Property at Turing Festival: http://www.youtube.com/watch?v=Pu4PAMFPo5Y - -19. Ethereum RLP: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP - -20. Ethereum Merkle Patricia trees: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree - -21. Peter Todd on Merkle sum trees:http://sourceforge.net/p/bitcoin/mailman/message/31709140/ diff --git "a/[\344\270\255\346\226\207]-\346\254\212\347\233\212\350\255\211\346\230\216\346\251\237\345\210\266FAQ.md" "b/[\344\270\255\346\226\207]-\346\254\212\347\233\212\350\255\211\346\230\216\346\251\237\345\210\266FAQ.md" deleted file mode 100644 index d8fbcacfc..000000000 --- "a/[\344\270\255\346\226\207]-\346\254\212\347\233\212\350\255\211\346\230\216\346\251\237\345\210\266FAQ.md" +++ /dev/null @@ -1,239 +0,0 @@ -### 什麼是Proof of Stake(權益證明機制) - -權益證明機制是公有鏈共識演算法的一類,乙太坊接下來的 Casper 演算法是其中之一。它和比特幣、目前的以太坊及許多其他區塊鏈背後的Proof of Work有著相似的作用,但在安全性及能源使用效率上有著顯著的優點。 - -總的來說,權益證明機制演算法大致如下。區塊鏈記錄著一組 **validator** (驗證者),所有持有該區塊鏈數位貨幣的使用者(即以太坊的以太幣)都可藉由一個特殊交易將他們的數位貨幣鎖進一個存庫來成為驗證者。創造一個新的區塊的過程則藉由一個驗證者參與的共識演算法來進行。 - -目前有許多種的共識演算法及許多種獎賞驗證者的方式,因此有許多不同種類的權益證明機制。從一個演算法的角度,主要分為兩種: 鏈型態的權益證明機制 及 Byzantine Fault Tolerance( BFT,拜占庭容錯)相似的權益證明機制。 - -在鏈型態的權益證明機制中,演算法在每個時間區間(例如每十秒為一區間)裡以偽隨機的方式選擇驗證者,並賦予其創造一個區塊的權利。而這個區塊如同區塊鏈,必須指向之前的區塊(通常是指向最長鏈的最新區塊),並隨時間拉長,成為單一條持續增長的鏈。 - -在拜占庭容錯相似的權益證明機制中,某個驗證者被隨機指派來_提議_(propose)新的區塊,每一輪每個驗證者將票(vote)投給特定的區塊,經過多輪投票來決定區塊是否有效。在過程結束之後,該區塊是否合法會達成永久的共識,即不會再改變。 - -### 權益證明機制在和工作量證明機制相比下有哪些優點? - -詳細說明可見:[A Proof of Stake Design Philosophy](https://medium.com/@VitalikButerin/a-proof-of-stake-design-philosophy-506585978d51)裡有更完整的論述。 - -簡短來說: -* 不需要為了達成鏈的安全而**消耗大量電力**,(估計以太坊和比特幣每天都會各消耗一百萬美元在電力及硬體成本上)。 -* 因為不需要消耗大量電力,所以**沒有發行等量的貨幣的需要**來提供加入網路的動機。理論上甚至可以有淨量為負值的發行量--透過銷毀一部分的交易手續費的方式來達成。 -* 權益證明機制提供了更多賽局理論的發揮空間,來**降低中心化組織的形成**,以及在組織已形成的情況下,可能的方法來防止他們進一步傷害網路(例如工作量證明機制中的[selfish mining](https://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf))。 -* **減少中心化造成的風險**。因為採用權益證明機制後,礦工(驗證者)要擴展規模將不會是個問題。在工作量證明機制中,當你資本多到一定程度,你可以負擔更好的規模生產設備,拉大和其他人的差距(投入一千萬的成本所獲得的收益不只是投入一百萬的十倍)。而在權益證明機制中,相比於一百萬貨幣,持有一千萬的貨幣會保證讓你獲得十倍的報酬,而且是以公平的方式。 -* 可以利用經濟上的懲罰來**大大地提高不同51%攻擊方式在權益證明機制中所需要的成本**,引用 Vlad Zamfir 所述--"想像一參與51%攻擊你的ASIC工廠就會被燒毀"。 - -### 權益證明機制和傳統的拜占庭容錯研究怎麼結合? - -拜占庭容錯研究中有一些重要的結論是適用到各種共識演算法中的,包含傳統的演算法如PBFT,同時也可用在任何權益證明機制中。如果搭配恰當的數學模型,甚至可以用在工作量證明機制中。 - -這些重要的結論包含: - -* [**CAP 理論**](https://en.wikipedia.org/wiki/CAP_theorem) - "如果網路發生阻斷(partition)時,你只能選擇資料的一致性(consistency)或可用性(availability),無法兩者兼得"。論點很直覺:如果網路因阻斷而分隔為二,在其中一邊我送出一筆交易:"將我的十元給A";在另一半我送出另一筆交易:"將我的十元給B"。則此時系統要不是 (1)無可用性,即這兩筆交易至少會有一筆交易不會被接受;要不就是 (2)無一致性,一半看到的是A多了十元而另一半則看到B多了十元。要注意的是,CAP理論和擴展性(scalability)是無關的,他在分片(sharded)或非分片的系統皆適用。 - -* [**FLP impossibility**](http://the-paper-trail.org/blog/a-brief-tour-of-flp-impossibility/) - 在非同步(asynchronous)的環境中(即兩個正常運作的節點間,網路延遲沒有上限),只要有一個惡意的節點存在,就沒有演算法能在有限的時間內達成共識。但值得注意的是,["Las Vegas" algorithms](https://en.wikipedia.org/wiki/Las_Vegas_algorithm)在每一輪皆有一定機率達成共識,隨著時間增加,機率會越趨近於1。而這也是許多成功的共識演算法會採用的解決辦法。 - -* 容錯的上限 - 由[ DLS 論文](http://groups.csail.mit.edu/tds/papers/Lynch/jacm88.pdf) 我們可以得到以下結論: (1)在部分非同步(partially synchronous)的網路環境中(即網路延遲有一定的上限,但我們無法事先知道上限是多少),協議可以容忍最多 1/3 的拜占庭故障(Byzantine fault)。 (2)在非同步(asynchronous)的網路環境中,具 deterministic 性質的協議無法容忍任何錯誤,但這篇論文並沒有提及[ randomized algorithms](http://link.springer.com/chapter/10.1007%2F978-3-540-77444-0_7) 在這種情況可以容忍最多1/3的拜占庭故障。 (3)在同步(synchronous)的網路環境中(即網路延遲有上限且上限是已知的),協議可以容忍 100% 的拜占庭故障,但當超過 1/2 的節點為惡意節點時,會有一些限制條件。要注意的是,我們考慮的是"具認證特性的拜占庭模型(authenticated Byzantine)",而不是"一般的拜占庭模型";具認證特性指的是將如今已經過大量研究且成本低廉的**公私鑰加密機制**應用在我們的演算法中。 - -工作量證明機制 [已被 Andrew Miller 及其他人分析過](https://socrates1024.s3.amazonaws.com/consensus.pdf),是一個仰賴同步的網路環境的模型。我們可以將網路設定為有接近無窮數量的節點,而每一個節點擁有非常小的算力,且在一定時間內有非常小的機率可以產生區塊。在這個設定中,假如沒有網路延遲存在,則此協議有 50% 的容錯率。經過觀察,以太坊有約 46% 而比特幣擁有約 49.5% 的容錯率,但如果網路延遲和產生區塊時間相當時,容錯率會降低至 33% ,若網路延遲趨近無限,則容錯率趨近零。 - -權益證明機制則是包含在拜占庭容錯共識模型中,因為所有驗證者皆是已知且系統會記錄驗證者的數量。權益證明機制的研究一般可分為兩個路線,一個是同步的網路環境模型,一個是部分同步的網路環境模型。鏈型態的權益證明機制演算法幾乎都仰賴同步的網路環境模型,而它們的安全性分析也都可用這些模型以相似於 [工作量證明機制](http://nakamotoinstitute.org/static/docs/anonymous-byzantine-consensus.pdf) 的方式來分析證明。另一個路線將部分同步網路環境中的傳統拜占庭容錯演算法和權益證明機制做連結,但解釋比較複雜,在後面的章節會有更深入的探討。 - -工作量證明機制演算法和鏈型態的權益證明機制演算法都偏好資料的**可用性**而非資料的**一致性**,但拜占庭容錯類的共識演算法更傾向於選擇資料的**一致性**,[Tendermint](https://github.com/tendermint/tendermint) 明確地選擇資料一致性的特質。而 Casper 則採用混合的模型,此模型偏好資料的可用性,但盡可能的確保資料的一致性,它讓鏈上的應用和使用者在任何時間都能知道當前資料的一致性有多大的保證。 - -Ittay Eyal 和 Emin Gun Sirer 的 [selfish mining 研究](https://bitcoinmagazine.com/articles/selfish-mining-a-25-attack-against-the-bitcoin-network-1383578440) 結論 - 在不同網路環境的模型中,比特幣挖礦的激勵兼容性(incentive compatibility)分別受到 25% 及 33% 的限制,即只有在 25% 或 33% 的礦工同謀不可能發生的前提下,挖礦的機制才是激勵兼容的(即礦工按照正常的方式挖礦:有多少算力獲得多少報酬)。這個結論和傳統的共識演算法的結論無關,因為傳統共識演算法的結論並沒有牽涉到激勵兼容性。 - -### 什麼是"無成本風險"問題及該如何解決這個問題? - -在許多之前(鏈型態)的權益證明機制演算法,包含 Peercoin,只有對產生區塊給予相對應的獎賞但並沒有懲罰。這在出現多條相競爭的鏈(即分叉)的情況時,會有非預期的影響,因為每個驗證者皆有動機在每一條相互競爭中的鏈上產生區塊(以下將下注和產生區塊視為相同意思)來確保他們會獲得獎賞,如下: - -![](https://raw.githubusercontent.com/vbuterin/diagrams/master/possec.png) - -在工作量證明機制中,這麼做會導致礦工的算力被分散,導致獲利下降: - -![](https://github.com/vbuterin/diagrams/blob/master/工作量證明機制sec.png?raw=true) - -當給予區塊獎賞的同時卻沒有懲罰,結果就會造成 - 如果每個驗證者都是狹義上(narrowly)經濟理性的話,則即便在沒有任何攻擊者的情況下,區塊鏈本身也沒辦法達成共識。因為每個驗證者都在每條鏈上下注。如果有攻擊者,攻擊者只需要贏過那些執行利他行為(altruistic,即只會在單一條鏈下注)的節點即可,不需要贏過那些經濟理性的節點。相反的在工作量證明機制中,攻擊者必須要同時贏過利他節點和經濟理性節點(但這確實是可行的攻擊:參考 SchellingCoin 的 [P + epsilon 攻擊](https://blog.ethereum.org/2015/01/28/p-epsilon-attack/))。 - -有些人會認為下注者有動機按照規則來下注且只下注在最長的鏈上,好讓他們的投資能夠保值。然而這個論點忽略了這個動機受制於公地悲劇理論([tragedy of the commons](https://en.wikipedia.org/wiki/Tragedy_of_the_commons)):每個下注者可能只會有 1% 的機會成為關鍵(pivotal)的角色(即他的決定會影響一個攻擊的成敗),所以用來買通他們的賄絡金額只需要是他們總賭注金額的 1% 。因此,全部的賄賂金額只需要是下注總額的 0.5-1% 。此外,本段開頭的論點同時暗示著任何"不可能失敗"的情況都不是一個穩定的平衡,因為不可能失敗的情況代表每個下注者成為關鍵角色的機會是零,即只要賄賂金額超過 0% 都能讓下注者有動機參與攻擊。 - -有兩種方式可以解決這個問題。第一個為 "Slasher",在[這篇文章](https://blog.ethereum.org/2014/01/15/slasher-a-punitive-proof-of-stake-algorithm/)有大略地描述,並進一步由 [Iddo Bentov ](https://arxiv.org/pdf/1406.5694.pdf)開發。當驗證者同時在不同條分叉的鏈上下注(產生區塊)的情況發生時,將證據紀錄進區塊鏈中並以此銷毀驗證者的下注資本。這讓動機結構改變如下: - -![](https://github.com/vbuterin/diagrams/blob/master/slasher1sec.png?raw=true) - -注意,這個演算法要能執行,**驗證者是哪些人**需要事先就知道。否則驗證者可以任意選擇要下注的鏈:即當A鏈可下注就下注A鏈,當B鏈可下注就下注B鏈,當兩條都可以下注就下注最長的鏈。所以事先確定驗證者的名單可以避免這種情況發生。但這也有缺點存在,包括要求節點需要頻繁地上線來獲得安全可信的鏈的狀態(即確認區塊是不是由合格的驗證者所產生),並且讓 medium-range 的驗證者共謀攻擊有可能發生(例如連續三十個驗證者中有25個預謀發起攻擊來回復過去19個區塊),因為驗證者事先知道什麼時候會輪到他產生區塊。如果這些風險是可接受的那就沒太大問題。 - -第二個方式單純地懲罰在錯的鏈產生區塊的驗證者。也就是當有兩個互相競爭的A和B鏈,如果有一個驗證者在B上面產生區塊,則他可在B鏈上獲得 R 的獎賞,但這個區塊的標頭(header)資料會被記錄在A鏈上(在 Casper 中叫做 "dunkle" )且他在A鏈上會受到 F 的罰金( F 可能等於 R )。這會將結構改變成: - -![](https://github.com/vbuterin/diagrams/blob/master/slasher2sec.png?raw=true) - -直覺來說,我們可以把工作量證明機制的經濟模型複製到這來用。在工作量證明機制中,在錯的鏈上產生區塊同樣有懲罰,但這個懲罰並不顯而易見:礦工額外的電力或硬體成本花費(因為要同時在兩條鏈上花費運算)。第二個方式的一個缺點是,它將些微的風險加注到驗證者身上(因為驗證者要承擔在錯的鏈上產生區塊的成本),不過這個風險會隨者時間慢慢減退,但另一方面,它的優點是不需要事先知道驗證者有誰。 - -### 上一章節介紹鏈型態的權益證明機制如何解決"零風險成本"問題,那拜占庭容錯相似的權益證明機制又是怎麼運作的呢? - -拜占庭容錯類型(部分同步的網路環境)的權益證明機制演算法允許驗證者藉由送出遵守兩類別規則的簽名訊息,來對區塊進行"投票",這兩類規則分別是: - -* **終局條件(Finality conditions)** - 規則用來決定某雜湊值是否可被視為不可更改的(finalized)。 -* **刪砍條件(Slashing condition)** - 規則用來決定是否有足夠理由懷疑某個驗證者作弊(例如同時下注多個相衝突的區塊)。 - -如果有驗證者觸發其中任何一條規則,他們的資本將全數被刪去。 - -以下舉兩個例子來說明不同刪砍條件的發生場景,下面的" 2/3 的驗證者" 代表 "全數驗證者資本總和的 2/3,而不是驗證者數量的 2/3 ",其他的比例亦相同。在這些例子中,"PREPARE" 和 "COMMIT" 可單純地理解為兩種驗證者可送的簽名訊息(`MESSAGE`)。 - -1. 如果`MESSAGE`包含:`["COMMIT", HASH1, view]` 和 `["COMMIT", HASH2, view]`,其中`view`為相同但`HASH1`和`HASH2`不同,且皆由同一個驗證者所簽名,則該驗證者的資本被刪去。即不能同時對相衝突的區塊做簽名。 -2. 如果`MESSAGE`包含:`["COMMIT", HASH, view1]`,則**除非** `view1 == -1` ,或同時存在其他包含`["PREPARE", HASH, view1, view2]`的簽名訊息(其中 `view2 < view1`)且這些訊息由至少 2/3 的驗證者所簽名,則對`"COMMIT"`簽名的驗證者的資本被刪去。即一個 `HASH` 值只有經過至少 2/3 `PREPARE` 才能被 `COMMIT`。 - -合適的刪砍條件需要有兩個重要的要求: - -* **可咎責的安全性(Accountable safety)** - 如果相互衝突的`HASH1` 和 `HASH2`(即分叉)都被認定為不可更改,則至少有 1/3 的驗證者肯定違反了某些刪砍條件。 -* **Plausible liveness** - 除非至少 1/3 的驗證者違反了某些刪砍條件,否則必定存在某些合法的訊息是 2/3 的驗證者可以簽的,且這些訊息會讓某些雜湊值變成不可更改(finalized)。即除非至少 1/3 的驗證者違規,否則一定可以讓新的雜湊值被 finalize。 - -如果我們有一組刪砍條件可以達成這兩個要求,我們便可以提供驗證者足夠的動機,並開始從 economic finality 的特性中得到成果。 - -### 一般來說,什麼是"經濟面上終局的特性"? - -經濟面上終局指的是:當區塊被認定為不可更改,或更一般來說,有一種訊息獲得足夠數量的簽名,則唯一讓鏈在未來納入另一個相衝突的區塊的方法是有一大群的人願意賠上一大筆錢。如果一個節點看到某個區塊符合經濟面上終局的特性,則他有經濟面上非常大的保證這個區塊會成為鏈的一部分歷史(且這條鏈也是大家都認可的)。 - -達成經濟面上終局有兩種方法: - -1. 如果有足夠多的驗證者對以下形式的聲明進行簽名,則一個區塊可被視為具有經濟面上的終局:"當區塊B沒有被收入則我會失去X的資本"。這讓使用者獲得了如下的保證 - (I)區塊B是鏈的一部分,或是 (II)若驗證者想騙他們,讓他們相信區塊B是有被收入的,則驗證者會損失一大筆錢。 - -2. 如果有足夠多的驗證者簽名表達支持收入區塊B,而且有方式能在驗證者違規時提出數學證明(_當不同於區塊B的某區塊B'也以同樣方式被收入_)並讓這些驗證者損失一大筆錢,則一個區塊可被視為經濟面上的不可更改。如果使用者看到這個被收入的區塊,並驗證了鏈的有效性,且藉由有效性(validity)和不可更改性(finality)他們可以在發生分叉的鏈之中做出選擇,則他們能獲得如下的保證 - (I)區塊B是鏈的一部分,或是 (II)若驗證者同時也參與了另一條互相競爭且亦符合終局條件的鏈,則驗證者會損失一大筆錢。 - -兩種達成終局(finality)的方法分別繼承自"零風險成本問題"的兩個解決方法: 藉由懲罰錯誤(如`"COMMIT"`不合法的區塊)來達成終局 及 藉由懲罰不明確性(如`"COMMIT"`兩個衝突區塊)來達成終局。第一個方法的主要優點是輕客戶端(light client)使用者也能驗證且比較直覺易懂;第二個方法的主要優點有 (I)比較容易瞭解為何誠實的驗證者不會被懲罰及 (II)干擾因素(griefing factors)對誠實的驗證者比較有利 - 相比於不誠實者干擾誠實者所要付出的成本,誠實者干擾不誠實者的成本是比較低的。 - -Casper 遵循第二種方法。不過可以透過增加鏈上的機制,讓驗證者可以自行選擇是否要對第一種方法的聲明("當區塊B沒有被收入則我會失去X的資本")簽名,此舉可讓更多輕客戶端使用者增加效率。 - -### 所以這和拜占庭容錯理論有什麼關聯? - -傳統的拜占庭容錯理論在 safety 和 liveness 上和我們有相似的要求。首先,傳統拜占庭容錯理論要求當超過 2/3 的驗證者是誠實的時候,safety必須要被達成。嚴格來說這是比較容易實現的模型,傳統的拜占庭容錯理論嘗試證明"如果共識機制無法達成safety,則我們知道至少有 1/3 的驗證者是惡意的";而我們的模型則是嘗試證明"如果共識機制無法達成safety,則我們知道至少有 1/3的驗證者是惡意的,而且我們知道是哪些驗證者,即便你在出現問題的當下不在線上"。從liveness的角度,我們的模型比較容易達成,因為我們不需要證明**共識會被達成**,我們只需要證明機制**沒有卡住**。 - -不過幸運的是,額外的"可咎責的"(accountable)特性需求其實不難實現;事實上,只要協議有正確的防禦機制(protocol armor),我們都可以將任何不管是部分同步或是非同步的傳統拜占庭容錯演算法轉換成可咎責的演算法。這個證明基本上歸結於一個事實--拜占庭故障(fault)可以被窮舉並分類,而這每一類要不是 (I)可咎責的(如果你`"COMMIT"`了這類的訊息,則你會被逮到,且我們可以為此建立一條刪砍條件的規則),要不就是 (II)無法被分辨是網路延遲還是故障(注意,即便是太早送出訊息這種故障,也沒辦法被分辨出來)。 - -### 什麼是弱主觀性(weak subjectivity)? - -首先很重要的一點是,利用存款(deposit,也就是驗證者加入的資本)來確保"風險成本不為零"的機制,改變了權益證明機制的安全模型假設(security model)。假設 (I)存款會被鎖住一個月,時間到之後可以提走, (II)有個 51% 攻擊嘗試反轉(revert)長達 10 天的交易量,則這些攻擊者產生的區塊會被寫入鏈裡當作證據且驗證者會被懲罰。然而,假設攻擊變成長達 40 天,則雖然這些攻擊產生的區塊可以再被寫入鏈裡,但驗證者早已能把錢提走而不會受到懲罰。為了要解決這個問題,我們需要一個"反轉限制(revert limit)"的規則,也就是當反轉所影響的區塊總時間長度超過存款鎖住的期限,則節點可以拒絕接受這些區塊(在上例,即拒絕影響超過一個月的反轉區塊)。這表示節點現在多了兩項要求: - -1. 當節點第一次連上並要同步鏈的資料的時候,他們必須藉由鏈外的方式來驗證最新的狀態,即透過朋友節點們或各個 Block Explorer 等等的方式。如果他們得到的都是同一條一樣的鏈,則可以確定這條是正確的。注意,只有在出現鏈分叉長度超過反轉限制時(在上例,即得到兩條在過去超過一個月的區塊皆不相同的鏈)才需要這種採用這種鏈外的交際驗證(social authentication)。 - -2. 節點每隔一段的時間("反轉限制"時間)就必須要上線同步。如果沒定時同步,則需要再透過一次鏈外的交際驗證來保證狀態的可信度。 - -如果攻擊者要利用鏈外交際這個管道來攻擊,他們必須要說服社群裡一大部分的人,讓他們相信攻擊者的鏈才是有效的;或是改為說服新加入社群的人:新加入的人可能會在下載軟體時一並收到最近一次的檢查點(checkpoint,即反轉限制的臨界點),但如果攻擊者能竄改這個檢查點的紀錄,則他們要能直接竄改整個軟體也不再是件難事,而且沒有單純的密碼經濟學的驗證方式能解決這個問題。當一個節點連接上了,只要他夠頻繁地上線,他就能以密碼經濟學上安全的模型來確保連接上正確的鏈,而不需要額外的鏈外交際驗證。 - -另外,這種交際驗證如果需要,也可以直接加入進使用者使用的過程中:如 (1)[BIP 70](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki)的交易就要求交易裡要加入最近一段時間的某個區塊的雜湊值,使用者的軟體會在交易成立前,藉此確保使用者和商家是在同一條鏈上(也可以透過其他鏈上的互動方式)。 或(2),採用Jeff Coleman的 [universal hash time](https://www.youtube.com/watch?v=phXohYF0xGo)。採用UHT的話,如果攻擊要能成功,攻擊者必須在被攻擊鏈繼續增長的**同時**,暗中產生另一條鏈(即攻擊者沒辦法事先或在事後短時間內產生一條相抗衡的鏈),代表這需要大多數的驗證者共謀了一段非常長的時間。 - -### 在權益證明機制裡可以用經濟上的方式來懲罰審查(censorship)行為嗎? - -審查行為比起交易反轉要更難去證明。區塊鏈本身無法分辨 (1)"使用者 A 嘗試送出交易 X 但被審查過濾掉了" 或是 (2)"使用者 A 送出交易 X 但因為交易費不夠而沒被收入區塊裡" 或是 (3)"使用者 A 從未送出交易 X "。但仍有一些方法可以對抗審查行為。 - -第一個是使用停機問題(halting problem)。這個方法比較弱的版本是將協議設計成圖靈完備,使得驗證者無法知道一筆交易會不會在花費他大量的運算後因為出現預期外的行為而出錯,但這同時也讓驗證者面臨潛在的 DoS 攻擊。這也是當初[ the DAO 軟分叉](http://hackingdistributed.com/2016/07/05/eth-is-more-resilient-to-censorship/)沒有實行的原因。 - -比較強的版本則是讓交易在未來中短期的時間內觸發特定的效果。使用者可以送出多筆相互關聯的交易及利用可預期的第三方的資訊來導致未來事件的發生,想要進行審查的驗證者要等到交易都被收入區塊(並確認為不可更改)才能知道發生了什麼事件,但此時要阻止交易又已經太遲。即便過濾掉所有相關的交易,審查者想阻止的事件還是會發生。審查者可以試著過濾掉每一筆交易,或是過濾掉沒有附上相關證明(證明交易不會導致任何非預期的情況發生)的交易,但這麼做會擋掉非常多不同類型的交易以至於讓整個系統失靈,審查者的存款價值也會跟著該數位貨幣的價值崩盤而下降。 - -第二個方法是([如 Adam Back 在這篇文章](https://www.reddit.com/r/Bitcoin/comments/4j7pfj/adam_backs_clever_mechanism_to_prevent_miners/d34t9xa))所介紹,要求交易都經過[timelock-encrypted](https://www.gwern.net/Self-decrypting%20files)加密。所以審查者只能在不知道交易的內容的情況下將交易收入區塊,直到之後某個時間點交易內容被揭露,但此時要過濾掉交易已經太遲。但是審查者可以選擇只收入有附上解密證明(如利用 zkSNARK 等零知識證明)的交易;這雖然會強迫使用者必須要去下載相關的使用軟體,但審查者可以直接提供所需軟體。這在賽局理論中,使用者是有動機去配合的。 - -或許在權益證明機制中比較好的做法是使用者透過軟體更新來執行硬分叉,將惡意的驗證者移除。這個方法和下載解密軟體來配合審查的方法相比,並沒有多難。總之,第二個方法雖然會降低和鏈溝通互動的速度(注意,採用這個方法必須是強制的才會有效,否則審查者只需要過濾掉經過加密的交易並收入沒加密的交易即可),卻也是比較適度且有效的。 - -第三個方法是在鏈分叉發生時,將偵測審查行為發生的機制加進分叉選擇的考量。原理很簡單,節點持續觀察著網路及交易,如果他們發現某筆交易帶有夠多的手續費卻遲遲未被收入,就給沒有收入這筆交易的鏈較低的評分。如果所有的節點都遵守這規則,則最終較弱勢的鏈也會因為收入了這個交易而讓其他誠實的節點都轉而加入這條鏈。這個方法主要的缺點是,離線的節點還是紀錄者強勢的(有審查機制的)鏈,如果在他們重新上線之前審查行為就結束了,則會造成上線的(誠實的)節點間的分歧。因此這個方法比較適合被用來當作緊急情況如硬分叉發生時的一個節點間的協調工具,如果是用在幾乎每天都會發生的鏈分叉選擇考量則不太合適。 - -### 驗證者是怎麼選出的?什麼又是stake grinding? - -在任何鏈型態的權益證明機制演算法中,都需要一個機制來隨機選出哪個驗證者可以產生下個區塊。例如,假設目前活躍中的驗證者包含 資本為 40 元的的 Alice、資本為 30 元的 Bob、資本為 20 元的 Charlie 及資本為 10 元的 David,則你希望他們各自被選出的機率分別為 40%、30%、20%及10%(當然在實際情況中,你會希望選出來的是一連串無限的候選人而不是一個,這樣當前面一位沒出現,後面一位就可以遞補,但這不影響根本的問題)。在非鏈形態的演算法中,一樣會因為不同原因而需要隨機性(randomness)。 - -"Stake grinding"是一種驗證者試圖透過一些計算或其他方式來影響隨機性的攻擊。例如: - -1. 在 [Peercoin](https://bitcointalk.org/index.php?topic=131901.0) 中,驗證者可以搜尋各種參數的組合並找到特定的參數來增加他們產生有效區塊的次數。 - -2. 在一個目前已經不使用的方式裡,第 N+1 個區塊的隨機性取決於第 N 個區塊裡的簽章。這讓驗證者可以重複產生新的簽章直到他們找到一個特別的簽章來讓他們能預測並掌握下一個區塊,以藉此控制系統。 - -3. 在 NXT 中,第 N+1 個區塊的隨機性取決於產生第 N 個區塊的驗證者。這讓驗證者可以藉由跳過一個產生區塊的機會來操縱隨機性。雖然這麼做的機會成本是損失一個區塊獎賞,但有時候新產生的隨機種子可以讓驗證者在未來數十個區塊中獲得高於平均區塊獎賞的獎勵。[這裏](http://vitalik.ca/files/randomness.html)有更詳細的分析。 - -\#1和\#2很容易解決;一般的做法是要求驗證者事先存款來避免驗證者一直改變身份(address)來找到可以影響隨機性的值,並避免使用可以輕易被操縱的訊息,例如一個區塊裡的簽章。有幾個主要的策略來解決\#3。第一個是利用 [secret sharing](https://en.wikipedia.org/wiki/Secret_sharing) 或是 [deterministic threshold signatures](https://eprint.iacr.org/2002/081.pdf) 並要求驗證者一同產生隨機值。這些方法在大多數驗證者沒有同謀的時候都足夠穩固(看各種應用不同,33%-50% 的驗證者合謀就可以干預,使得協議對維持 liveness 的機率假設剩下 67% )。 - -第二個方法是使用密碼學的方式:驗證者事先 commit 一些訊息(如公布 `sha3(x)`),接著在區塊內公佈 `x` 值,最後將 `x` 值和其他人的隨機值加在一起。理論上針對這個方法有兩種潛在的攻擊。 - -1. 在commit時操縱 `x` 值。但因為結果會將許多人的 `x` 值一起加入考量,其中只需要一個人是誠實的,隨機性的分佈就會呈常態分佈,所以這攻擊不太可行。 - -2. 選擇性地不公開區塊。這種攻擊的機會成本是損失一個區塊獎賞,而且這個方法頂多只能讓一個人看到下一個區塊的驗證者是誰,所以最多可能的獲益也是一個區塊獎賞。唯一的例外是,如果一個驗證者跳過,則遞補上來的驗證者和下一個區塊的驗證者有可能會是同樣一個驗證者。可以用懲罰的方式來抵消驗證者跳過的動機。 - -第三個方法是使用 [Iddo Bentov 的 "majority beacon"](https://arxiv.org/pdf/1406.5694.pdf),藉由之前產生的(也用 beacon 方式產生的) N 個隨機數字中的每個 bit 值的多數決來產生新的隨機數字(即,如果大多數數字的第一個 bit 為 1 ,則新的數字的第一個 bit 為 1 ,否則為 0 )。攻擊的成本會是 `~C * sqrt(N)` ,其中 C 是攻擊其他 beacon 產生的隨機數字的成本。總之,有許多 stake grinding 的解決方法存在,這個問題比較像是 [differential cryptanalysis](https://en.wikipedia.org/wiki/Differential_cryptanalysis) 而不是 [halting problem](https://en.wikipedia.org/wiki/Halting_problem) - 權益證明機制的設計者最終會明瞭且會知道如何克服,不是很根本且無法彌補的缺陷。 - -### 針對 Casper 的 51% 算力攻擊會是怎麼樣的攻擊? - -51% 攻擊最基本的形式就是 **finality reversion**:驗證者確立區塊 A 的紀錄為不可更改後又將另一個區塊 A' 也列為不可更改,打破區塊不可更改特性的保證。在這個情況中並存著兩個彼此不相容的歷史紀錄,導致鏈產生分叉。這需要仰賴社群以鏈外的方式進行協調來決定應該選擇哪條鏈,而哪條該被捨棄。 - -協調的管道有很多種,如社群媒體、block explorer 及交易所間的溝通、線上論壇等等。決定該選哪條鏈的原則是 "哪條先出現就選哪條" 。另一個方式是讓市場機制去決定:在很短的時間裡,兩條分叉都可以在交易所中交易,直到其中一條因為價值更高而勝出。在這種情況中,"哪條先出現就選哪條" 的原則會是市場機制的 [Schelling point](https://zh.wikipedia.org/wiki/谢林点),即參與者會因為覺得其他人也會選擇先出現的那條鏈而傾向選擇先出現的那條,所有人在沒有溝通的情況下按照這個傾向選擇了先出現的那條鏈。所以實際中,這兩種方式並用是非常有可能的。 - -當該選擇哪條鏈的共識達成時,使用者(即驗證者、light node 及 full node)就可以手動地將勝出區塊的雜湊值藉由特殊的選項寫入軟體中,之後他們的節點就會忽略其他不包含該雜湊值的鏈。之後不管是哪條鏈被選擇,都有證據可以用來懲罰至少 1/3 的違規驗證者。 - -另外一種攻擊是阻斷 liveness:一個由超過 34% 驗證者組成的集團可以拒絕和其餘的驗證者合作。在這種情況下,將沒有區塊能被變成不可更動。Casper 採用混合(鏈 + 拜占庭容錯)型態的共識,因此鏈還是會持續增長,但安全性會大大降低(因為一直沒有新的區塊可以被視為不可更改)。如果很長一段時間(例如一天)都沒有區塊變成不可更改,則有以下幾種選項: - -1. 可以採用一個自動化的功能來輪轉驗證者名單,瓦解集團的佔比。在新的驗證者名單中區塊有機會被變為不可更改,但使用者會收到提醒告訴他們這些不可更改的區塊還是不能全信的,因為很有可能舊的一組驗證者會重新奪回控制權並改為將其他的區塊變為不可更改。使用者如果確信舊的一組驗證者不會再上線,就可以忽略這些警告。在這種情況發生時,所有舊的驗證者如果沒有再繼續參與共識過程,則他們會受到相當大筆的罰款。 - -2. 採用硬分叉的方式移除集團驗證者的存款,並增加新的驗證者。 - -在第二種方法中,分叉還是一樣要由鏈外的共識來協調,且可能會由市場機制的方式(即兩條擁有不一樣驗證者組成的鏈短暫的並存於交易市場上)。如果是藉由市場共識的方式,有個有力的論點是:市場會傾向選擇 "好人勝出" 的鏈,這條鏈的驗證者展現了他們的誠意(或至少他們和使用者的利益是並存的),因此也是一條對應用開發者較有用的鏈。 - -選擇攻擊應對的策略如社交協調或機制內自動化,兩者之間其實有如一道光譜,並不是非黑即白。通常設計越往自動化的解法越理想,因為這可以降低當 51% 攻擊和社交層面(包含市場共識如交易所)的攻擊同時發生時的風險。可以想像一個採用 \#1 的措施:節點在超過一定時間都沒有區塊變為不可更改時自動更換驗證者名單,這會降低交際協調的需要,但節點也因此要更頻繁地保持上線。但不管是哪種方式,攻擊者都會損失一大筆的錢。 - -另外一種比較不容易發覺的攻擊是審查攻擊:超過 34% 的驗證者拒絕將含有某些特定交易的區塊變為不可更改,除此之外鏈的運作都正常。攻擊的範圍從輕微的,干擾特定應用的攻擊(如過濾 Raiden 或閃電網路的交易是較簡單偷錢的方式)到阻擋所有交易的大範圍攻擊。 - -其中又分成兩種情況,第一個是攻擊者佔 34%-67%。在這種情況中,正常的驗證者可以拒絕將他們主觀認定為正在過濾交易的區塊(即攻擊者產生的區塊)變成不可更改或接在後面,這讓這種攻擊變為一個標準的針對 liveness 的攻擊。比較危險的情況是當攻擊者佔超過 67%,攻擊者可以任意的阻擋他們不喜歡的交易並拒絕接在包含這些交易的區塊後面。 - -面對這個攻擊有兩道防線。第一,以太坊具有圖靈完備特性,[在本質上就具有抵抗審查的能力](http://hackingdistributed.com/2016/07/05/eth-is-more-resilient-to-censorship/),因為審查交易的過程在某種程度上相似於解決停機問題(halting problem)。但因為區塊有 gas 限制,所以審查並不是不可能,不過用"簡單"的方式來審查反而會讓攻擊者自己有被 DoS 的風險。 - -單純具有這個抵抗能力[還不夠好](https://pdaian.com/blog/on-soft-fork-security/),還有其他方式可以加強抵抗審查的能力。最有趣的方式是增加一個機制內的功能:讓交易能自動規劃未來的事件,因為預測一個事件的執行結果或是連鎖事件是很難的。驗證者可以藉由混淆事件規劃的順序來加入成為驗證者,藉此稀釋攻擊者的佔比到低於 33% 。 - -第二,引進 "active fork choice rule" 的概念:當面臨鏈分叉,其中一個選擇鏈的考量是和鏈進行互動並藉此驗證該鏈是否有在過濾你的交易。最有效的方式是節點重複地送出一筆交易來規劃下注並在最後一刻取消。如果節點偵測到審查機制,就不取消交易並暫時加入成為驗證者之一,將攻擊者的佔比稀釋到 33% 。如果集團過濾掉他們的交易,則採用這個 "active fork choice rule" 的節點就不會選擇這條鏈。這會讓審查攻擊轉變為 liveness 攻擊,此時就可以藉由解決 liveness 攻擊的方式來處理。 - -### 聽起來似乎很仰賴鏈外的社交協調,這樣難道不危險嗎? - -攻擊 Casper 代價非常高。以下我們將會講到,攻擊 Casper 的代價至少和買礦機持續不斷的對採用工作量證明機制的鏈發動 51% 攻擊直到無效果為止的代價一樣。因此,上面段落所描述的復原方法只有在非常極端的情形才會用到。事實上,工作量證明機制的提倡者亦表達在某些相似情況採用社交協調的意願,例如[改變工作量證明機制的算法](https://news.bitcoin.com/bitcoin-developers-changing-proof-work-algorithm/)。所以權益證明機制需要的社交協調是否會比工作量證明機制所需要的社交協調還多還無明確的結果。 - -在現實中,我們預期用到社交協調的方式的次數會接近零次,因為攻擊者會瞭解到單純為了讓區塊鏈停擺一兩天要花費這麼大筆的錢是不符利益的。 - -### 邊際成本趨近邊際收益不就表示所有具有一定高度安全層級的共識演算法都一樣有效(或一樣地浪費)? - -許多人都提出過這個論點,而解釋最清楚的就屬[Paul Sztorc 的這篇文章](http://www.truthcoin.info/blog/工作量證明機制-cheapest/)。其中的重點大概是:如果你創造一個有 100 元獎賞的機會,則大家為了得到它會願意花費最高到 99.9 元(包含自己付出的勞力),此時邊際成本趨近邊際效益。因此,這個理論說:任何提供區塊獎賞的演算法(不管是權益證明機制或工作量證明機制),其中為了獲取獎賞而進行對社會無效益的活動的數量都是一樣的,即它們都一樣地浪費資源。 - -這個理論有三個盲點: - -1. **單純地說邊際成本趨近邊際效益是不夠的,必須還要假設一個真的有人可以花費那些成本的機制存在。** 例如,假設我明天宣布未來每一天我都會隨機從一個十人名單中挑出一個人並給予他 100 元,然而沒有人有辦法花費 99 元來取得其中的隨機值。他們要不是不在名單中拿不到獎賞,要不就是在名單中但沒有任何有效的方法取得我的隨機值,只能獲得期望值為平均每天 10 元的獎賞。 - -2. **邊際成本趨近邊際效益不表示總成本趨近總收益。** 例如,假設存在一個演算法利用偽隨機(pseudo-randomly)的方式從一大群驗證者中選擇 1000 位驗證者(一個驗證者獲得 1 元獎賞)。如果你資本佔總資本的 10% 則你平均會獲得 100 元。假設你可以花費 1 元來(無限次地)重設隨機值,因為 [central limit theorem](https://en.wikipedia.org/wiki/Central_limit_theorem),你可獲得的獎賞的標準差是 10 元,又因為[其他已知的數學結論](http://math.stackexchange.com/questions/89030/expectation-of-the-maximum-of-gaussian-random-variables), N 個隨機抽樣中最大的期望值約略小於 ` M + S * sqrt(2 * log(N))` ,其中 M 是中間值且 S 是標準差。因此增加重設隨機值的次數(即增加 N )所獲得的獎賞會快速地下降,例如如果完全不嘗試重設隨機值你的期望獲利是 100 元,嘗試一次是 105.5 元,兩次是 108.5 元,三次是 110.3 元,四次是 111.6 元,五次是 112.6 元,六次是 113.5元(只增加 0.9 元的獲利)。因此嘗試超過五次之後就不值得再繼續嘗試。所以一個由經濟因素所驅動的攻擊者,如果他總資本佔 10% ,則他會花費 5 元嘗試重設隨機值來獲得額外的 13 元的獲利,雖然這麼做很沒效率。如果一個機制可被有心人士利用,但被利用的機率不高,則損失不會多。但這不適用於在工作量證明機制中因為出現一個漏洞而導致全部資源投入而造成浪費的情況。而這點也和下一章節要介紹的 capital lockup costs 非常相關。 - -3. **權益證明機制要變得安全穩固所需要的獎賞比起工作量證明機制的獎賞少的非常多。** - -### 什麼又是 capital lockup costs? - -將 X 數量的 ether 鎖進存庫是有代價的,例如犧牲選擇其他選項的機會。如果我有 1000 ether,我想怎麼使用就怎麼使用,但如果我將它鎖在存庫裡數個月,而且沒有保險來支付可能的意外支出的時候該怎麼辦?在這段時間我同時也失去將 ether 轉換成其他代幣的自由。我可以透過賣空相等數量 ether 的方式來模擬賣掉我的 ether,但會有交易手費續和利息的成本。有些人可能會認為: captital lockup 造成的經濟上的不便和工作量證明機制造成的經濟層面上無效率的程度是一樣的。但答案是否定的,如同上一章節的理由\#2和理由\#3。 - -我們先從理由\#3開始講起。考慮一種模型:權益證明機制存款是無限期的、ASICs可以永久持續運作、ASIC技術固定(即不適用摩爾定律)而且電力花費是零,並假設穩定的利率是每年 5%。在工作量證明機制裡,我花 1000 元買了礦機,礦機每年給我 50 元的利潤直到永遠。在權益證明機制中,我存 1000 元(因為存款是無限期的所以這筆錢當作花掉)並獲得每年 50 元的利潤直到永遠。到目前為止,兩種情況看起來是等價的(雖然技術上來說,在權益證明機制中當我的存款因違規被銷毀時,會間接造成其他人的存款價值升高,但這邊我們先不討論)。在這個假設下,不管是權益證明機制或工作量證明機制,任何人要發動 "Maginot-line" 51% 攻擊(即硬體買得比網路其他人加起來還多)的成本都會因為我的加入而再多上 1000 元。 - -現在假設模型依序做以下的變更: - -1. 摩爾定律適用,ASICs 每 2.772 年貶值 50%(為方便計算,假設其價值每年持續降低 25%)。如果我要繼續保持 "付一次,永遠都能持續拿回錢" 的模式,我可以將 1000 變成一筆資金,其中167用來買 ASICs ,833 元花在 5% 報酬率的投資。833元的投資產生每年 41.67 元的利潤剛好足夠花在更新 ASICs 設備上(為方便計算,假設技術發展是穩定連續的)。這時挖礦的利潤會降低至 167 * 0.05 = 每年 8.33 元,因此 83.3% 的礦工會退出競爭,直到回到每年 50 元利潤的穩定狀態,所以這時發動 Maginot-line 51% 攻擊的成本會縮小至少六倍。 - -2. 電力加上硬體維護組成大約 1/3 的挖礦成本。1/3 是從最近的數據估計而來的:Bitfury 的新資料中心 [每 gigahash 電力消耗為 0.06 焦耳 ](http://www.coindesk.com/bitfury-details-100-million-georgia-data-center/),或 每 terahash 60 焦耳、每terahash 0.000017千瓦小時。如果假設比特幣網路的平均消耗皆如此的話,以[比特幣總共算力約 1.67 million TH/s](http://bitcoinwatch.com/) 來算,每秒約消耗 27.9 千瓦小時。中國電力成本為[每千瓦小時 0.11 元 ](http://www.statista.com/statistics/477995/global-prices-of-electricity-by-select-country/),約為每秒 3 元或每天 26 萬元。比特幣區塊獎賞加上手續費為 600 * 13 * 144 = 一天 112 萬元。因此電力組成約 23% 的成本,另外我們可以用簡單的計算預估硬體維護成本為 10% 。這表示你的 1000 元資金裡,只有 111 元要拿來買 ASICs,55 元要拿來付持續性的花費如電力和維護等,而 833 元會花在投資上,因此現在要發動 Maginot-line 51% 攻擊的成本已經是一開始的至少九倍小了。 - -3. 事實上存款是短暫而非永遠(被視為拿不回來)的,當然你自願永遠存著的話也行。這讓我多了一些空間選項,我可以在任何時間內結束並等待一段時間(如四個月)。這表示我願意花更多的錢來獲得更多的利潤(因為投資不會再被當作拿不回來的錢),或許是 3000 元。因此,在權益證明機制裡發動 Maginot line 51% 攻擊的成本增加為原本的三倍,和工作量證明機制比起來是 27 倍的安全性。 - -以上包含了很多簡化過的計算,但它的目的是為了指出經過許多因素考量,都顯示出權益證明機制有更高的安全性。而這個[看似可疑的多重因素論點](http://lesswrong.com/lw/kpj/multiple_factor_explanations_should_not_appear/)為何這麼強烈凸顯權益證明機制的優點的主要理由是:在工作量證明機制中,我們操作並利用物理特性;而在權益證明機制中,我們可以設計出一套準確具有理想特性的機制 - 簡而言之,我們可以用我們的方式來優化 "物理特性"。在安全模型上的改變,特別是弱主觀性(weak subjectivity)這個性質的出現,讓我們能得到以下結論 - **權益證明機制要變得安全穩固所需要的獎賞比起工作量證明機制的獎賞少的非常多。**。 - -接者我們可以討論 邊際成本/效益 和 總成本/效益 的不同。在 capital lockup costs 的情況中這非常重要。例如假設一個情況,你有價值 100000 的 ether。鎖住其中的 50000 應該不會有什麼問題,鎖住 80000 可能會有一點不方便雖然 20000 還是夠充足,鎖住 90000 就有點問題了,99000 問題就大了,全鎖住那你可能是瘋了,因為你會連交易費都出不起。因此你的邊際成本快速的增加,我們可以用以下方式比較權益證明機制情況和工作量證明機制情況的不同: - -![](https://blog.ethereum.org/wp-content/uploads/2014/07/liquidity.png) - -可以看到在權益證明機制的總成本是遠小於存入 1 ether 的邊際成本乘上現有所有的存款總量。 - -注意,這部分的論點可惜地並沒有完全解釋到 "貨幣的安全發行量(safe level of issuance)"。但其顯示出即使我們將貨幣發行量控制地很低,我們還是能獲得可觀的 權益證明機制參與人數,雖然這也代表很大一部分的發行量會被用來獎賞驗證者。 - -### 在權益證明機制的礦池會有類似工作量證明機制礦池中心化的風險嗎? - -從 [Bitcoin](https://blockchain.info/pools) 和 [Ethereum](https://etherscan.io/stats/miner?range=7&blocktype=blocks) 來看,大約需要三個礦池聯合才能發動 51% 攻擊( 在寫這篇文章的時候,Bitcoin 約需四個、Ethereum 約需三個)。假設在權益證明機制中,包含所有礦池、交易所一共有 30% 的參與率,則 [三個礦池或交易所](https://etherscan.io/accounts) 就足夠發動 51% 攻擊;如果參與率提高到 40% 則需要八個。另外礦池、交易所也不能將所有資本投入攻擊中,因為他們需要保留部分金錢來應付客戶。 - -再加上在權益證明機制中,組成的礦池的動機是較低的,因為這會需要較高的信任成本 - 雖然礦池不偷錢,但是可以假裝被駭去觸發刪砍條件而導致資本全被沒收,同時扮成檢舉者領檢舉獎金。不過另一方面,即便需要信任對方,不需要自己跑一個 full node 就能用自己的錢賺利潤仍是很有吸引力的。總之,中心化和去中心化間的平衡需要經驗累積,也只有等到系統真的上線一段時間了才有辦法得到答案。但配上 sharding 之後,我們預計會更進一步降低中心化,因為 (i)需要考量的變化更少且 (ii)在 sharding 模型中,驗證交易的負擔和所投入的資本成正比,所以並不會因為組成礦池而節省成本支出。 - -最後一點是,中心化在權益證明機制中比其在工作量證明機制中的負面影響更小,因為從 51% 攻擊中復原容易且便宜多了,也不需要換新的挖礦演算法。 - -### 權益證明機制 能被用在私有鏈或聯盟鏈嗎? - -一般來說是可以的。任何權益證明機制演算法都可以被私有鏈或聯盟鏈用做一個共識演算法。唯一不同是成為驗證者的方式:一開始會由一群大家同意且信任的使用者成為驗證者,接著再由這群驗證者透過投票去加入新的驗證者。 \ No newline at end of file diff --git "a/[\344\270\255\346\226\207]-\347\275\221\347\273\234\347\212\266\346\200\201.md" "b/[\344\270\255\346\226\207]-\347\275\221\347\273\234\347\212\266\346\200\201.md" deleted file mode 100644 index 15cf5f2d5..000000000 --- "a/[\344\270\255\346\226\207]-\347\275\221\347\273\234\347\212\266\346\200\201.md" +++ /dev/null @@ -1,93 +0,0 @@ ---- -name: Network Status -category: ---- - -Special thanks to Kyle Chen for translation. - -# 网络状态监控 - -以太坊(中心化的)网络状态监控器 (有时被称为“eth-netstats”),是一个基于网页的应用程序,通过一组节点去监控测试链或者主链的健康状态。 - -### 登记你的节点 - -要登记你的节点,你必须安装客户端的信息中继器,这是一个节点模块。这里给出的指示可以在Ubuntu Linux上使用(Mac OS X使用同样的指示,不过sudo指令可能不是必须的)。其他平台会有所变化(请确保nodejs-legacy也安装了,不然一些模块可能会失效。) - -用Git clone指令复制程序库,然后用install指令安装PM2 - - git clone https://github.com/cubedro/eth-net-intelligence-api - cd eth-net-intelligence-api - npm install - sudo npm install -g pm2 - -然后编辑里面的app.json文件去配置你的节点:\ - -* 修改LISTENING_PORT选项右边的数值,将其改成以太坊的监听端口(默认:30303) -* 修改 INSTANCE_NAME选项右边的数值,改成你想给节点起的名字; -* 如果你想修改联系信息,将CONTACT_DETAILS选项右边的值改动 -* 修改RPC_PORT选项右边的数值,改成你的节点的RPC端口(在cpp和go的版本中都是默认8545的端口); -* 修改WS_SECRET选项右边的值,改成密令secret(你必须从官方的Skype联系渠道)获得 - -最后用以下的指令去运行进程: - - pm2 start app.json - -一些指令是可用的: - -* pm2 list 以显示进程状态; -* pm2 logs 以显示记录; -* pm2 gracefulReload node-app 以用于软重启; -* pm2 stop node-app 以停止应用程序; -* pm2 kill 以停止后台进程. - -### 升级 - -如果想升级的话,需要根据以下步骤进行: - -* git pull 以获取最新的版本 -* sudo npm update 以更新程序依赖库 -* pm2 gracefulReload node-app以重新载入客户端 - -## 在一个干净的Ubuntu系统里自动安装 - -获取和运行build shell。这会安装你需要的所有东西:在develop开发分支(你可以选eth或者geth)里面的ethereum – CLI, node.js, npm & pm2. - - bash <(curl https://raw.githubusercontent.com/cubedro/eth-net-intelligence-api/master/bin/build.sh) - -### 配置 - -通过修改processes.json配置应用程序。注意你必须修改 ./bin/processes.json,这是processes.json的备份。(以让你可以设置环境变量,而不需要在更新的时候重写它) - - "env": - { - "NODE_ENV" : "production", //告诉客户端我们在生产环境 - "RPC_HOST" : "localhost", // eth JSON-RPC Host,默认是8545 - "RPC_PORT" : "8545", // eth JSON-RPC 端口 - "LISTENING_PORT" : "30303", // eth监听端口(只用于显示) - "INSTANCE_NAME" : "", // 你想给节点起的名字 - "CONTACT_DETAILS" : "", //如果你想的话可以在这里加入你的联系信息,如电子邮件或skype - "WS_SERVER" : "wss://stats.ethdev.com", //eth-netstats WebSockets api服务器的路径 - "WS_SECRET" : "", // 用于登陆的WebSockets api 服务器密令secret } - -## 运行 - -使用pm2运行: - - cd ~/bin - pm2 start processes.json - -以太坊(eth或者geth)必须在允许rpc选项的情况下运行: - - geth --rpc - -在geth下,默认的rpc端口(如果没有指定的话)是8545 - -## 升级 - -要升级API客户端的话就要使用如下的命令: - - ~/bin/www/bin/update.sh - -这会停止当前的netstats客户端进程,自动检测你的以太坊的安装状态和版本,升级到最新的开发者版本,更新netstats客户端并重新载入进程。 - - diff --git a/_Sidebar.md b/_Sidebar.md deleted file mode 100644 index be20b8059..000000000 --- a/_Sidebar.md +++ /dev/null @@ -1,75 +0,0 @@ -### Basics -- [Home](https://github.com/ethereum/wiki/wiki/) -- [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) -- [FAQ](https://github.com/ethereum/wiki/wiki/FAQ) - -### Ðapp Development -- [Ðapp Developer Resources](https://github.com/ethereum/wiki/wiki/Dapp-Developer-Resources) -- [JavaScript API](https://github.com/ethereum/wiki/wiki/JavaScript-API) -- [JSON RPC API](https://github.com/ethereum/wiki/wiki/JSON-RPC) -- [Solidity](https://ethereum.github.io/solidity/docs/home/) -- [Solidity Features](https://github.com/ethereum/wiki/wiki/Solidity-Features) -- [Useful Ðapp Patterns](https://github.com/ethereum/wiki/wiki/Useful-Ðapp-Patterns) -- [Standardized Contract APIs](https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs) -- [Ðapp using Meteor](https://github.com/ethereum/wiki/wiki/Dapp-using-Meteor) -- [Ethereum development tutorial](https://github.com/ethereum/wiki/wiki/Ethereum-Development-Tutorial) -- [Mix Tutorial](https://github.com/ethereum/wiki/wiki/Mix:-The-DApp-IDE) -- [Mix Features](https://github.com/ethereum/wiki/wiki/Mix-Features) -- [Serpent](https://github.com/ethereum/wiki/wiki/Serpent) -- [LLL](https://github.com/ethereum/cpp-ethereum/wiki/LLL) -- [Mutan](https://github.com/obscuren/mutan) - -### ÐΞV Technologies -- [RLP Encoding](https://github.com/ethereum/wiki/wiki/RLP) -- [RLPx Node Discovery Protocol](https://github.com/ethereum/wiki/wiki/Node-discovery-protocol-(RLPx)) -- [ÐΞVp2p Wire Protocol](https://github.com/ethereum/wiki/wiki/%C3%90%CE%9EVp2p-Wire-Protocol) -- [ÐΞVp2p Whitepaper](https://github.com/ethereum/wiki/wiki/libp2p-Whitepaper) (WiP) -- [Web3 Secret Storage](https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition) - -### Ethereum Technologies -- [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) -- [Subtleties](https://github.com/ethereum/wiki/wiki/Subtleties) -- [Solidity, Docs & ABI](https://github.com/ethereum/wiki/wiki/Solidity,-Docs-and-ABI) -- [NatSpec Format](https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format) -- [Contract ABI](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI) -- [Bad Block Reporting](http://github.com/ethereum/wiki/wiki/Bad-Block-Reporting) -- [Bad Chain Canary](http://github.com/ethereum/wiki/wiki/Bad-Chain-Canary) -- [Extra Data](http://github.com/ethereum/wiki/wiki/Extra-Data) -- [Brain Wallet](https://github.com/ethereum/wiki/wiki/Brain-Wallet) - -### Ethash/Dashimoto -- [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) - -### Infrastructure Development -- [Morden](https://github.com/ethereum/wiki/wiki/Morden) -- [Inter-exchange Client Address Protocol](https://github.com/ethereum/wiki/wiki/ICAP:-Inter-exchange-Client-Address-Protocol) -- [URL Hint Protocol](https://github.com/ethereum/wiki/wiki/URL-Hint-Protocol) -- [NatSpec Determination](https://github.com/ethereum/wiki/wiki/NatSpec-Determination) -- [Exchange Integration](https://github.com/ethereum/wiki/wiki/Exchange-Integration) -- [Mining](https://github.com/ethereum/wiki/wiki/Mining) -- [Licensing](https://github.com/ethereum/wiki/wiki/Licensing) -- [Network Status](https://github.com/ethereum/wiki/wiki/Network-Status) -- [Raspberry Pi](https://github.com/ethereum/wiki/wiki/Raspberry-Pi-instructions) - -### Ethereum Clients -- [AlethZero (C++)](https://github.com/ethereum/wiki/wiki/AlethZero) -- [Mist (Go)](https://github.com/ethereum/wiki/wiki/Ethereal) -- [pyeth (Python)](https://github.com/ethereum/wiki/wiki/Pyeth) - -### Concerning Whisper -- [Whisper Proposal](https://github.com/ethereum/wiki/wiki/Whisper) -- [Whisper Overview](https://github.com/ethereum/wiki/wiki/Whisper-Overview) -- [PoC-1 Wire protocol](https://github.com/ethereum/wiki/wiki/Whisper-Wire-Protocol) -- [PoC-2 Wire protocol](https://github.com/ethereum/wiki/wiki/Whisper-PoC-2-Wire-Protocol) -- [PoC-2 Whitepaper](https://github.com/ethereum/wiki/wiki/Whisper-PoC-2-Protocol-Spec) - -### Misc -- [Hard Problems of Cryptocurrency](https://github.com/ethereum/wiki/wiki/Problems) -- [Chain Fibers](https://github.com/ethereum/wiki/wiki/Chain-Fibers-Redux) -- [Glossary](https://github.com/ethereum/wiki/wiki/Glossary) \ No newline at end of file diff --git a/drafts/[english]-old-ethereum-whitepaper.md b/drafts/[english]-old-ethereum-whitepaper.md deleted file mode 100644 index 939ca7ff1..000000000 --- a/drafts/[english]-old-ethereum-whitepaper.md +++ /dev/null @@ -1,639 +0,0 @@ ---- -name: Old Ethereum Whitepaper -category: ---- - -### A Next-Generation Smart Contract and Decentralized Application Platform - -In the last few months, there has been a great amount of interest into the area of using Bitcoin-like blockchains - the mechanism that allows for the entire world to agree on the state of a public ownership database - for more than just money. Commonly cited applications include using on-blockchain digital assets to represent custom currencies and financial instruments (["colored coins"](https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit)), ["smart property"](https://en.bitcoin.it/wiki/Smart_Property) devices such as cars which track a colored coin on a blockchain to determine their present legitimate owner, as well as more advanced applications such as decentralized exchange, financial derivatives, peer-to-peer gambling and on-blockchain identity and reputation systems. Perhaps the most ambitious of all cited applications is the concept of autonomous agents or [decentralized autonomous organizations](http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/) (DAOs) - autonomous entities that operate on the blockchain without any central control whatsoever, eschewing all dependence on legal contracts and organizational bylaws in favor of having resources and funds autonomously managed by a self-enforcing smart contract on a cryptographic blockchain. - -However, most of these applications are difficult to implement today, simply because the scripting systems of Bitcoin, and even next-generation cryptocurrency protocols such as the Bitcoin-based colored coins protocol and so-called "metacoins", are far too limited to allow the kind of arbitrarily complex computation that DAOs require. What this project intends to do is take the innovations that such protocols bring, and generalize them - create a fully-fledged, Turing-complete (but heavily fee-regulated) cryptographic ledger that allows participants to encode arbitrarily complex contracts, autonomous agents and relationships that will be mediated entirely by the blockchain. Rather than being limited to a specific set of transaction types, users will be able to use Ethereum as a sort of "Lego of crypto-finance" - that is to say, one will be able to implement any feature that one desires simply by coding it in the protocol's internal scripting language. Custom currencies, financial derivatives, identity systems and decentralized organizations will all be easy to do, but more importantly, unlike previous systems, it will also be possible to construct transaction types that even the Ethereum developers did not imagine. Altogether, we believe that this design is a solid step toward the realization of "cryptocurrency 2.0"; we hope that Ethereum will be as significant an addition to the cryptocurrency ecosystem as the advent of Web 2.0 was to the static-content-only internet of 1999. - - -### Table of Contents - -* [Why A New Platform](#why-a-new-platform) - * [Colored Coins](#colored-coins) - * [Metacoins](#metacoins) -* [Philosophy](#philosophy) -* [Basic Building Blocks](#basic-building-blocks) - * [Modified GHOST Implementation](#modified-ghost-implementation) - * [Ethereum Client P2P Protocol](#ethereum-client-p2p-protocol) - * [Currency and Issuance](#currency-and-issuance) - * [Data Format](#data-format) - * [Mining Algorithm](#mining-algorithm) - * [Transactions](#transactions) - * [Difficulty Adjustment](#difficulty-adjustment) - * [Block Rewards and Limits](#block-rewards-and-limits) -* [Contracts](#contracts) - * [Applications](#applications) - * [Sub-currencies](#sub-currencies) - * [Financial derivatives](#financial-derivatives) - * [Identity and Reputation Systems](#identity-and-reputation-systems) - * [Decentralized File Storage](#decentralized-file-storage) - * [Decentralized Autonomous Organizations](#decentralized-autonomous-organizations) - * [Further Applications](#further-applications) - * [How Do Contracts Work?](#how-do-contracts-work) - * [Language Specification](#language-specification) -* [Fees](#fees) -* [Conclusion](#conclusion) -* [References and Further Reading](#references-and-further-reading) - - -## Why A New Platform? - -When one wants to create a new application, especially in an area as delicate as cryptography or cryptocurrency, the immediate, and correct, first instinct is to use existing protocols as much as possible. There is no need to create a new currency, or even a new protocol, when the problem can be solved entirely by using existing technologies. Indeed, the puzzle of attempting to solve the problems of [smart property](https://en.bitcoin.it/wiki/Smart_Property), [smart contracts](https://en.bitcoin.it/wiki/Contracts) and [decentralized autonomous corporations](http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/) on top of Bitcoin is how our interest in next-generation cryptocurrency protocols originally started. Over the course of our research, however, it became evident that while the Bitcoin protocol is more than adequate for currency, basic multisignature escrow and certain simple versions of smart contracts, there are fundamental limitations that make it non-viable for anything beyond a certain very limited scope of features. - - -### Colored Coins - -The first attempt to implement a system for managing smart property and custom currencies and assets on top of a blockchain was built as a sort of overlay protocol on top of Bitcoin, with many advocates making a comparison to the way that, in the [internet protocol stack](http://en.wikipedia.org/wiki/Internet_protocol_suite), [HTTP](http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol) serves as a layer on top of [TCP](http://en.wikipedia.org/wiki/Transmission_Control_Protocol). The [colored coins](https://docs.google.com/a/ursium.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit) protocol is roughly defined as follows: - -1. A colored coin issuer determines that a given transaction output H:i (H being the transaction hash and `i` the output index) represents a certain asset, and publishes a "color definition" specifying this transaction output alongside what it represents (eg. 1 satoshi from `H:i` = 1 ounce of gold redeemable at Stephen's Gold Company) -2. Others "install" the color definition file in their colored coin clients. -3. When the color is first released, output H:i is the only transaction output to have that color. -4. If a transaction spends inputs with color X, then its outputs will also have color X. For example, if the owner of H:i immediately makes a transaction to split that output among five addresses, then those transaction outputs will all also have color X. If a transaction has inputs of different colors, then a "color transfer rule" or "color kernel" determines which colors which outputs are (eg. a very naive implementation may say that output 0 has the same color as input 0, output 1 the same color as input 1, etc). -5. When a colored coin client notices that it received a new transaction output, it uses a back-tracing algorithm based on the color kernel to determine the color of the output. Because the rule is deterministic, all clients will agree on what color (or colors) each output has. - -However, the protocol has several fundamental flaws: - - -**Simplified Payment Verification in Bitcoin ** - -![SPV in bitcoin](https://www.ethereum.org/gh_wiki/spv_bitcoin.png) - -_Left: it suffices to present only a small number of nodes in a Merkle tree to give a proof of the validity of a branch._ - -_Right: any attempt to change any part of the Merkle tree will eventually lead to an inconsistency somewhere up the chain._ - - -1. **Difficulty of simplified payment verification** - Bitcoin's [Merkle Tree](http://en.wikipedia.org/wiki/Merkle_tree) construction allows for a protocol known as "[simplified payment verification](https://en.bitcoin.it/wiki/Scalability#Simplified_payment_verification)", where a client that does not download the full blockchain can quickly determine the validity of a transaction output by asking other nodes to provide a cryptographic proof of the validity of a single branch of the tree. The client will still need to download the block headers to be secure, but the amount of data bandwidth and verification time required drops by a factor of nearly a thousand. With colored coins, this is much harder. The reason is that one cannot determine the color of a transaction output simply by looking up the Merkle tree; rather, one needs to employ the backward scanning algorithm, fetching potentially thousands of transactions and requesting a Merkle tree validity proof of each one, before a client can be fully satisfied that a transaction has a certain color. After over a year of investigation, including help from ourselves, no solution has been found to this problem. -2. **Incompatibility with scripting** - as mentioned above, Bitcoin does have a moderately flexible scripting system, for example allowing users to sign transactions of the form "I release this transaction output to anyone willing to pay to me 1 BTC". Other examples include [assurance contracts](http://en.wikipedia.org/wiki/Assurance_contract), [efficient micropayments](https://en.bitcoin.it/wiki/Contracts#Example_7:_Rapidly-adjusted_.28micro.29payments_to_a_pre-determined_party) and on-blockchain auctions. However, this system is inherently not color-aware; that is to say, one cannot make a transaction of the form "I release this transaction output to anyone willing to pay me one gold coin defined by the genesis H:i", because the scripting language has no idea that a concept of "colors" even exists. One major consequence of this is that, while trust-free swapping of two different colored coins is possible, a full decentralized exchange is not since there is no way to place an enforceable order to buy or sell. -3. **Same limitations as Bitcoin** - ideally, on-blockchain protocols would be able to support advanced derivatives, bets and many forms of conditional transfers. Unfortunately, colored coins inherits the limitations of Bitcoin in terms of the impossibility of many such arrangements. - -### Metacoins - -Another concept, once again in the spirit of sitting on top of Bitcoin much like HTTP over TCP, is that of "metacoins". The concept of a metacoin is simple: the metacoin protocol provides for a way of encoding metacoin transaction data into the outputs of a Bitcoin transaction, and a metacoin node works by processing all Bitcoin transactions and evaluating Bitcoin transactions that are valid metacoin transactions in order to determine the current account balances at any given time. For example, a simple metacoin protocol might require a transaction to have four outputs: MARKER, FROM, TO and VALUE. MARKER would be a specific marker address to identify a transaction as a metacoin transaction. FROM would be the address that coins are sent from. `TO` would be the address that coins are sent to, and VALUE would be an address encoding the amount sent. Because the Bitcoin protocol is not metacoin-aware, and thus will not reject invalid metacoin transactions, the metacoin protocol must treat all transactions with the first output going to MARKER as valid and react accordingly. For example, an implementation of the transaction processing part of the above described metacoin protocol might look like this: - - if tx.output[0] != MARKER: - break - else if balance[tx.output[1]] < decode_value(tx.output[3]): - break - else if not tx.hasSignature(tx.output[1]): - break - else: - balance[tx.output[1]] -= decode_value(tx.output[3]); - balance[tx.output[2]] += decode_value(tx.output[3]); - - -The advantage of a metacoin protocol is that the protocol can allow for more advanced transaction types, including custom currencies, decentralized exchange, derivatives, etc, that are impossible to implement using the underlying Bitcoin protocol by itself. However, metacoins on top of Bitcoin have one major flaw: simplified payment verification, already difficult with colored coins, is outright impossible on a metacoin. The reason is that while one can use SPV to determine that there is a transaction sending 30 metacoins to address X, that by itself does not mean that address X has 30 metacoins. What if the sender of the transaction did not have 30 metacoins to start with and so the transaction is invalid? Ultimately, finding out any part of the current state requires scanning through all transactions since the metacoin's original launch to figure out which transactions are valid and which ones are not. This makes it impossible to have a truly secure client without downloading the entire, arguably prohibitively large, Bitcoin blockchain. - -In both cases, the conclusion is as follows. The effort to build more advanced protocols on top of Bitcoin, like HTTP over TCP, is admirable, and is indeed the correct way to go in terms of implementing advanced decentralized applications. However, the attempt to build colored coins and metacoins on top of Bitcoin is more like building HTTP over SMTP. The intention of SMTP was to transfer email messages, not serve as a backbone for generic internet communications, and one would have had to implement many inefficient and architecturally ugly practices in order to make it effective. Similarly, while Bitcoin is a great protocol for making simple transactions and storing value, the evidence above shows that Bitcoin is absolutely not intended to function, and cannot function, as a base layer for financial peer-to-peer protocols in general. - -Ethereum solves the scalability issues by being hosted on its own blockchain, and by storing a distinct "state tree" in each block along with a transaction list. Each "state tree" represents the current state of the entire system, including address balances and contract states. Ethereum contracts are allowed to store data in a persistent memory storage. This storage, combined with the Turing-complete scripting language, allows us to encode an entire currency inside of a single contract, alongside countless other types of cryptographic assets. Thus, the intention of Ethereum is not to replace the colored coins and metacoin protocols described above. Rather, Ethereum intends to serve as a superior foundational layer offering a uniquely powerful scripting system on top of which arbitrarily advanced contracts, currencies and other decentralized applications can be built. If existing colored coins and metacoin projects were to move onto Ethereum, they would gain the benefits of Ethereum's simplified payment verification, the option to be compatible with Ethereum's financial derivatives and decentralized exchange, and the ability to work together on a single network. With Ethereum, someone with an idea for a new contract or transaction type that might drastically improve the state of what can be done with cryptocurrency would not need to start their own coin; they could simply implement their idea in Ethereum script code. In short, Ethereum is a foundation for innovation. - - -## Philosophy - -The design behind Ethereum is intended to follow the following principles: - -1. **Simplicity** - the Ethereum protocol should be as simple as possible, even at the cost of some data storage or time inefficiency. An average programmer should ideally be able to follow and implement the entire specification, so as to fully realize the unprecedented democratizing potential that cryptocurrency brings and further the vision of Ethereum as a protocol that is open to all. Any optimization which adds complexity should not be included unless that optimization provides very substantial benefit. -2. **Universality** - a fundamental part of Ethereum's design philosophy is that Ethereum does not have "features". Instead, Ethereum provides an internal Turing-complete scripting language, which a programmer can use to construct any smart contract or transaction type that can be mathematically defined. Want to invent your own financial derivative? With Ethereum, you can. Want to make your own currency? Set it up as an Ethereum contract. Want to set up a full-scale Daemon or Skynet? You may need to have a few thousand interlocking contracts, and be sure to feed them generously, to do that, but nothing is stopping you with Ethereum at your fingertips. -3. **Modularity** - the parts of the Ethereum protocol should be designed to be as modular and separable as possible. Over the course of development, our goal is to create a program where if one was to make a small protocol modification in one place, the application stack would continue to function without any further modification. Innovations such as [Dagger](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Dagger), [Patricia trees](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree) and [RLP](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP) should be implemented as separate libraries and made to be feature-complete even if Ethereum does not require certain features so as to make them usable in other protocols as well. Ethereum development should be maximally done so as to benefit the entire cryptocurrency ecosystem, not just itself. -4. **Agility** - details of the Ethereum protocol are not set in stone. Although we will be extremely judicious about making modifications to high-level constructs such as the [C-like language](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-CLL) and the address system, computational tests later on in the development process may lead us to discover that certain modifications to the algorithm or scripting language will substantially improve scalability or security. If any such opportunities are found, we will exploit them. -5. **Non-discrimination** - the protocol should not attempt to actively restrict or prevent specific categories of usage. All regulatory mechanisms in the protocol should be designed to directly regulate the harm and not attempt to oppose specific undesirable applications. A programmer can even run an infinite loop script on top of Ethereum for as long as they are willing to keep paying the per-computational-step transaction fee. - - -## Basic Building Blocks - -At its core, Ethereum starts off as a fairly regular memory-hard proof-of-work mined cryptocurrency without many extra complications. In fact, Ethereum is in some ways simpler than the Bitcoin-based cryptocurrencies that we use today. The concept of a transaction having multiple inputs and outputs, for example, is gone, replaced by a more intuitive balance-based model (to prevent transaction replay attacks, as part of each account balance we also store an incrementing nonce). Sequence numbers and lock times are also removed, and all transaction and block data is encoded in a single format. Instead of addresses being the RIPEMD160 hash of the SHA256 hash of the public key prefixed with 04, addresses are simply the last 20 bytes of the SHA3 hash of the public key. Unlike other cryptocurrencies, which aim to offer a large number of "features", Ethereum intends to take features away, and instead provide its users with near-infinite power through an all-encompassing mechanism known as "contracts". - -### Modified GHOST Implementation - -The "Greedy Heavist Observed Subtree" (GHOST) protocol is an innovation first introduced by Yonatan Sompolinsky and Aviv Zohar in [December 2013](http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf). The motivation behind GHOST is that blockchains with fast confirmation times currently suffer from reduced security due to a high stale rate - because blocks take a certain time to propagate through the network, if miner A mines a block and then miner B happens to mine another block before miner A's block propagates to B, miner B's block will end up wasted and will not contribute to network security. Furthermore, there is a centralization issue: if miner A is a mining pool with 30% hashpower and B has 10% hashpower, A will have a risk of producing stale blocks 70% of the time whereas B will have a risk of producing stale blocks 90% of the time. Thus, if the stale rate is high, A will be substantially more efficient simply by virtue of its size. With these two effects combined, blockchains which produce blocks quickly are very likely to lead to one mining pool having a large enough percentage of the network hashpower to have de facto control over the mining process. - -As described by Sompolinsky and Zohar, GHOST solves the first issue of network security loss by including stale blocks in the calculation of which chain is the "longest"; that is to say, not just the parent and further ancestors of a block, but also the stale descendants of the block's ancestor (in Ethereum jargon, "uncles") are added to the calculation of which block has the largest total proof of work backing it. To solve the second issue of centralization bias, we go beyond the protocol described by Sompolinsky and Zohar, and also provide block rewards to stales: a stale block receives 87.5% of its base reward, and the nephew that includes the stale block receives the remaining 12.5%. Transaction fees, however, are not awarded to uncles. - -Ethereum implements a simplified version of GHOST which only goes down one level. Specifically, a stale block can only be included as an uncle by the direct child of one of its direct siblings, and not any block with a more distant relation. This was done for several reasons. First, unlimited GHOST would include too many complications into the calculation of which uncles for a given block are valid. Second, unlimited GHOST with compensation as used in Ethereum removes the incentive for a miner to mine on the main chain and not the chain of a public attacker. Finally, calculations show that single-level GHOST has over 80% of the benefit of unlimited GHOST, and provides a stale rate comparable to the 2.5 minute Litecoin even with a 40-second block time. However, we will be conservative and still retain a Primecoin-like 60-second block time because individual blocks may take a longer time to verify. - - -### Ethereum Client P2P Protocol - -**P2P Protocol** -![SPV in bitcoin](https://www.ethereum.org/gh_wiki/minerchart.png) - -The Ethereum client P2P protocol is a fairly standard cryptocurrency protocol, and can just as easily be used for any other cryptocurrency; the only modification is the introduction of the GHOST protocol described above. The Ethereum client will be mostly reactive; if not provoked, the only thing the client will do by itself is have the networking daemon maintain connections and periodically send a message asking for blocks whose parent is the current block. However, the client will also be more powerful. Unlike bitcoind, which only stores a limited amount of data about the blockchain, the Ethereum client will also act as a fully functional backend for a block explorer. - -When the client reads a message, it will perform the following steps: - -1. Hash the data, and check if the data with that hash has already been received. If so, exit. -2. Determine the data type. If the data is a transaction, if the transaction is valid add it to the local transaction list, process it onto the current block and publish it to the network. If the data item is a message, respond to it. If the data item is a block, go to step 3. -3. Check if the parent of the block is already stored in the database. If it is not, exit. -4. Check if the proof of work on the block header and all block headers in the "uncle list" is valid. If any are not, exit. -5. Check if every block header in the "uncle list" in the block has the block's parent's parent as its own parent. If any is not, exit. Note that uncle block headers do not need to be in the database; they just need to have the correct parent and a valid proof of work. Also, make sure that uncles are unique and distinct from the parent. -6. Check if the timestamp of the block is at most 15 minutes into the future and that it is ahead of the timestamp of the parent. Check if the difficulty of the block and the block number are correct. If either of these checks fails, exit. -7. Start with the state of the parent of the block, and sequentially apply every transaction in the block to it. At the end, add the miner rewards. If the root hash of the resulting state tree does not match the state root in the block header, exit. If it does, add the block to the database and advance to the next step. -8. Determine TD(block) ("total difficulty") for the new block. TD is defined recursively by TD(genesis_block) = 0 and TD(B) = TD(B.parent) + sum([u.difficulty for u in B.uncles]) + B.difficulty. If the new block has higher TD than the current block, set the current block to the new block and continue to the next step. Otherwise, exit. -9. If the new block was changed, apply all transactions in the transaction list to it, discarding from the transaction list any that turn out to be invalid, and rebroadcast the block and those transactions to the network. - -The "current block" is a pointer maintained by each node that refers to the block that the node deems as representing the current official state of the network. All messages asking for balances, contract states, etc, have their responses computed by looking at the current block. If a node is mining, the process is only slightly changed: while doing all of the above, the node also continuously mines on the current block, using its transaction list as the transaction list of the block. - - -### Currency and Issuance - -The Ethereum network includes its own built-in currency, ether. The main reason for including a currency in the network is twofold. First, like Bitcoin, ether is rewarded to miners so as to incentivize network security. Second, it serves as a mechanism for paying transaction fees for anti-spam purposes. Of the two main alternatives to fees, per-transaction proof of work similar to [Hashcash](http://en.wikipedia.org/wiki/Hashcash) and zero-fee laissez-faire, the former is wasteful of resources and unfairly punitive against weak computers and smartphones and the latter would lead to the network being almost immediately overwhelmed by an infinitely looping "logic bomb" contract. For convenience and to avoid future argument (see the current mBTC/uBTC/satoshi debate), the denominations will be pre-labelled: - -* 1: wei -* 10^3: lovelace -* 10^6: babbage -* 10^9: turing -* 10^12: szabo -* 10^15: finney -* 10^18: ether - -This should be taken as an expanded version of the concept of "dollars" and "cents" or "BTC" and "satoshi" that is intended to be future proof. In the near future, we expect "ether" to be the primary unit in the system, much like the dollar or bitcoin; "finney" will likely be used for microtransactions, "szabo" for per-step fees and "wei" to refer specifically to the lowest-level "base" unit much like the satoshi in Bitcoin. The remaining denominations will likely only come into play if Ethereum grows much larger or computers get much more efficient and it makes sense to use lower units than szabo to measure fees. - -The issuance model will be as follows: - -* Ether will be released in a fundraiser at the price of 1000-2000 ether per BTC, with earlier funders getting a better price to compensate for the increased uncertainty of participating at an earlier stage. The minimum funding amount will be 0.01 BTC. Suppose that X ether gets released in this way -* 0.225X ether will be allocated to the fiduciary members and early contributors who substantially participated in the project before the start of the fundraiser. This share will be stored in a time-lock contract; about 40% of it will be spendable after one year, 70% after two years and 100% after 3 years. -* 0.05X ether will be allocated to a fund to use to pay expenses and rewards in ether between the start of the fundraiser and the launch of the currency -* 0.225X ether will be allocated as a long-term reserve pool to pay expenses, salaries and rewards in ether after the launch of the currency -* 0.4X ether will be mined per year forever after that point - - -| Group | After 1 year | After 5 years -| ------------- | ------------- |-------------| -| Currency units | 1.9X | 3.5X | -| Fundraiser participants | 52.6% | 28.6% | -| Fiduciary members and early contributors | 11.8% | 6.42% | -| Additional pre-launch allocations | 2.63% | 1.42% | -| Reserve | 11.8% | 6.42% | -| Miners | 21.1% | 57.1% | - - -**Long-Term Inflation Rate (percent)** - -![SPV in bitcoin](https://www.ethereum.org/gh_wiki/inflation.svg) - -_Despite the linear currency issuance, just like with Bitcoin over time the inflation rate nevertheless tends to zero_ - - -For example, after five years and assuming no transactions, 28.6% of the ether will be in the hands of the fundraiser participants, 6.42% in the fiduciary member and early contributor pool, 6.42% paid to the reserve pool, and 57.1% will belong to miners. The permanent linear inflation model reduces the risk of what some see as excessive wealth concentration in Bitcoin, and gives individuals living in present and future eras a fair chance to acquire currency units, while at the same time retaining a strong incentive to obtain and hold ether because the inflation "rate" still tends to zero over time (eg. during year 1000001 the money supply would increase from 500001.5 * X to 500002 * X, an inflation rate of 0.0001%). Furthermore, much of the interest in Ethereum will be medium-term; we predict that if Ethereum succeeds it will see the bulk of its growth on a 1-10 year timescale, and supply during that period will be very much limited. - -We also theorize that because coins are always lost over time due to carelessness, death, etc, and coin loss can be modeled as a percentage of the total supply per year, that the total currency supply in circulation will in fact eventually stabilize at a value equal to the annual issuance divided by the loss rate (eg. at a loss rate of 1%, once the supply reaches 40X then 0.4X will be mined and 0.4X lost every year, creating an equilibrium). - - -### Data Format - -All data in Ethereum will be stored in [recursive length prefix encoding](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP), which serializes arrays of strings of arbitrary length and dimension into strings. For example, ['dog', 'cat'] is serialized (in byte array format) as [ 130, 67, 100, 111, 103, 67, 99, 97, 116]; the general idea is to encode the data type and length in a single byte followed by the actual data (eg. converted into a byte array, 'dog' becomes [ 100, 111, 103 ], so its serialization is [ 67, 100, 111, 103 ]. Note that RLP encoding is, as suggested by the name, recursive; when RLP encoding an array, one is really encoding a string which is the concatenation of the RLP encodings of each of the elements. Additionally, note that block number, timestamp, difficulty, memory deposits, account balances and all values in contract storage are integers, and Patricia tree hashes, root hashes, addresses, transaction list hashes and all keys in contract storage are strings. The main difference between the two is that strings are stored as fixed-length data (20 bytes for addresses, 32 bytes for everything else), and integers take up only as much space as they need. Integers are stored in big-endian base 256 format (eg. 32767 in byte array format as [ 127, 255 ]). - -A full block is stored as: - - [ - block_header, - transaction_list, - uncle_list - ] - -Where: - - transaction_list = [ - transaction 1, - transaction 2, - ... - ] - - uncle list = [ - uncle_block_header_1, - uncle_block_header_2, - ... - ] - - block_header = [ - parent hash, - sha3(rlp_encode(uncle_list)), - coinbase address, - state_root, - sha3(rlp_encode(transaction_list)), - difficulty, - timestamp, - extra_data, - nonce - ] - -Each transaction and uncle block header is itself a list. The data for the proof of work is the RLP encoding of the block WITHOUT the nonce. `uncle_list` and `transaction_list` are the lists of the uncle block headers and transactions in the block, respectively. `nonce` and `extra_data` are both limited to a maximum of 32 bytes, except the genesis block where the `extra_data` parameter will be much larger. - -The `state_root` is the root of a [Merkle Patricia tree](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree) containing (key, value) pairs for all accounts where each address is represented as a 20-byte binary string. At the address of each account, the value stored in the Merkle Patricia tree is a string which is the RLP-serialized form of an object of the form: - - [ balance, nonce, contract_root ] - -The nonce is the number of transactions made from the account, and is incremented every time a transaction is made. The purpose of this is to (1) make each transaction valid only once to prevent replay attacks, and (2) to make it impossible (more precisely, cryptographically infeasible) to construct a contract with the same hash as a pre-existing contract. `balance` refers to the account's balance, denominated in wei. `contract_root` is the root of yet another Patricia tree, containing the contract's memory, if that account is controlled by a contract. If an account is not controlled by a contract, the contract root will simply be the empty string. - -### Mining algorithm - -One highly desirable property in mining algorithms is resistance to optimization through specialized hardware. Originally, Bitcoin was conceived as a highly democratic currency, allowing anyone to participate in the mining process with a CPU. In 2010, however, much faster miners exploiting the rapid parallelization offered by graphics processing units (GPUs) rapidly took over, increasing network hashpower by a factor of 100 and leaving CPUs essentially in the dust. In 2013, a further category of specialized hardware, application-specific integrated circuits (ASICs) outcompeted the GPUs in turn, achieving another 100x speedup by using chips fabricated for the sole purpose of computing SHA256 hashes. Today, it is virtually impossible to mine without first purchasing a mining device from one of these companies, and some people are concerned that in 5-10 years' time mining will be entirely dominated by large centralized corporations such as AMD and Intel. - -To date, the main way of achieving this goal has been "memory-hardness", constructing proof of work algorithms that require not only a large number of computations, but also a large amount of memory, to validate, thereby making highly parallelized specialized hardware implementations less effective. There have been several implementations of memory-hard proof of work, all of which have their flaws: - -* **Scrypt** - Scrypt is a function which is designed to take 128 KB of memory [to compute](https://litecoin.info/User:Iddo/Comparison_between_Litecoin_and_Bitcoin#SHA256_mining_vs_scrypt_mining). The algorithm essentially works by filling a memory array with hashes, and then computing intermediate values and finally a result based on the values in the memory array. However, the 128 KB parameter is a very weak threshold, and ASICs for Litecoin are [already under development](https://axablends.com/merchants-accepting-bitcoin/litecoin-discussion/litecoin-scrypt-asic-miners/). Furthermore, there is a natural limit to how much memory hardness with Scrypt can be tweaked up to achieve, as the verification process takes just as much memory, and just as much computation, as one round of the mining process. -* **Birthday attacks** - the idea behind birthday-based proofs of work is simple: find values xn, i, j such that i < k, j < k and abs(H(data+xn+i) - H(data+xn+j)) < 2^256 / d^2. The d parameter sets the computational difficulty of finding a block, and the k parameter sets the memory hardness. Any birthday algorithm must somehow store all computations of H(data+xn+i) in memory so that future computations can be compared against them. Here, computation is memory-hard, but verification is memory-easy, allowing for extreme memory hardness without compromising the ease of verification. However, the algorithm is problematic for two reasons. First, there is a time-memory tradeoff attack where users 2x less memory can compensate with 2x more computational power, so its memory hardness is not absolute. Second, it may be easy to build specialized hardware devices for the problem, especially once one moves beyond traditional chip and processor architecture and into various classes of hardware-based hash tables or probabilistic analog computing. -* **Dagger** - the idea behind [Dagger](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Dagger), an in-house algorithm developed by the Ethereum team, is to have an algorithm that is similar to Scrypt, but which is specially designed so that each individual nonce only depends on a small portion of the data tree that gets built up for each group of ~10 million nonces. Computing nonces with any reasonable level of efficiency requires building up the entire tree, taking up over 100 MB of memory, whereas verifying a nonce only takes about 100 KB. However, Dagger-style algorithms are vulnerable to devices that have multiple computational circuits sharing the same memory, and although this threat can be mitigated it is arguably impossible to fully remove. - -One of the key ingredients in a standard cryptocurrency is the idea of proof of work. A proof of work, in general, is a function which is hard to compute, but easy to verify, allowing it to serve as a probabilistic cryptographic proof of the quantity of computational resources controlled by a given node. In Bitcoin, and Ethereum, this mechanism is intimately tied in with the blockchain: every block requires a proof of work of some prespecified difficulty level in order to be valid, and in the event of multiple competing blockchains the chain with the largest total quantity of proof of work is considered to be valid. Thus, in order to reverse a transaction, an attacker needs to start a new fork of the blockchain from before the block the transaction was confirmed in, and then apply more computational power than the rest of the network combined in order to overtake the legitimate fork. - -However, one of the key requirements for a proof of work algorithm to, well, work is decentralization. If the proof of work algorithm is designed in such a way that the proof of work computation can only be efficiently done by entities with the millions of dollars of capital required to develop specialized hardware, then the number of participants in the process will be small enough that it will be possible for the majority of miners to conspire and reverse transactions. Alternatively, if the proof of work algorithm encourages miners to outsource their block verification work to centralized entities, then that is another way that centralization can creep in, and it would be the mining pools that have the potential to form conspiracies. Ideally, proof of work algorithms should solve both of those problems. - -#### Blockchain Based PoW Specification - -This mining algorithm is based on Adam Back's Hashcash, also used by Bitcoin. In Hashcash, we take a hash function `H` (assume 256-bit length) which takes as input data and a nonce and a difficulty parameter, and say that a valid nonce is one where `H(data,nonce) < 2^256 / difficulty`. Completing the proof of work essentially entails trying different nonces until one works, and verifying means applying the hash function to the data and nonce provided and making sure that the result is indeed below the target. In Bitcoin, `H` is a simple computation of `sha256(block_header + nonce)`. Here, however, `H` is much more complex, taking in as data not just the block header but also the state data and transactions from the last 16 blocks. - -In this early sketch of the mining algorithm, `H` is defined as follows: - -1. Let `h[i] = sha3(sha3(block_header) ++ nonce ++ i)` for `1 <= i <= 16` -2. Let `S` be the blockchain state 16 blocks ago. -3. Let `C[i]` be the transaction count of the block `i` blocks ago. Let `T[i]` be the `(h[i] mod C[i])`th transaction from the block `i` blocks ago. -4. Apply `T[0]`, `T[1]` … `T[15]` sequentially to `S`. However, every time the transaction leads to processing a contract, (pseudo-)randomly make minor modifications to the code of all contracts affected. -5. Let `S'` be the resulting state. Let `r` be the sha3 of the root of `S'`. - -#### Properties - -1. The algorithm is memory-hard; mining requires the miner to store the full state of the last 16 blocks in order to be able to query the blockchain. However, the algorithm is not sequentially memory-hard and is vulnerable to shared memory optimizations. -2. The algorithm requires every node to store the entire blockchain state and be able to process transactions. Furthermore, as new blocks are created, it will likely be more efficient to generate the new blockchain state by computing it rather than by asking for and downloading the missing Patricia tree nodes. Hence, there is no reason why a miner would not want to be a full node. -3. The EVM (Ethereum Virtual Machine) code is Turing-complete. Hence, an ASIC that performs transaction processing vastly more efficiently than existing CPUs would necessarily be a general-purpose computing device vastly more efficient than existing CPUs. Thus, if you can make an Ethereum ASIC, you can push the entire computing industry forward by about 5 years. -4. Because every miner must have the full blockchain, there is no equivalent to the Bitcoin mining strategy of only downloading headers from a centralized source. Hence, centralized mining pools offer no benefits over p2pools, and so miners are more likely to use p2pools. -5. The algorithm is relatively computationally quick to verify, although there is no "nice" verification formula that can be run inside EVM code. - -(3) and (4) combined basically mean that this proof of work algorithm provides both forms of decentralization, and (2) helps prevent centralization due to blockchain bloat since it helps ensure that at least miners will store the chain. - -In the above given form, the algorithm has several faults. First, due to the Pareto effect, it is likely that over 90% of transactions will use up less than 10% of the blockchain, so a truly full node will not be required to mine. Second, some targeted optimizations involving executing contracts and caching results may be possible. Finally, arguably most importantly, a deep 51% attack becomes possible, where attackers start hundreds of blocks back, produce 16 blocks with transactions optimized for themselves to process quickly (eg. obfuscated loops, weakened trapdoor functions), and then mine much faster than the legitimate chain. For the last two reasons, we expect that very heavy use (perhaps even dominance) of contract corruption/randomization will be necessary in the final version of the algorithm. - -### Transactions - -A transaction is stored as: - - [ nonce, receiving_address, value, [ data item 0, data item 1 ... data item n ], v, r, s ] - -nonce is the number of transactions already sent by that account, encoded in binary form (eg. 0 -> '', 7 -> '\x07', 1000 -> '\x03\xd8'). (v,r,s) is the raw Electrum-style signature of the transaction without the signature made with the private key corresponding to the sending account, with 0 <= v <= 3. From an Electrum-style signature (65 bytes) it is possible to extract the public key, and thereby the address, directly. A valid transaction is one where (i) the signature is well-formed (ie. 0 <= v <= 3, 0 <= r < P, 0 <= s < N, 0 <= r < P - N if v >= 2), and (ii) the sending account has enough funds to pay the fee and the value. A valid block cannot contain an invalid transaction; however, if a contract generates an invalid transaction that transaction will simply have no effect. Transaction fees will be included automatically. If one wishes to voluntarily pay a higher fee, one is always free to do so by constructing a contract which forwards transactions but automatically sends a certain amount or percentage to the miner of the current block. - -Transactions sent to the empty string as an address are a special type of transaction, creating a "contract". - - -### Difficulty adjustment - -Difficulty is adjusted by the formula: - - D(genesis_block) = 2^36 - D(block) = - if anc(block,1).timestamp >= anc(block,501).timestamp + 60 * 500: D(block.parent) - floor(D(block.parent) / 1000) - else: D(block.parent) + floor(D(block.parent) / 1000) - -`anc(block,n)` is the nth generation ancestor of the block; all blocks before the genesis block are assumed to have the same timestamp as the genesis block. This stabilizes around a block time of 60 seconds automatically. The choice of 500 was made in order to balance the concern that for smaller values miners with sufficient hashpower to often produce two blocks in a row would have the incentive to provide an incorrect timestamp to maximize their own reward and the fact that with higher values the difficulty oscillates too much; with the constant of 500, simulations show that a constant hashpower produces a variance of about +/-20%. - -### Block Rewards and Limits - -A miner receives three kinds of rewards: a static block reward for producing a block, fees from transactions, and nephew/uncle rewards as described in the GHOST section above. The miner will receive 100% of the block reward and transaction fees for themselves. As described in the GHOST section, uncles only receive 87.5% of their block reward, with the remaining 12.5% going to the including nephew; the transaction fees from the stale block do not go to anyone. - -The default approach is to have no mandatory fees, allowing miners to include any transactions that they deem profitable to include. This approach has been received very favorably in the Bitcoin community particularly because it is "market-based" - that is, there is a market with miners on one side and transaction senders on the other where supply and demand determine the price. However, the problem with this line of reasoning is that transaction processing is not a market; although it is intuitively attractive to construe transaction processing as a service that the miner is making the effort to offer to transaction senders that needs to be paid for at an agreed-upon rate, in reality every transaction that a single miner includes needs to be processed by every node in the network, so the external costs of transaction processing borne by the network, which has no say in whether or not a transaction takes place, are thousands of times higher than the internal costs borne by the miner. - -However, as it turns out this flaw in the market-based mechanism, when given a particular inaccurate simplifying assumption, magically cancels itself out. The argument is as follows. Suppose that: - -1. The mining block reward is `B`. -2. A transaction leads to `k` operations, offering the reward `kR` to any miner that includes it where `R` is set by the sender and `k` and `R` are visible to the miner beforehand. -3. An operation has a processing cost of `C` to any node (ie. all nodes have equal efficiency) -4. There are `N` mining nodes, each with exactly equal processing power (ie. `1/N` of total) -5. No non-mining full nodes exist. - -A miner would be willing to process a transaction if the expected reward is greater than the cost. The expected reward is `kR/N` since the miner has a `1/N` chance of processing the next block. The cost is simply `kC`. Thus, the miner is willing to process transactions where: - - kR/N > kC - kR > kNC - R > NC - -Note that `R` is the per-operation fee, and `NC` is the cost to the entire network together of processing an operation. Hence, miners have the incentive to include only those transactions for which the total utilitarian benefit exceeds the cost. However, there are three important deviations from those assumptions in reality: - -1. The miner does pay a higher cost to process the transaction than the other verifying nodes, since the extra verification time delays block propagation and thus increases the chance the block will become a stale. -2. There do exist nonmining full nodes. -3. The mining power distribution may end up radically inegalitarian in practice. -4. Speculators, political enemies and crazies whose utility function includes causing harm to the network do exist, and they can cleverly set up contracts where their cost is much lower than the cost paid by other verifying nodes. - -(1) provides a tendency for the miner to include fewer transactions, and (2) increases `NC`; hence, these two effects at least partially cancel each other out. (3) and (4) are the major issue; to solve them we simply institute a floating cap: no block can have more operations than 150% of the long-term exponential moving average (exact figure subject to change pending further economic analysis). - -## Contracts - -In Ethereum, there are two types of entities that can generate and receive transactions: actual people (or bots, as cryptographic protocols cannot distinguish between the two) and contracts. A contract is essentially an automated agent that lives on the Ethereum network, has an Ethereum address and balance, and can send and receive transactions. A contract is "activated" every time someone sends a transaction to it, at which point it runs its code, perhaps modifying its internal state or even sending some transactions, and then shuts down. The "code" for a contract is written in a special-purpose low-level language consisting of a stack, which is not persistent, 2^256 memory entries, which are also not persistent, and 2^256 storage entries which constitute the contract's permanent state. Note that Ethereum users will not need to code in this low-level stack language; we are providing a simple [C-Like language](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-CLL) with variables, expressions, conditionals, arrays and while loops, and provide a compiler down to Ethereum script code. - -### Applications - -Here are some examples of what can be done with Ethereum contracts, with all code examples written in our C-like language. The variables `call.sender`, `call.value`, `call.data` and `call.datasize` are properties of the incoming transaction, `contract.storage`, and `contract.address` of the contract itself, and `block.account_balance`, `block.number`, `block.difficulty`, `block.parenthash`, `block.basefee` and `block.timestamp` properties of the block. `block.basefee` is the "base fee" which all transaction fees in Ethereum are calculated as a multiple of; for more info see the "fees" section below. All variables expressed as capital letters (eg. `A`) are constants, to be replaced by actual values by the contract creator when actually releasing the contract. - - -### Sub-currencies - -Sub-currencies have many applications ranging from currencies representing assets such as USD or gold to company stocks and even currencies with only one unit issued to represent collectibles or smart property. Advanced special-purpose financial protocols sitting on top of Ethereum may also wish to organize themselves with an internal currency. Sub-currencies are surprisingly easy to implement in Ethereum; this section describes a fairly simple contract for doing so. - -The idea is that if someone wants to send X currency units to account A in currency contract C, they will need to make a transaction of the form `(C, 100 * block.basefee, [A, X])`, and the contract parses the transaction and adjusts balances accordingly. For a transaction to be valid, it must send 100 times the base fee worth of ether to the contract in order to "feed" the contract (as each computational step after the first 16 for any contract costs the contract a small fee and the contract will stop working if its balance drains to zero). - - if tx.value < 100 * block.basefee: - stop - elif contract.storage[1000]: - from = tx.sender - to = tx.data[0] - value = tx.data[1] - if to <= 1000: - stop - if contract.storage[from] < value: - stop - contract.storage[from] = contract.storage[from] - value - contract.storage[to] = contract.storage[to] + value - else: - contract.storage[MYCREATOR] = 10^18 - contract.storage[1000] = 1 - - -Ethereum sub-currency developers may also wish to add some other more advanced features: - -* Include a mechanism by which people can buy currency units in exchange for ether, perhaps auctioning off a set number of units every day. -* Allow transaction fees to be paid in the internal currency, and then refund the ether transaction fee to the sender. This solves one major problem that all other "sub-currency" protocols have had to date: the fact that sub-currency users need to maintain a balance of sub-currency units to use and units in the main currency to pay transaction fees in. Here, a new account would need to be "activated" once with ether, but from that point on it would not need to be recharged. -* Allow for a trust-free decentralized exchange between the currency and ether. Note that trust-free decentralized exchange between any two contracts is theoretically possible in Ethereum even without special support, but special support will allow the process to be done about ten times more cheaply. - - -### Financial derivatives - -The underlying key ingredient of a financial derivative is a data feed to provide the price of a particular asset as expressed in another asset (in Ethereum's case, the second asset will usually be ether). There are many ways to implement a data feed; one method, pioneered by the developers of [Mastercoin](http://mastercoin.org/), is to include the data feed in the blockchain. Here is the code: - - if tx.sender != FEEDOWNER: - stop - contract.storage[data[0]] = data[1] - -Any other contract will then be able to query index I of data store D by using `block.contract_storage(D)[I]`. A more advanced way to implement a data feed may be to do it off-chain - have the data feed provider sign all values and require anyone attempting to trigger the contract to include the latest signed data, and then use Ethereum's internal scripting functionality to verify the signature. Pretty much any derivative can be made from this, including leveraged trading, options, and even more advanced constructions like collateralized debt obligations (no bailouts here though, so be mindful of black swan risks). - -To show an example, let's make a hedging contract. The basic idea is that the contract is created by party A, who puts up 4000 ether as a deposit. The contract then lies open for any party to accept it by putting in 1000 ether. Say that 1000 ether is worth $25 at the time the contract is made, according to index I of data store D. If party B accepts it, then after 30 days anyone can send a transaction to make the contract process, sending the same dollar value worth of ether (in our example, $25) back to B and the rest to A. B gains the benefit of being completely insulated against currency volatility risk without having to rely on any issuers. The only risk to B is if the value of ether falls by over 80% in 30 days - and even then, if B is online B can simply quickly hop onto another hedging contract. The benefit to A is the implicit 0.2% fee in the contract, and A can hedge against losses by separately holding USD in another location (or, alternatively, A can be an individual who is optimistic about the future of Ethereum and wants to hold ether at 1.25x leverage, in which case the fee may even be in B's favor). - - if tx.value < 200 * block.basefee: - stop - if contract.storage[1000] == 0: - if tx.value < 1000 * 10^18: - stop - contract.storage[1000] = 1 - contract.storage[1001] = 998 * block.contract_storage(D)[I] - contract.storage[1002] = block.timestamp + 30 * 86400 - contract.storage[1003] = tx.sender - else: - ethervalue = contract.storage[1001] / block.contract_storage(D)[I] - if ethervalue >= 5000: - mktx(contract.storage[1003],5000 * 10^18,0,0) - else if block.timestamp > contract.storage[1002]: - mktx(contract.storage[1003],ethervalue * 10^18,0,0) - mktx(A,(5000 - ethervalue) * 10^18,0,0) - -More advanced financial contracts are also possible; complex multi-clause options (eg. "Anyone, hereinafter referred to as X, can claim this contract by putting in 2 USD before Dec 1. X will have a choice on Dec 4 between receiving 1.95 USD on Dec 29 and the right to choose on Dec 11 between 2.20 EUR on Dec 28 and the right to choose on Dec 18 between 1.20 GBP on Dec 30 and paying 1 EUR and getting 3.20 EUR on Dec 29") can be defined simply by storing a state variable just like the contract above but having more clauses in the code, one clause for each possible state. Note that financial contracts of any form do need to be fully collateralized; the Ethereum network controls no enforcement agency and cannot collect debt. - - -### Identity and Reputation Systems - -The earliest alternative cryptocurrency of all, [Namecoin](http://namecoin.org/), attempted to use a Bitcoin-like blockchain to provide a name registration system, where users can register their names in a public database alongside other data. The major cited use case is for a [DNS](http://en.wikipedia.org/wiki/Domain_Name_System) system, mapping domain names like "bitcoin.org" (or, in Namecoin's case, "bitcoin.bit") to an IP address. Other use cases include email authentication and potentially more advanced reputation systems. Here is a simple contract to provide a Namecoin-like name registration system on Ethereum: - - if tx.value < block.basefee * 200: - stop - if contract.storage[tx.data[0]] or tx.data[0] < 100: - stop - contract.storage[tx.data[0]] = tx.data[1] - -One can easily add more complexity to allow users to change mappings, automatically send transactions to the contract and have them forwarded, and even add reputation and web-of-trust mechanics. - - -### Decentralized Autonomous Organizations - -The general concept of a "decentralized autonomous organization" is that of a virtual entity that has a certain set of members or shareholders which, perhaps with a 67% majority, have the right to spend the entity's funds and modify its code. The members would collectively decide on how the organization should allocate its funds. Methods for allocating a DAO's funds could range from bounties, salaries to even more exotic mechanisms such as an internal currency to reward work. This essentially replicates the legal trappings of a traditional company or nonprofit but using only cryptographic blockchain technology for enforcement. So far much of the talk around DAOs has been around the "capitalist" model of a "decentralized autonomous corporation" (DAC) with dividend-receiving shareholders and tradable shares; an alternative, perhaps described as a "decentralized autonomous community", would have all members have an equal share in the decision making and require 67% of existing members to agree to add or remove a member. The requirement that one person can only have one membership would then need to be enforced collectively by the group. - -Some "skeleton code" for a DAO might look as follows. - -There are three transaction types: - -* [0,k] to register a vote in favor of a code change -* [1,k,L,v0,v1...vn] to register a code change at code k in favor of setting memory starting from location L to v0, v1 ... vn -* [2,k] to finalize a given code change - -Note that the design relies on the randomness of addresses and hashes for data integrity; the contract will likely get corrupted in some fashion after about 2^128 uses, but that is acceptable since nothing close to that volume of usage will exist in the foreseeable future. 2^255 is used as a magic number to store the total number of members, and a membership is stored with a 1 at the member's address. The last three lines of the contract are there to add C as the first member; from there, it will be C's responsibility to use the democratic code change protocol to add a few other members and code to bootstrap the organization. - - if tx.value < tx.basefee * 200: - stop - if contract.storage[tx.sender] == 0: - stop - k = sha3(32,tx.data[1]) - if tx.data[0] == 0: - if contract.storage[k + tx.sender] == 0: - contract.storage[k + tx.sender] = 1 - contract.storage[k] += 1 - else if tx.data[0] == 1: - if tx.value <= tx.datan * block.basefee * 200 or contract.storage[k]: - stop - i = 2 - while i < tx.datan: - contract.storage[k + i] = tx.data[i] - i = i + 1 - contract.storage[k] = 1 - contract.storage[k+1] = tx.datan - else if tx.data[0] == 2: - if contract.storage[k] >= contract.storage[2 ^ 255] * 2 / 3: - if tx.value <= tx.datan * block.basefee * 200: - stop - i = 3 - L = contract.storage[k+1] - loc = contract.storage[k+2] - while i < L: - contract.storage[loc+i-3] = tx.data[i] - i = i + 1 - if contract.storage[2 ^ 255 + 1] == 0: - contract.storage[2 ^ 255 + 1] = 1 - contract.storage[C] = 1 - -This implements the "egalitarian" DAO model where members have equal shares. One can easily extend it to a shareholder model by also storing how many shares each owner holds and providing a simple way to transfer shares. - -DAOs and DACs have already been the topic of a large amount of interest among cryptocurrency users as a future form of economic organization, and we are very excited about the potential that DAOs can offer. In the long term, the Ethereum fund itself intends to transition into being a fully self-sustaining DAO. - - -### Further Applications - -1. **Savings wallets**. Suppose that Alice wants to keep her funds safe, but is worried that she will lose or someone will hack her private key. She puts ether into a contract with Bob, a bank, as follows: Alice alone can withdraw a maximum of 1% of the funds per day, Alice and Bob together can withdraw everything, and Bob alone can withdraw a maximum of 0.05% of the funds. Normally, 1% per day is enough for Alice, and if Alice wants to withdraw more she can contact Bob for help. If Alice's key gets hacked, she runs to Bob to move the funds to a new contract. If she loses her key, Bob will get the funds out eventually. If Bob turns out to be malicious, she can still withdraw 20 times faster than he can. - -2. **Crop insurance**. One can easily make a financial derivatives contract but using a data feed of the weather instead of any price index. If a farmer in Iowa purchases a derivative that pays out inversely based on the precipitation in Iowa, then if there is a drought, the farmer will automatically receive money and if there is enough rain the farmer will be happy because their crops would do well. - -3. **A decentralized (non-centrally managed) data feed**, using proof-of-stake voting to give an average (or more likely, median) of everyone's opinion on the price of a commodity, the weather or any other relevant data. - -4. **Smart multisignature escrow**. Bitcoin allows multisignature transaction contracts where, for example, three out of a given five keys can spend the funds. Ethereum allows for more granularity; for example, four out of five can spend everything, three out of five can spend up to 10% per day, and two out of five can spend up to 0.5% per day. Additionally, Ethereum multisig is asynchronous - two parties can register their signatures on the blockchain at different times and the last signature will automatically send the transaction. - -5. **Peer-to-peer gambling**. Any number of peer-to-peer gambling protocols, such as Frank Stajano and Richard Clayton's [Cyberdice](http://www.cl.cam.ac.uk/~fms27/papers/2008-StajanoCla-cyberdice.pdf), can be implemented on the Ethereum blockchain. The simplest gambling protocol is actually simply a contract for difference on the next block hash. From there, entire gambling services such as SatoshiDice can be replicated on the blockchain either by creating a unique contract per bet or by using a quasi-centralized contract. - -6. A full-scale **on-chain stock market**. Prediction markets are also easy to implement as a trivial consequence. - -7. An **on-chain decentralized marketplace**, using the identity and reputation system as a base. - -8. **Decentralized Dropbox**. One setup is to encrypt a file, build a Merkle tree out of it, put the Merkle root into a contract alongside a certain quantity of ether, and distribute the file across some secondary network. Every day, the contract would randomly select a branch of the Merkle tree depending on the block hash, and give X ether to the first node to provide that branch to the contract, thereby encouraging nodes to store the data for the long term in an attempt to earn the prize. If one wants to download any portion of the file, one can use a [micropayment-channel](https://bitcointalk.org/index.php?topic=244656.0)-style contract to download the file from a few nodes a block at a time. - - -### How do contracts work? - -A contract making transaction is encoded as follows: - - [ - nonce, - '', - value, - [ - data item 0, - data item 1, - ... - ], - v, - r, - s - ] - - -The data items will, in most cases, be script codes (more on this below). Contract creation transaction validation happens as follows: - -Deserialize the transaction, and extract its sending address from its signature. -Calculate the transaction's fee as NEWCONTRACTFEE plus storage fees for the code. Check that the balance of the creator is at least the transaction value plus the fee. If not, exit. -Take the last 20 bytes of the sha3 hash of the RLP encoding of the transaction making the contract. If an account with that address already exists, exit. Otherwise, create the contract at that address -Copy data item i to storage slot i in the contract for all i in [0 ... n-1] where n is the number of data items in the transaction, and initialize the contract with the transaction's value as its value. Subtract the value and fee from the creator's balance. - - -### Language Specification - -The contract scripting language is a hybrid of assembly language and Bitcoin's stack-based language, maintaining an index pointer that usually increments by one after every operation and continuously processing the operation found at the current index pointer. All opcodes are numbers in the range [0 ... 63]; labels further in this description such as STOP, EXTRO and BALANCE refer to specific values and are defined further below. The scripting language has access to three kinds of memory: - -* **Stack** - a form of temporary storage that is reset to an empty list every time a contract is executed. Operations typically add and remove values to and from the top of the stack, so the total length of the stack will shrink and grow over the course of the program's execution. -* **Memory** - a temporary key/value store that is reset to containing all zeroes every time a contract is executed. Keys and values in memory are integers in the range [0 ... 2^256-1] -* **Storage** - a persistent key/value store that is initially set to contain all zeroes, except for some script code inserted at the beginning when the contract is created as described above. Keys and values in storage are integers in the range [0 ... 2^256-1] - -Whenever a transaction is sent to a contract, the contract executes its scripting code. The precise steps that happen when a contract receives a transaction are as follows: - -**Contract Script Interpretation ** - -![SPV in bitcoin](https://www.ethereum.org/gh_wiki/flowchart.png) - -1. The contract's ether balance increases by the amount sent -2. The index pointer is set to zero, and STEPCOUNT = 0 -3. Repeat forever: - -* if the command at the index pointer is STOP, invalid or greater than 63, exit from the loop -* set MINERFEE = 0, VOIDFEE = 0 -* set STEPCOUNT <- STEPCOUNT + 1 -* if STEPCOUNT > 16, set MINERFEE <- MINERFEE + STEPFEE -* see if the command is LOAD or STORE. If so, set MINERFEE <- MINERFEE + DATAFEE -* see if the command will modify a storage field, say modifying KEY from OLDVALUE to NEWVALUE. Let F(K,V) be 0 if V == 0 else (len(K) + len(V)) * STORAGEFEE in bytes. Set VOIDFEE <- VOIDFEE - F(KEY,OLDVALUE) + F(KEY,NEWVALUE). Computing len(K) ignores leading zero bytes. -* see if the command is EXTRO or BALANCE. If so, set MINERFEE <- MINERFEE + EXTROFEE -* see if the command is a crypto operation. If so, set MINERFEE <- MINERFEE + CRYPTOFEE -* if MINERFEE + VOIDFEE > CONTRACT.BALANCE, HALT and exit from the loop -* subtract MINERFEE from the contract's balance and add MINERFEE to a running counter that will be added to the miner's balance once all transactions are parsed. -* set DELTA = max(-CONTRACT.STORAGE_DEPOSIT,VOIDFEE) and CONTRACT.BALANCE <- CONTRACT.BALANCE - DELTA and CONTRACT.STORAGE_DEPOSIT <- CONTRACT.STORAGE_DEPOSIT + DELTA. Note that DELTA can be positive or negative; the only restriction is that the contract's deposit cannot go below zero. -* run the command -* if the command did not exit with an error, update the index pointer and return to the start of the loop. If the contract did exit with an error, break out of the loop. Note that a contract exiting with an error does not make the transaction or the block invalid; it simply means that the contract execution halts midway through. - -In the following descriptions, S[-1], S[-2], etc represent the topmost, second topmost, etc items on the stack. The individual opcodes are defined as follows: - -* (0) STOP - halts execution -* (1) ADD - pops two items and pushes S[-2] + S[-1] mod 2^256 -* (2) MUL - pops two items and pushes S[-2] * S[-1] mod 2^256 -* (3) SUB - pops two items and pushes S[-2] - S[-1] mod 2^256 -* (4) DIV - pops two items and pushes floor(S[-2] / S[-1]). If S[-1] = 0, halts execution. -* (5) SDIV - pops two items and pushes floor(S[-2] / S[-1]), but treating values above 2^255 - 1 as negative (ie. x -> 2^256 - x). If S[-1] = 0, halts execution. -* (6) MOD - pops two items and pushes S[-2] mod S[-1]. If S[-1] = 0, halts execution. -* (7) SMOD - pops two items and pushes S[-2] mod S[-1], but treating values above 2^255 - 1 as negative (ie. x -> 2^256 - x). If S[-1] = 0, halts execution. -* (8) EXP - pops two items and pushes S[-2] ^ S[-1] mod 2^256 -* (9) NEG - pops one item and pushes 2^256 - S[-1] -* (10) LT - pops two items and pushes 1 if S[-2] < S[-1] else 0 -* (11) LE - pops two items and pushes 1 if S[-2] <= S[-1] else 0 -* (12) GT - pops two items and pushes 1 if S[-2] > S[-1] else 0 -* (13) GE - pops two items and pushes 1 if S[-2] >= S[-1] else 0 -* (14) EQ - pops two items and pushes 1 if S[-2] == S[-1] else 0 -* (15) NOT - pops one item and pushes 1 if S[-1] == 0 else 0 -* (16) MYADDRESS - pushes the contract's address as a number -* (17) TXSENDER - pushes the transaction sender's address as a number -* (18) TXVALUE - pushes the transaction value -* (19) TXDATAN - pushes the number of data items -* (20) TXDATA - pops one item and pushes data item S[-1], or zero if index out of range -* (21) BLK_PREVHASH - pushes the hash of the previous block (NOT the current one since that's impossible!) -* (22) BLK_COINBASE - pushes the coinbase of the current block -* (23) BLK_TIMESTAMP - pushes the timestamp of the current block -* (24) BLK_NUMBER - pushes the current block number -* (25) BLK_DIFFICULTY - pushes the difficulty of the current block -* (26) BLK_NONCE - pushes the nonce of the current block -* (27) BASEFEE - pushes the base fee (x as defined in the fee section below) -* (32) SHA256 - pops two items, and then constructs a string by taking the ceil(S[-1] / 32) items in memory from index S[-2] to (S[-2] + ceil(S[-1] / 32) - 1) mod 2^256, prepending zero bytes to each one if necessary to get them to 32 bytes, and takes the last S[-1] bytes. Pushes the SHA256 hash of the string -* (33) RIPEMD160 - works just like SHA256 but with the RIPEMD-160 hash -* (34) ECMUL - pops three items. If (S[-2],S[-1]) are a valid point in secp256k1, including both coordinates being less than P, pushes (S[-2],S[-1]) * S[-3], using (0,0) as the point at infinity. Otherwise, pushes (2^256 - 1, 2^256 - 1). Note that there are no restrictions on S[-3] -* (35) ECADD - pops four items and pushes (S[-4],S[-3]) + (S[-2],S[-1]) if both points are valid, otherwise (2^256 - 1,2^256 - 1) -* (36) ECSIGN - pops two items and pushes (v,r,s) as the Electrum-style RFC6979 deterministic signature of message hash S[-1] with private key S[-2] mod N with 0 <= v <= 3 -* (37) ECRECOVER - pops four items and pushes (x,y) as the public key from the signature (S[-3],S[-2],S[-1]) of message hash S[-4]. If the signature has invalid v,r,s values (ie. v not in [27,28], r not in [0,P], s not in [0,N]), return (2^256 - 1,2^256 - 1) -* (38) ECVALID - pops two items and pushes 1 if (S[-2],S[-1]) is a valid secp256k1 point (including (0,0)) else 0 -* (39) SHA3 - works just like SHA256 but with the SHA3 hash, 256 bit version -* (48) PUSH - pushes the item in memory at the index pointer + 1, and advances the index pointer by 2. -* (49) POP - pops one item. -* (50) DUP - pushes S[-1] to the stack. -* (51) SWAP - pops two items and pushes S[-1] then S[-2] -* (52) MLOAD - pops two items and sets the item in memory at index S[-1] to S[-2] -* (53) MSTORE - pops two items and sets the item in memory at index S[-1] to S[-2] -* (54) SLOAD - pops two items and sets the item in storage at index S[-1] to S[-2] -* (55) SSTORE - pops two items and sets the item in storage at index S[-1] to S[-2] -* (56) JMP - pops one item and sets the index pointer to S[-1] -* (57) JMPI - pops two items and sets the index pointer to S[-2] only if S[-1] is nonzero -* (58) IND - pushes the index pointer -* (59) EXTRO - pops two items and pushes memory index S[-2] of contract S[-1] -* (60) BALANCE - pops one item and pushes balance of the account with that address, or zero if the address is invalid -* (61) MKTX - pops four items and initializes a transaction to send S[-2] ether to S[-1] with S[-3] data items. Takes items in memory from index S[-4] to index (S[-4] + S[-3] - 1) mod 2^256 as the transaction's data items. -* (63) SUICIDE - pops one item, destroys the contract and clears all storage, sending the entire balance plus the contract deposit to the account at S[-1] - - -As mentioned above, the intent is not for people to write scripts directly in Ethereum script code; rather, we will release compilers to generate ES from higher-level languages. The first supported language will likely be the simple [C-like language](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-CLL) used in the descriptions above, and the second will be a more complete first-class-function language with support for arrays and arbitrary-length strings. Compiling the C-like language is fairly simple as far as compilers go: variables can be assigned a memory index, and compiling an arithmetic expression essentially involves converting it to reverse Polish notation (eg. `(3 + 5) * (x + y)` -> `PUSH 3 PUSH 5 ADD PUSH 0 MLOAD PUSH 1 MLOAD ADD MUL`). First-class function languages are more involved due to variable scoping, but the problem is nevertheless tractable. The likely solution will be to maintain a linked list of stack frames in memory, giving each stack frame N memory slots where N is the total number of distinct variable names in the program. Variable access will consist of searching down the stack frame list until one frame contains a pointer to the variable, copying the pointer to the top stack frame for memoization purposes, and returning the value at the pointer. However, these are longer term concerns; compilation is separate from the actual protocol, and so it will be possible to continue to research compilation strategies long after the network is set running. - - -## Fees - -In Bitcoin, there are no mandatory transaction fees. Transactions can optionally include fees which are paid to miners, and it is up to the miners to decide what fees they are willing to accept. In Bitcoin, such a mechanism is already imperfect; the need for a 1 MB block size limit alongside the fee mechanism shows this all too well. In Ethereum, because of its Turing-completeness, a purely voluntary fee system would be catastrophic. Instead, Ethereum will have a system of mandatory fees, including a transaction fee and six fees for contract computations. The fees are currently set to: - -* TXFEE (100x) - fee for sending a transaction -* NEWCONTRACTFEE (100x) - fee for creating a new contract, not including the storage fee for each item in script code -* STEPFEE (1x) - fee for every computational step after the first sixteen in contract execution -* STORAGEFEE (5x) - per-byte fee for adding to contract storage. The storage fee is the only fee that is not paid to a miner, and is refunded when storage used by a contract is reduced or removed. -* DATAFEE (20x) - fee for accessing or setting a contract's memory from inside that contract -* EXTROFEE (40x) - fee for accessing memory from another contract inside a contract -* CRYPTOFEE (20x) - fee for using any of the cryptographic operations - - -The coefficients will be revised as more hard data on the relative computational cost of each operation becomes available. The hardest part will be setting the value of x. There are currently two main solutions that we are considering: - -* Make x inversely proportional to the square root of the difficulty, so x = floor(10^21 / floor(difficulty ^ 0.5)). This automatically adjusts fees down as the value of ether goes up, and adjusts fees down as computers get more powerful due to Moore's Law. -* Use proof of stake voting to determine the fees. In theory, stakeholders do not benefit directly from fees going up or down, so their incentives would be to make the decision that would maximize the value of the network. - -A hybrid solution is also possible, using proof of stake voting, but with the inverse square root mechanism as an initial policy. - - -## Conclusion - -The Ethereum protocol's design philosophy is in many ways the opposite from that taken by many other cryptocurrencies today. Other cryptocurrencies aim to add complexity and increase the number of "features"; Ethereum, on the other hand, takes features away. The protocol does not "support" multisignature transactions, multiple inputs and outputs, hash codes, lock times or many other features that even Bitcoin provides. Instead, all complexity comes from a universal, Turing-complete scripting language, which can be used to build up literally any feature that is mathematically describable through the contract mechanism. As a result, we have a protocol with unique potential; rather than being a closed-ended, single-purpose protocol intended for a specific array of applications in data storage, gambling or finance, Ethereum is open-ended by design, and we believe that it is extremely well-suited to serving as a foundational layer for a very large number of both financial and non-financial protocols in the years to come. - - -## References and Further Reading - -1. Colored coins whitepaper: https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit -2. Mastercoin whitepaper: https://github.com/mastercoin-MSC/spec -3. Decentralized autonomous corporations, Bitcoin Magazine: http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/ -4. Smart property: https://en.bitcoin.it/wiki/Smart_Property -5. Smart contracts: https://en.bitcoin.it/wiki/Contracts -6. Simplified payment verification: https://en.bitcoin.it/wiki/Scalability#Simplifiedpaymentverification -7. Merkle trees: http://en.wikipedia.org/wiki/Merkle_tree -8. Patricia trees: http://en.wikipedia.org/wiki/Patricia_tree -9. Bitcoin whitepaper: http://bitcoin.org/bitcoin.pdf -10. GHOST: http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf -11. StorJ and Autonomous Agents, Jeff Garzik: http://garzikrants.blogspot.ca/2013/01/storj-and-bitcoin-autonomous-agents.html -12. Mike Hearn on Smart Property at Turing Festival: http://www.youtube.com/watch?v=Pu4PAMFPo5Y -13. Ethereum RLP: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP -14. Ethereum Merkle Patricia trees: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree -15. Ethereum Dagger: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Dagger -16. Ethereum C-like language: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-CLL -17. Ethereum Slasher: http://blog.ethereum.org/?p=39/slasher-a-punitive-proof-of-stake-algorithm -18. Scrypt parameters: https://litecoin.info/User:Iddo/ComparisonbetweenLitecoinandBitcoin#SHA256miningvsscryptmining -19. Litecoin ASICs: https://axablends.com/merchants-accepting-bitcoin/litecoin-discussion/litecoin-scrypt-asic-miners/ \ No newline at end of file diff --git a/drafts/[english]-patricia-tree-draft.md b/drafts/[english]-patricia-tree-draft.md deleted file mode 100644 index 57f12ab23..000000000 --- a/drafts/[english]-patricia-tree-draft.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -name: Patricia Tree -category: ---- - -The best known tutorial/explanation of the ethereum patricia tree is here: -https://easythereentropy.wordpress.com/2014/06/04/understanding-the-ethereum-trie/ \ No newline at end of file diff --git a/enode-url-format.md b/enode-url-format.md deleted file mode 100644 index 96208ce8a..000000000 --- a/enode-url-format.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -name: ENode URL Format -category: ---- - -An Ethereum node can be described with a URL scheme "enode". - -The hexadecimal node ID is encoded in the username portion of the URL, separated from the host by an @ sign. The hostname can only be given as an IP address, DNS domain names are not allowed. The port -in the host name section is the TCP listening port. If the TCP and UDP (discovery) ports differ, the UDP port is specified as query parameter "discport". - -In the following example, the node URL describes a node with IP address `10.3.58.6`, TCP listening port `30303` and UDP discovery port `30301`. - -``` -enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@10.3.58.6:30303?discport=30301 -``` - -The enode url scheme is used by the Node discovery protocol and can be used in the `bootnodes` command line option of the client or as the argument to `suggestPeer(nodeURL)` function in the JSRE. - -See also -- https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options -- https://github.com/ethereum/go-ethereum/wiki/JavaScript-Console diff --git "a/e\317\200-Programme.md" "b/e\317\200-Programme.md" deleted file mode 100644 index ef6ea8a2f..000000000 --- "a/e\317\200-Programme.md" +++ /dev/null @@ -1,21 +0,0 @@ ---- -name: Ethereum Raspberry Pi -category: ---- - -# The Ethereum Raspberry Pi (eπ) Programme - -The eπ programme is aimed to get as many nodes distributed around the world as possible. Any existing Ethereum meetup group is eligible to apply. - -We will offer to loan the group a set of equipment to run an Ethereum node. This will include: - -- Raspberry Pi 2 Model B; -- 64 GB fast memory card; -- PSU. - -We expect you guys to be the ones to run the install (https://github.com/ethereum/wiki/wiki/Raspberry-Pi-instructions). - -Your node will be placed on both our public and curated node lists, and aside from allowing us to show dots all over the world, will help us better understand network dynamics and emergent effects stemming from our propagation strategies. - -To apply for the programme, send an application including your name, meetup group name/town and an address for shipment to epi@ethereum.org. - diff --git a/images/natspec1.png b/images/natspec1.png deleted file mode 100644 index cf31fcf24fce2801ffbedaac8ae151d7e5d806d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82697 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

wS*%-n0fWjsb2}4#4rP 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�#pOa+AG7A-y+ zT%EB&?)O}OfwVCslZvVS`))Tt>Aq*lX7(e zk#|Z0Mjb8>cs{I7ZP$;9cr%sb8(Fc6-YHRTMrRx(`g1(Z$ z_%C7|hZrtah5cL4^y*3aW{X{p{@kYwi@NH4))|j5p>FVIpCMr%a{65gdJ4?0e{P=^ z?>x!e@G-Wd{S~2#EYH%D|I@=V7l#?fHDOJJFA<yv|RKt@^-`sjCz z5d-`33s}z@MfpucDJ4TJ$lw|{WE`AN09if`*Zlj(5oKU*bNt3%Y; ze^^QxB_6%J$NwZNCQ?y!qSaa$VH4QubHx{>xnIf$k^`8ikWi_~UnOoV)lR*4?{$Dfn1%^v5cq=73Io zfWSkZmT3_(+9{v@7(VzW;#GC!F~{Ad=Ub?d(2MTn{&4@d?$F^kkSp>YH>g?Xf8FGD z)QHkEx+Qo?{D`v%_kuav-`JV;1JKz*4acqz8})7m-`#j&qOW`JE`e_NjrW)SJ%0I{ z!~83i8UDmcSOiW)m}LolgYSGc^N%P0KHB=q++zCSQNLa>0cXuHy|Abh*)_a26p`>sPlDsUxsR(L%NjY)tw4$?)0(2){KXwEo_qJV;cbQBOsASf+B zC@KQdrGy9}AR;ZHL+ItK?TEg=^L^(!=fCrD%?KoW@9h0N>sjkw_kBM+)YepH*~7U9 zg+j5YT>DcOh1zuoh1!1px1I3HNc+3X@NK)tB^CYO;LHEFTMyv(-M6n9d%*D&`I0(jLEa8eRzQOK@zKNzQMM9rx+UrIsYjuKO!aE-=ay2E1nJYfH~3l9!W= z;l6%+-8pdj8+kXCjC;7KLvGa4IPAa-pyE3{H z$Hty#um;FdtrSYeKhIntCCx~&qt`@KoK{?^CoBoOf1Ze1vW`ME#}}May&>g)8&~yD zCV#KMr9{ExM}Oxpt_ij}e#mq!vLST-bGo)RxfX`y$Jf-32C)IDeoVVdRHjy3mGZc%vbK<3I-m7NH zaUOPEo@l=Q>uD$?{}Xo-1$oT{xtzl}0-9a@d?P~$F6goB@RG+~Dt_ISFGub=m)(21 zU8?)agyzfc%*lJP#YhnR`=u&OLZkeusEi(!p}_^;w-wipU`>PZ=v{t#T5cs`-ht;C z+jd)Q9*uhIXSn-@5s{8b`y;}u*~@SFa>VODBI*V2Db4+wfRkZc_q^0aKeYCas88yp z6VH!_h>e+dgb_qC&k8-j?)7W@c|BCn;Jn10+2d6AzTp5VM~ka1b&|3}E`Gkb7;+MS zuf?z^dn$IXI6IocQQa@<;$0ll-Wqq?OH^t0%ecwbpO+yVezkMktLKkofBX3o>cTqP zN3oP&cZIqazWvOvw-C+OFDL$X@9W6XBb^-h^&-kgX#TUCitmB98wsEBAOHTZ zYx(518@-4q-f`~N(Tgnq^MZQ>ws0F~Ib76#`l^)~^Q-%zb+D0%w6wlJzXpBQ31bFlqg%@i*Tg%DC?35S(IHgDEHzMz=1=44*6On;pJ zIf18vfoF1cOoTP#baU<_qs=CwG^64)*brkhtjQzk+Ke|@eit0=ZsdqrejJN4ObweT z%^+zeDmn`h%~yPtlF$3@gG$Uc*4vtE=c5l6`$Pkj@D<4 z_V^j3t9Old-_UYdl4F(}?qIC*hA8-7XwOi{oj!Qnmn~C(oTF#Tq>~E;UPw8I>6BwJ z2DvUgL~5vuTl_rV`OJg_?ts!E37cED?3%hUrJkb@g^>msUShcek!is@6*E7i2{?Ci z4|u7U$O%P$UDrpVsP_EQJOZhL|3tX}Z*Rpov;K@mS^Cr55 z(CMJ9{Uorj(kM|D)6usv{nFG~Jz!!74TCX2f9GojWMORhzPbb{?g5KN7pB zzp10r+VwTw)%YZ=d$ug5tSZ%uN^3Q4h^ff6;#ao6uu);M(lw0rSeMs`SG;T)v{XWQ zGg!1S{;CPP6lJ{Z=J;5+SGy_axl=7U@rYw*PHq6nTS#7B9nwH)jsaKV`DIdiMdX`c zHeOy^Hp|5BLdn6dhn%1Kyz4AeCHqCCjNFDhnePimm#6!vY&^6}3VuBq&55$h=b9m# z;QETQnv)fT>X@tF!qBSqS0o>~q{GEn7)>iBR}+_)$0_D}_L98Jn@X89$iSjYt!cgm z70X{GSomaA`gewef$AXXhwhTSc*KM*+WWzHxBi3OSD?sZ?jFQaUit8uBQdQsY`d zzPEQe`djXa@uHBh&b+}5eJ{&VQBI?JI7^1ROOvb z{k4d#+qQ`jEs2BUW^7lLoY{tb7ou~6(3@-SLY={v-Cqdaw5-D!E!zH<{%%fOxy-K| zTIZdJq^_r_H6sso_{$xLHVy11Gw;M%0(>3_*pF0QF7U5bm2~YC?RzsAxBhiDP7<9& zJ$vu|eG`T7_QWI9LT5bj@LFf`19W3=1DZ`-!59oeHfOJQP04biQoIVG4& zUB>Fx%HeH1i6oPx@lnmk9_Xfyu;f6)wVI{^N6P6qg;_S@O}`W)t+jyqd^!z%M>AO_ zvX8*&&K^&4lXmSj+qRR{kZHm^w;qcwoC;l93KN0+PcBJ+x<370jdS7K5ryTC|7kc2 z10y1$#^jQ2FLGA0>uih>89Dw#Yh1i|(U8&@x0HwEOZe<((OxP?j~;d5 z5qU5fn!`Fy6_Sy;;*A*gV$1bC{ae!G)YPBV7q#(a zTH?+YpHuw&dXHj6VHTtu29|?L0vh?wV_g=RDaB3WO!>o``Dl^UgGTKtIp3l>F`;jI zFG~A%N1#>Bm&f^wX#%HngTMaz%R#%cg1x-_?YQ-hIE;z%-1*9zsBzWb->BqF)x(2U0?5%!mk%oeD>yveI!w15-WebsO|o_Z!4DK zg0btndb}T8G)+{UQKZlS|smD9Ye3^I7w$*MolPrTRFD0OiG~a<*9T5A6k*Kd4ztc zr#-DZ?G1Z{jAc{2BvXavOPw+(yNXfU!Bsg|xwL?>bRUq`)wUiIDYDjiGCQ{SXg?dX zf7hhrh02QPJjvvo_S7oA{14{b%TK&Dq+L3+_xAdjw~D!V_|iItEk1?VsF8~_92>CA z^uIF?Za#6!>#lLsx-Z3LN0hMhLhnIp;G)ju;P8%5!Mhm5auQ~uV|V#-eS^u`Xxysu z*gZ9&-LgURY3ou`7ejsB{r~E)e6mM2kXqz#ZaL8~;-R8@;AWD-g5==0Z`UH+-QCam zO*k6XK2qa@ryR-k$T&Cm^eCs?ggucUgIO-15Fxte4>jtM>4nIrFq??+VzrtH@>yZ#r8svo9c$I?iJxw!9!6uh zl>#q$dsZ~)D)%zXny&Q5v~quojtPID3s*ZdOJgVAT&BcWX4%BE;l_pMNFbf@&jiNS_e|Fv2E$huF})Dq~eiphs<6*HkxHP zIWN)WjB)xxEZ7lOSx&zW8xjmgRAgl8%idRMTM|S>W^sAqx!vUpA9~CE$mt#@GKST$UbyZe`<%~x3wVPDJB_57gxYbRWBmM= zMGUh$#E2dF!W(M~{N3wS3#u9+kpc>G%t<-WF zbWPmLbPuezkskH7Ll;I;9wCM8Dot&VnSW*;>1iJN#1!lpx5pZ zHO@3FQ4XWt-`^iS>q-cCbl~7YvE*%Aw|btP{yUIbX}PvjKJ9MhnsEM7H-Uz6RMLs8 z359i0-*#G=qNa;4B03Jv?4SGi`YGq)jUWWXmlxisND7)33?TK3gb#Rk8ZJFJS)Htu z@#TwneRH$nt#n+pwREqUDL^s<_*7LD6`ev(jOg_6_#?b50=ccMth_MiEQs8gugt2OpjHkSs5JsJQlxpQfJ^ z*WeX8R7IQ2{pLTG82YocTu}KGX#QG2=p^wEZ`0ePd1sr>Lg)9seSR{|vgqzsQ*7O=-&foM58|Qw^yYj5pCxB4uIgy>6t!|KG(U9}pw)r_h zFGG{T2<;n*GD15JD)TwkeckZDYf^Kj!@gpO8@(S!_Cku2c%{|OlQ`K{Nemcfu9ljZ zE=9#1%BVbL_UZNS;fxr|`ONN6=~6PmdEZ1}kRZi+(kbU>343;Eo_MFZ7?=GR?=`7# z)@BBl?%<@!!cyh4Cr>i*MiQQ1z8uASbQ2x%_gqiwnwZ4(nk|MQ{kXeROEV8Iaa3f% zvs~?T*?IHn>D{t^6AAajxou?TKMaJACT{p?J?b^jZcXJ~SX}NDGj*7b*grS&DOgY? zoHgKjLv*h8>`;?GFJ6MDo0$K2jcaf3JZ{{}*@Thfy{=_%Z*MZyDQ7|M|2QaObcmA^ z2P4z;T&7{1kra1E$Jp2y>-6DFQ^HyE_)6+m!$h9RV)NX}6785=vp2%~Sy;$fdKoNK z_oBe^&{iW(X@|@YdxJ7{s_t7*`p3IxKCncIICiyFWBbz`#}{9kqbY}LKK~q*Ly{z( zw_OghVP)n_m&mtZ! z$B(cRN6W9c8i(C8$Q)~@=E_p*(0)!6W3h4P24!fSxSaP@RdX|Hr%jqi-7KZo*7#0e z@8ud-_w)(?5W8pJzE798?fU2>ed*GrvfeFDrt|d2qnzTN&sBFswM|)FriG0b z4K;P3-(FZ-s!hfj;9vDxOx+)Ro-aGxoRp=Lnyg<4REUH`d)|B!_v}C2(2QnfWkrj7 zcjgk$F8`fcDxYX+3W=POiN#zStKX_ab&&GF(iPac(_bSJ~@ivg&%yt)4Zust; zYF;?58lf6>ieII^vDkshdnV%P(-#Z9mM@u>uAYnB)|*G8P&*j&r|VV3KW|BJV+Il5 zHLdWzX0w>yxnt)}+{L@g*oEHpl|?)tw4Yy3 zl*kZ)rtLl>d@jDJ)O`@w*51xyX+$u4+H-Ac zZJz4tK*mMYM~mTk6|f^v@m+Ql2CiWxojz;7d-u-a^XnI#xt6Zp&Gk_tY~0*V21T~e z-nsN#hc<=Ykrg>V**9tEckqN}2c3);Q&EeoyTuefIq|`~M>bs%nUZ z-?$_TpJESvkzh_LuxmZWa^%cgoPSfCq)9op@axyF9r1zUwOoi_4)V*3$OgOfn?5%X|2%qCr9tjO+C37;?iqo893-q$?|mGHTB?k z{zC^2y!@U2>PUWzV!o^*hOQrV+R`G&l-T+3;0e(|>0Y1Iw2g7m9K)Qr!Ou&x!^{r{ zwd{aeQ@!?D^S1x;Xof>u+C!Lh?Y^~QTj+J$#gX+;vYjoN?y`47%0 zmjFXqoPB~A2DfpUj5i`aBLA+nj5=gAv~`hhGq8&lIVMq>*Yrc)#@^=ut)%t-z+73t09H<&iUtIES6HgVAqv zC)rZ}aVH3>MUOO`uI%7)E$cV*n-7o{5fV}fX64a^P?q!@(Izf4#Hc>z%=XsBBXy09 z`geD-%uy_Z?7w|{$|>patYJRXsk=ZWTyZ(`@4I&~eE|z4{uWanEeaVkgAI7sz6x2d zvFB7~W4yFhl(2!j3GsJtm}b+Vtv;L2dWR8Fwf(k_&vR@K#hloI&-ncLI*$S;-qfY! zioyhgFg10XC>$OZ)>#p-@+>;~)hYAROr6xLF6Km!VNGO34%SDtL%0K}a!REw&!*uV z+;zkFedsFeyyFLV>}4NmlJ4t(e8$GfNjLNh(N;>d^#F4&UH4vN!EKJ!6w5Mh{E>39lLg^Av9W!*K8^7#Ia-V?aQzF%M4#= z{bSp{&3N^%s=jO3q?`01Ra)y~Q(ax_>B`lYLVB<4+R{`EYb}D-Fp!8HCVEQfpWmdW zmtDNO)1<<`@H=!Q zXB)Tx%s6x?4W_}Nr`Qeq<*!}YVZcn|Ai0M;eApWAT468LQjYPg4q+?2Rd)cQ^K;I8 zQqa2Z+WN{Q&ZH1$v)}}ntzrK0SE*QaoN@lE`EhCnC=jMR`3jU)G}St(hVdYO`i-*( zr2X#KR(FLBvoqO53`f=$`WA3&_x2vHcap*ft}P=~VR>%UT4ugcq9xOJcIea!0|!qe zcmKlld)6D9^YMl2Vi@al^@v6poI(Dp(muaj_2ZEh_07?ZGUD+b+~&4|lLQ0hTHBT+ zXYXtSykU1fI=q(YM@^Du7SDDWD@<^EdnUpCC`cbWc8N>crO{|5LjT339RYK#%J*wu zX~e&>Z+|6|Ej@`wGkp$d1roM|@I;^8{Pd~cA*`$SJe6hlQ&*U*w3Lyty>i9inE-Rb zw-W9{Gg&q@bI;RzoF|_&+!8N|TEw80#W&AIebL%?@NGGEzT-X%7qe=9{Qlv4!S}Mz zEfzaCkKFhW$x}JTdR4`$d3K}XUC`?0S#O#3XSSG?xC^qZQZEdCJJLs&`QwiZHg_8i z+1=PY2EMnP_u2Vc#pdqaz0wCz#TIXjf67>k5AK52m@@VJ3j0qwZSm3tonL_hiHW6( z=Pdwzqg>mQCr(hOUIHJzBSwfnR(%I2H_D9f^OpZw4`;S;^YLY{Si0)ZR6jzVAsAm9 zK-16C9o)*oiXw1TG;YlF4Q<}rZJM|`Drkv}Ep%?b8p0C+p}h+>)c-Ji7)g*tCrw(a~;9XKUgU~OsGcl`64%Uv=u5ovGlpfC)ta4DB= zeIK2zclabc_S$WJ+86#UVXU`oZSjw-#x}hGqaW%byGgFO1PE&kBbwfxK_u8(kOA}W zmAJZjA_{efYo9kt4H^)f*D5;rrSO$3r>?wil6SIt*laZlb$a{u?bmE)3uAJhr`JdM zUX|NClfoao`^)3TeKxjedJ<_eS|EUA9~rp3gckg8g5Bgc>bAmp{}FGpt9D;Zi;|?8BLjMVQFZ>>Y(^p{=(brDB8fuor_ydCOr0U9kZf!`` zaZ=%@{_D`Qx4(YY;W>X>JCsXKYilHG=bf7;p~NLlmXR{6em+9=pZE4S7hoD}V}^Ge zx&*xMem5$5^W7T_iK|<7-`M;W7QsP*JDc?jg?g*?1g?7E>!Z^Z+5n(z#AC<8IHK78 zdGAnbK2bB^H1>r{Fu;kY+OlmWs=;zuNB8XddTPp0gyg?Y0RM-u=$`%O2f&4%TySZE z?~(UJPuA5?&XTo~Oy7gyxwXxai~xneY8%DXqsIMqqO@^SoyUKXW-Z%>Gfq}oUuinL zCNw%b8TR%0gL2-Qe^>OgeQ=j4|D5-oN$W0jL@y=8H#X)162%2=th)rAa_IeFE$6i~ zSoe7ayBb3Ee|9UZrj545Bzu24NNHF-Jm{UBxn%l77|~t?PW{5}8{)A5R#IWjH?Z<6 z%Y`C97jJa>-o1NSkPEv@JTeRviWFDIB=EQH;#>YF-n(9}l_;CuoG2%9?wr1Psb}kG zdqz%oz+jZoAr6i#VFR2UtrUY@8jLZ391H1K15&Q1NMNdunK@d{%eVIQLOK4d-$1Ce zKFGd1wr~F&I#7yXbfl>qgyM|1ZHhC=yY;Zjho|u1!Go!qiL%DcyLa!_F*8dL$nqNR zmUaL3z$yUUl0>F?_vL)~as&SyvhXX-L>vNCFpN$FXPMT@bLdgeKI6`1(W<3HN;*+p zy(zKd*JW{f5$$gp2c38l&bwU#3~dNYP!b?D>ACaDq@9Jc_5ASCG}GIu@%h>1k<@Te zivQ|#EvEvuz`ze;9A{1{l5+0;hH0GeC(18{0+41MZqn(wIy>pKFR^-D)DX?+c#t}4 zzDBd^2ufAt%rQ{5{&tdAxsS&*>BF}=*8|@}?@sRbIQzp}I-$$St3<+Ob#WTOqc92Q z(9PTm^PjD~nBR~p20(=jz?-P3rfX~asyRsk4*;L>9Ri1QNoxY(M=9|b?s%oa70Rd7 zi_3ZZcweG|pP_5zTG37x&a~`o(L}`nlfCSspZ?i>uqUMNB(D*rD=e|~x~!vK1S_w6 zrh?x*WdB+Mt(MnM{SmvEu7d+EaIt^a+FZL9>j0)h6V&uV*FHs{WM9n%#d@myLSXB&(c8x4_xrQ+@{1Fz>0=AEKj%Q%v1f$X z-P*%hJuuN%2y@UB_iqvWcv|o77QM!Z0_&#(K`1YyKlP*hDO*tM!ZPb+=EjZQrX3ls zmUTmXaY`Gj9!$RTA90Ph#EsWd-FsVn`;@O-5juMGox26}s(JbOEY{eGl3@Xr+=^wK zX|l%gNCXN(WP-el_Z)4DF6HOv$9(;;`^ukxA{h%q@6Z9cpdW)sddUsXgi>LiVy3yO z2Q(`aLlfmF#{~t20GUoLt3)0jU74&jikEWkAi7#&#=FV=i?WUx@VZI9ZRk!`?#y?0 zcR7-A1}0@bZ;*DunOelrc^H=AKyA2)xVWzGV5khxy@d{Bu=Yfl*1E?w*@oA4w02K< z`j;oFX?4ct7v5Uw?eZzfXFYc8m?yNjYCKP$KE2Nzc0ZS!l${ZwsI+66hjhFDZ&?gI z?d{tO0Sh$m(*FBg0xI#+uALtq9>gq8S%FXEBTl(o%+c2Zk z{wmg01rZ4=t)=2I6Fo8wrv#MiEbC^eN@}{dZvzJlpLtt3o8LD#e=R}!DtcP3)Fv0t zFmuB=_x|&D4#mPx!;wNTSX*XFI(MIA;Sm2|Ro2{XPc6!U$WwsnajbtPRNvUx5yB>N zh=*s~a3kQIT};6VYx?()ZEkLfzfyZ6J`jS)HzMEiK$d^o;yKxC9(h8`5b_=Lo2k%Ta3n4CZLAvswcybD z@}6n3dC5SS+}tuFS42|M0LadK`SwnuX;MfnEl^Dt+D5X+DTR{GPH3*4MMb5bwXU)2 zE%RL-ig)F%VPq#3IaBG0-o0;nZZhB0^0q@qAh!EP>M~etUUuc9xsG?c58wRJ+E8m} z+}U%-kH`*;F3QSPLh?nZ4(Qv`AnBBnE5x)YMREg!c0AW~Yr}YQ=(nrwEELSO1bqXY zmcGh)jkXE0aGtvcV$P@c_x3Ws+}%$H8X|%qh^u=4{#k5n)?o{uqn2+<^9{?^Lh}bj zU8qamMT(F{od}6*>qp!?D~Lhf#rZW5Dycs5OA|f^|J5BYSRpVW(6;~mJ@NP^oMmMN zgyt=b$b&NCqB+ScXPLz zp_#>(L=hBH^L}+rqw{CI2MT#Eqvd%l(ZemtN|pzYt82s3gKq0vo-=sr;)=+&{l z%1WpbxqH}zzlj)ncZLuv-HH;bo#i%~J2N2hH5KOf@hPuK$@Wnz<$8<M;z68?iyUau z(&y1(u9#EiGs`AJZ%bAmJL?E%&C(l+d1%YUX<;nii{}NED_fDK=0e5Ok$+oV`t%zWreM`q+*wy?l4 z06;yzyuIj5%QK#KbGyRx(_?V*l1`Lx7EneG9j{+Bc&Gq;I(z7PX?9#MyLpGz=BM4c zd0cKFuYI6r>o4amYIXbn3)tK|8--H3`2DGVyzqb8iQCyQaA!Wy;BrLAHw|41OY^zu z|Knc2ELZ(%)&IAU`v37M|I|iW(y36$cl4_LN*zF-q*Mj(7XfI|)zu|zL`ZNc?%zrC zpKU@o%$KRDm|7n1OhD7D48-yYl0yMlnZ~>Fl|gb>)zC1ov&($>@@2=%D|<1cZC8Ne z(uG&7c#cQb*_T1D8&QB|I*6H<>aQ$J8eO{dH^NK6LNo{FHru4oVbFk9RO>;V5g-7t za)j)=%%oT%bw|y2B3U_{mrU#n#3#ym)4#mCi;#a%Qjs+FwGPN&4*V;Kw>?1%$ zM%YJ9YGG9JQe(^F=F_W6Z6c1=_9cSof0O$J(IJu;y`7kQEAq}>QS;7mED)S8f!?K; zFZAj`D@3Jm2(C5S=J)yxuxKPJnuFBtX{-#n9w9GwA3Xk9kj-51XntPa9Dr5_0BZMZ zw{6>2=)dF+1oP*K=lD`*-#Ao~q+@iF--JvC#`nNwurnUlOvsFtKnp_^9WAMN-m?05 z)AW+!)6iV(WPU?@bQZ%n$6rnqKo*Ih2^L!lWLh?m*T#Z-G zlRQ8)DFjwGoZgfRq~S=ksY~lZUr_GcoF@?Idhl#+KI_lV zTAy?56om?)X44RD0Lcd_=#F1MJoFkqWt{gXmFVhyJ?8ZArqkwjz%j^Vf*oLJB$28WcGpa8cD`xEb^PKKC_*)?AB- zK4tE3eWGD$GrgKse(xiZ5UZjtcun+l^-G3@1x&r$1s=dW5$}Skj!b#*vjL&*@wq4m z$Ufr$m!9G`{k};8Q2|yE1~{G6`vzS+-aS^{78B!|Zz~eCek_@{%tuH^ ztqr=3q^P$S=_|koF2x1Ot2_^blx8fqo38S3=F`x00${8e|mEE!QRU) zNebij(2IVXo^=O^ZGAm(ebu+h-Lm<_&$Pv+-vI@z%mXBbsu`%NK4uhJVD?ecohLl%9YjVT%yLz zZtmD94t$ER39vk>Uzb4$@lv7^5}dAE0K*^NeOo{LDS&BWi>aS0&brIYOF~5N)Zij}U-%6mCUGRJ1W; z+yb1BuUA3L$}3ZX`BBC!yDNIIk$mc`n08s_e7dX;lR}4NZ0RXLFUb zd^mR2o&@sc8PTBW>cdgbo~42Op#T|)mpuBvd*JPUj2z;a3lBGt`aq>P4%CD~0V6{M z7h)KOG~eMwM7|QR?=Ga;R` zmKQs6w0x#sWXGq=!vN=RUax>^CnzXrKR?zLk>)}xT`HhK{@{wvz5eDBo3OriIhN^J z#UkxvmV0_wPq=h?lLkT5CfQ|FL6;ex<^uvO$)vV4+>>C2txg1~B=zGj+yCcHbB^iSSroT|zFb znIxYDl8w;$^VcB?J}E5pq(bt~gzkX1b}+Nt45&{K6{FXgxj~~)$AnFbvg6L#Bf75L z$fpI~T*I(z05+Uv~t*Y)rsd`qi_;oLz@}?eA%=<6u{t}1KK=%$?XjcZV z>AzBseaZSSVE`@8Rwyy3l;;mZLk%|8*9?#*o^|tl?MrSTlAL^ph;x1uCCW#S9^JEd zuO5Uo6JV-IVt&v@AW*0QdstWy+zgptalEgxkIo%gClFbe21;Y5_hc`;OJWr{vUdMI2yjERT@|XzKz&o5^VD60Bp@ zOn&7syDxA5ij()v1DX`rNu^Qnand_;;s+BT(_(-%SzB44K(8$NunRszNJ^^HJqi54 z0?6Wq%GwF|FUvA;=?XXtVC6*^kV=N*nrs^!0lpd5UJd8XL53O1@F$S!vI&zk67fDO z4-TjugbP(wSMMlx8<3xf&p-e8yquDhlpzcq5j#JIFl`I~V4UK&9$*(Ha=>e2LO%l4 z4Cu51>sr?Iv^2Y_`z#?aMS!r%!uD=14@+^$BWJ2bRpi(e5-01Ay~KSZv7)Ao>cIC{ zf3t%6QZZmfbwkPixd^1$7$(A`AUZI#Nlrp?0H`_7+1*gN#L6N5XO2l>8@Lp52#HET z6@hC^qqW)Oje=*f>c<116oF%wXb|At>x+~bG^V`nR$hS>G;-gGMZkOJ^A{n(M(7h= z%<+je6LU=l++jB*WP?6FIqJ||kOicolfnACU3_+Z6#*u%Z~P@71gw9CW}@!BJ#3=G z2#t<-VvNipJg2{2p?S7zAheel9X-Bd$Br%q zzVogx1lUEdr!+RI=Tdt~ z-nobw2cDV%&E4!p*Uej^NB|9@eaRsEdh3~o@kaXk&-z(=fql-`KA2s?8@Ol%hSd=u z0*SC;=%(*gf|xhlfR2t1gk}NO#dShNL4oFO0e}@eDY@3QVWSWeoN`{-0A>y%1||z4 zt<2X0X`W!5KLLgcXx$Wy-(ntr2imayib$ce;0)+M;My?2ItS2lyeNU|OT+Z;LOjKp zYrGp%8?-*lhqR%Rj-C3@M+z7VUiT^Dc?$D|A=2U&pQA`c7`0GkEZ7AiN$aJ%3nJKrD! zhL85urCCG}FfYD+5hli@)H4ftWYDdAXno>Z(uz-o_tcyGm z1%^RL7oofg-S`UMgTbk@me^52jd-c=L@^*^@R=c=He|rO2F|&Ey9SEm1*2RGvSrX( zIuOcDr(!3X7XN{%Xxp%!Y#zX6&#s48?mxC?t4n4|Z07aPkBx0j;)d?O$b2xUCDzEE z{YhP{%D!Zqm}$bTuTsLwIW^I4+=oRyj+)g^WMAcxEY#Ve(iB>~{GY6tYCIbfOMl5*09ucbg63B%mv5{DdKKEB*wUhK8r z-rhJ_3=URS(>(FqUN2BygioH-hF)TDU?3IT(;y7SCRQam=0{a=Ir7x>M0bX;Qf4rg9ASfzM%0E+IeOVuV&$>$v zaLz$teg%sc;l{zgnDx{Vhv$@X$^>X)2W$N}v)pe12kmF+(olRM%{9=Rf9F|1yGEyn;+}(SirJ>#Dwau0Oh?f;m7=5Fu#DTt2e;^F(6BGp1E-$-7#7~ zP;j(lIH?^GB5(I!f|1k`Gbzx9mJR&iCp41ejaTN!!6l&}=`(eM?a-lTe5OTXW55T& zR@qa0e0+uW?N_0sz-9+2Im-IliX>=6ON)yiYipH(?L=PDm=`itTuYeBm4!u8jwlE}Bi93a+`AkK5NMc}AhQz)o;_`r>oYMkSl9px#V-W> zgh1L9fQ4{yc-XNs+xWOOtR5uH5MvwSGX!=fltbd`ix)4BPg2CVX1mj!V?>Q_=8c=c zlI#RfcL;0-P@C7lNLt^}AYuOxVzU+y_!A(fJ`kS3yCA*>P<#^4yS=Al)Y_mJMMXs1 z%2! z`I(R&y~8iApvPc@O806*dZ<%`nvAr%ynbV63tea?h|2=NOj5wS zF>sCgMa3v7n5NC>j5ZEIlItb=+z@@58OiUomr+__-vjc^YxVpB6_g9#YgPSY$8pi=a zPKQ;|0l+>J5JGH61^C!GTdcxkECY=Jy2CbKv4+Y8u&{`nI@LVn25?7DMdcyz1f~|$ zVz*S6vgxbPT+m*qUrp7~lAr#ktgP(YJ zgA`a*?Nk5)mK^;<zzy$X>66r-)CX^~UcOAsI8 zJ6tN3Y$G|cpbT?LyCihIflRTC$i?!tg$);Sjq_{1RfIuP1k!kvXW?kz_)Lpr7RVce zm8TrfTbeq8JT5LF;V7tf<^Dd7n}&}bJUFwWwl!Kk?wkrZM1(h%kPrehx@pdmKo*!b z$;)93=wM^XqUIhLvp%S4l3rui0UKsJSZ#)w-#MT%l1wTC%aKW81vRzQRt3lwP;LcO zkZ@x52lL_Jj=+-o1`Nnd5a?saf`ILRr11)%ef(+wY0PhDFQlxoi68mD{=2`JgKa#G@pFR0+|c!!h&mkD?trrqiav(R_(`D=q}aMtIN0&C6F{JlNRS(vdO= z@kU-xvQ+_i8EV|rCMkyv0FDi5FOmY6?SmzLV2I30zycQ(3=$iZ)Qn=@F{h?pudG6I zVc>Fmd1)!OX-{+-6i0*4Zwu2w0AQ1PvbMSkjx6h$iS9hDz`($J!y~P!!C`z#1i&Bk zPcJT)G6@$?$ zc+q&L(04bqft^77T>z^j?LNJAqDr*Lry?aJS;d3~%N;ZJ`D~<#O)r~S6oXn|A8CwK zM1)T^uhoK>efaR93Ah5FgX&jJ-oW++ZImP19DscG6bQzE1DX9QJ zV7u{yeNRCkS}XV^I#MofgQB0?Ch3S&Ww`rm5fGCZq=`~B{;Q9*0epOSH`JX-eg+v0 z!DHYOv!f8q*<;*_l%1TizYYu_9Sh>k0&)ZCSl|^lE-uGBSCZE_(y)NJ8`+l$Pfe7a zfT7F=WeHK%plo*&U6YYy3ImzrpIlsgzPhFc(fE+flP)d7ckFe@F#x?bbX2Z7MuVdu9w_s|W@skS}6_CZU@RdGsis zk$^lDcy{4IL{6VRP0BZE&(Pw7Zu=zc&4qp$QCdAc3#tYz7%;IEFwcyY4&f~N09SZ^ z`}jN5uIsdnXacnUv3VakOZjEC%j1^XaUt^fXe zE25IYv3eF3Nvz!GQ(%(L7}84%katEw&o_kg4uXq^zzj})HU=&d&d z*|8m3b#Dkw9pnxXrP^)aD%eT7F>5X^E;CGKPEjlYYLDKhF34yF*d`ksHUOd+3y;u%KKmoVEUt-f4^MP{mc}#Lblc~(ZJU?;9whc4M?fj+R-Xj}KJ9Z!g0Mf>JHbsMeYY*<3Wja2$(|T$Lut9wFe@uIZSW-*GF~muFvtJZhVFM`e}kjGB7jCR_68nbA5e%W_GsS zI$Yru#4f0;lOXu=aYbh8)V8D;ZbJ(v}{NqRX_Vx;d?yp}DUxe;J+YuI20?&))td@l|MYJ-r zU*^XVboTE+3SkVudJqvF9u9dK{>$g@YScC{F?pookX$&K@@nECf1fXa3^4jU6izmE zUtP(5ILt&)1azT=;igYZr~Gn-%?4#&&-uN;wY-P2MFz--?6ZRdSkXV8$${%Ta7K2w zT~SsR0kIW0io*N>eLK)5o5QqIA78aj4|n^Pq(A6y17r$}%!V-EX>!wKJ~RT$?aAxk z#*Q%W4m~+~ncLyF zuL}ck9FVv%zyT-nq<3p1oY&b{rc`=DN=7SZ&6+LAJi)Dt0wSja>4bP}98PllxM=?O zi`twyqOYra4F0em$G-bBu`Wf?M=L5U4CMk>i(ykM!ag8#3{FO<@3z)sG?Ec0^9E44 zzA+d`-axY4@d0x=0@MjWnN4P3?Vtcahco$MO~KYa;^-DCUV|36Dr2zVDbR+J1RFfx2(LJjh+1!z`g1rM21yw zj*N=~GySR94rH4?>~e(XZk=$&SOX&Np(n* z1t|)dZ-kN_TShcma6_D67P-?SQSCP$+4Y&HBHFX4QFL1Fs;5|l6!GnW? zK>l_(9EU~(wwqm72!bI*n(|$|J{JH942I@@`lJorlc7*Xj$``gI zzsjHwl~8eg(HhxFim-{`MJd@c8J|;HxHeXP!luw|pk@@@cCD?c%2DtKfe_m1{(WJ7 z{wjJ2lBvOljOe1`oT1PKMi7Zaa9sc(Nkcr$0E@wnYKW-*6~|3w#K>byNlvuGju1nV z_H6=SUmgLon>K7#fQG=f$Pziw)4cUHRR*<{Cv( zhttQWTk_Sr8?Qg#$x^4?ID@!{;V&c%7Qz~^hiza;GgC{1aC(g__xhhRaZ zO9==_k={WdAOy&_4+8ot@B6O*`tDkegSp(?d+s^=?D9O%CJ~6RDq0}QhgfK&T)Ekl zIP02juRmf9AS$#ySFu$A+7=Z@(JB_a4?6|8FMQXEF&XBNA<2V%VBelS21+!D#fgsN zdQiE2`9wKr{EJqb+N<=@nXme=rWYZWfyDA<=TR^|Kp|6}J2%{Id)m6|5=5!>BOQkT zQl7@-KCPHx%{IkxwGNa??4it!2+IzmD+njS_W^GzVm98rV5$aW+&Oich&SZ*8hrD< zVyc0J0|vCh6jmgpF;!qGMbGL(A zk?PM37>4he{Qmtpb3kAqkj*z4@quy6_#Rpdsy^jPu;t4Rq2B=GU=L{PkWyA=W~cy5 zxQrLhGGifBLy;>GZke%=WBLrCWCJi_^Cwkiv_=3-{xftxFMuqF4e*;`M$rZe;KC__#Mq07rVT+K%rDSpb%Dr_PWe%S-`+A=mJGtrq#Rb8~Zur-A~7 z2evB_O!X!3S9Fkj>dh!@q(p@^%1CbuKoTh|_DuXJY^K>?ZM?8mEr~MH5bM8zF$^I$ zC2B@Oq^81oYrEAnUajwyfAjwqR9*Ko2ed?{5PLeyD@Ic`Tm2&1k}D*7Bq3YVo1vD( zcb!`&=bH5C6yoc!JML={|_@m1Uv40Rk9YvjxKe4)1 zi4r}K6;_3kGn5Z9VHZIJ8+% zl{Rm$H-+eH5Vm|a4vq#e4an$*ER;N+|8e*O@YBJuMVQ3^z@$PV5LWR;#OW_tWT$fQ zn$%r_P%@xs#T|&?dJX=tT&nFXlQS=FTXXjj2FNS+{Atua5=FNGMNl)VgUWQzBsegUF19jpcax#xbuG{}Du;1RPjb4l>tQ zuRbKFarCC!?L=tU|0&Y@I%XPQE=u%|Jv%D^5%;TCukvQwU3EtpkUv$E_urT&N77R6&ciNka$S)Zi0yu%k( zWZr&YoMa@?cH{KH#G;NyJw%oOY-*-i^Vtk@*d`Dx0%z@Ppne+mNLXhw2pyFX*O>wXbYQJ5;`{I)BudK`Q5UR{39gLGOME=0X5l92ViL&ccRKQ7Z#8n+&2C!6XN(-v09m^BI2~KAZ?>DMD&$ z>V4mpj2@pCtUAF9_8jZBH{BdhZ_N4%S^+~HB$5Sb(Sbm%g!)p4+mviTjiS0cbu`;$ zs!AY?F|yr?ynMye9!qY8;08|4%&37S+|Ilj((IQ$zu`RRb=YrKj?TEpfu0VI7g;br z+6?B_>h}tJGyoVG>Ukn!<$f^dWl_FH?sNZGekkMWKY~$*kZk$!?Qw^0-F@3R@+a{a zL`txQKtQo?%oN5Q|Mlw+(kkZkeA|ccYa2ZGr2b(yic+(v9OdldBIOGs4cTlV#Ix(O zz7knGl3_Q9Kx2vgH&$*QqhK;ty#s?GNph^y%|~pkmoEc`vcT1KY-go4`dJ!EYZ_rM_3(jN6MgLBqkL##Vh3tsA=$nIgkel2{P`ER}dJ1B}SMV@P3g%7bM2P2}ks|4C`dwJ|~FsSy~gr z^3Q^6f_QXb&LN>)2jG-|@Nh^@8#UWkfsczIIv@c!4R{wIC`v+r?dB#80Rwvx(tW8^9nkM<1Voo?Fv(X1k`<3W ztbTn1$MPBy1_{b=fCmSrK?#JTF(V^m-@${otV3dB-Fco6c;tiD()5H3pA@tS0l(`4 znDGV(K zm%Srnfw=z@3jpp=Xhd9Ugw~7OSv~N(!0~FW1Pq&{I_!8dxJ`H84he#5iAti_QDBB7 z1wIM*j_}nG5kW4_Kc7n8$iY_s$>9hy&A%^Qf1y;{AzykMu&?q1D7VN#dNsj=loqcEMl zc%1&%o$qD`AfOP|1q?CD+6TORsZnJ9U!4HvyQ0p?Z5Hy2F8_7IO*UYB{_4U+SW2$!&S===ehKdW_mdU^0c#|h zgAssNLJlj0RvD4MK0}ZbuD_2Sy)a%d^{nrgJ@1p-h(69tR#~?dW7%e(o3H z;oS1_^2YG)R}Op3avBqs1kt8f3LyypWk8m1N<|hjO;8pj16Uh!0>9n$%5b7QkgxCV z-!J`x_WN^yc+H_HY0b+*1Uk@I!W4RQBpl*oS4JkVWss9BRT6t|g zC_xKIQ#Gh-{u=j{31JJ#H~`exIIPVxh0Xt&Th{S}`Vk-`21eH2c5&JAs1JY)7u1Zv zpbY<-;Kh%YKf8MM>Sy8cg5%&N7XnA)w;K!n(AEsE$lD8G60pA@>^-;!zYU+&Ze-in zBT6d-K#(f?@N2Po?n(QD7n9=&F>x?ybtKX3UORHOE>BlLUR2cA*Z=!;9ZKu!x`AM4 z5C-}EJ|M-*H>HY_sDSN298;(~{dU(sSAjf2AwUTI`(@w3BwIUv!mU<+{J-Du>X|Dz zt<@j@fBd4AqXS$;!J{`i>gtt9ScepE*WpH7Lt*~vnk?Q}iwX#;4kFASns<4+l({yX zY)f@W`t>;)^@wph{_gP2rJ_2c*?x8F_`ZZ^Y&3)yQy zXomY7al6s-3#eC(H{LGHpH2zOhc%(CedyPnV;tbh7N3h{fs+rCh@9H{Tsjos@?{;Q zr`2KN`t0j|J9j3n88b6G+XP|U^gy@#Kt63w@9w6r?2zKl%(MfKKQHU-nmxl{My_S7 zB2~kl|1^A_R8~5$oPnKGC_Epdik zf%Dx-+2@3}{=AHWCA<~sy1Jd>jSJb`_GbiOzp?10bl_zPwb$U3#*tR4C6u)jXoVZX z7&ns5W~;-er`kn_8pBvtY>2`>euiR11`Y4-sEygK&z36jprss=a@Xo}L(M4pj?bQ4 zF=oABpTFp>*RoW#f6crPal**nd3SN6{n(``@W2{Q1sT^o9!nW67jbQD-u3eaJzXk{ zHssh7)P`F4G=>Gt8lJtq+xx9HH48wfBfK=Puoe#yY4Mm>4i0-4b|euMw&76#re*k{nCMP@N0;BoiDaHsJ=K?5$1xw zDWC7nqc=seIuSsvSlzH>U}*F6^XmsTdJ37*zH<~(6vX*#EF<=}KP8xdWfIt^)~aD; zPD@i5wpP9tO<(NmZySGJzN1MeL%db*QREYj4Wo|-R&fkFV2W?TG?>GqswtN3+sJF$ zHFDBZLd!{@F-7wLd$xaW?WeP!xgIWY{~Wi@g96$NKtMi5b717a15WmRfYQ_^BrQoU za(6w%QTdMdAl-iP^X4ysjDh$8)*;cxxkxK?pQz#EJ9%H3Esy9Eacx%?=VzPPQ$7rV z50^ac#PpQDB2uw?t0^%kKAp{v$U+V{yz-(5>1e@5+?HDiR$Ib~PkObx3S8L3DyE`6 z2exx!B%=lgNF23n2AX4E5AjGu3<96S>IP@K5!@6;rkXliGhTY+QkNd_sT-KE8f}^5 zHhd)-8IE7L&|Uhpo_fSBLfEC@{_akNQGccip-LuT@kQ)Hf@7+JKi2x#^2@H6W0nfO3NdTDZfn zpn{T8u$vGS#kY0Kmgi72LGW6@JDmit%7eDRLnu{?wl=BJ;0t=Rx|4bitA4>0wOf+H zROV~x_$DXf9*ID|G@Sw`MR~Egs6Y#{U=uvf2=PrSYETvCq}Z#|$i_A-fS z;ghr~QdCXvJ@9FSf03Cn85xZJ_)1U6dLf6&>007~7Ez7LAUptMV^ukatmY!$avyX` z?3+m0k63x>dH_!LjvrCbBaDb5fXX|7jCcj&apXMWm8V;q0JLGQz9WOWVk;t~*xWW- z^@muVqS=k?PITQwSNFs?1^}kn$hwXoDm1FpLJc-Ex8unnp1ptl^*10-5VRCfY()RR zNb0DlQ&OWWFRI#m=IQ<=?2?e??2Z9T>ky&`(?Ke2@1eN}xg`gk4t$2{Inb_|$~CT< z$*_|%J$JawKR7T(@mu7+U1zj5?_5Z{yBV+cV?dGq9Ggx&6fLQ`)g)%D3$A>xEdH33 zWPSbgBF#))Z^^I<|81k+nTnahP>=Y9sU_D(EUhr{k`M8`Qgm@i@by&-(FqZSmQv4; zKZg8%4PalpOV3VMWto>()YN}c{N~V`vsARQcf`>bzF?;$_@ecAEuW&!yn!x;g(8>`P!&40OMluBxi)4Ku?iNFstI zqFm_H=GEb;zI>g9su+v755Nb&f`YFfx$cQeNelIcw6rwiyk#JQX@1SM-CvrT-FG#H zQ#+fDYi3`@A~4tEe>k?EA#{K^0(SJ{%&0xch)5Y1MoR9?=h4cOY|V0y6zHqsiMQXf zRcYzO6zzTw>D14S)iYT6`Ua<_F^}P(Lp7)PI8}WcPQ-cbXZbKZ)0)@hB#7~J2T%kI z>@^T~$&@PH$t0oy2;8fb`|FdhkIo@x8yGj8=rbvD7=Cl+cB}W>=SO?6_9F*xH64V~ zm&*x$Iem|?HvqRAfQ)_96U*1PamH28WgxMLYl|T^=a?^OLwTSzu{~2$*)Le~xDTP~ zyOa@SdNMPot=-ihQvCZlwZ9Pm$ryE~+sCxxI1~$oj3YR)OILh+FymCH9AnMr`0hi& zl&^HMc$=*}0+@&$bD*V@3F*f}besHqnEmv%4S4B$`;4Y&yD<*{mG|~WQbLtJ*0=W7 z%pv--mjD==mQz*N|2?h@*VP;CpCWLIbvSX-hWjMj(i-CHhdzG;G{`O%0RaKcm~G5s?cumO?F<-s0+u!ouRC=5gS4~qKS95L~`6~=Q&08r899YwlO zLqR=`(2j;^N-2di5bC`xftVDLIFST4)KCvI)hJC(+;nAV@o$IfzP3fTB=w0xJ@Mrm%+8?f!Fkm5yv0Wg4^-j<=4a7V^Z zUJ>mYHt=-<1yk^c0phwEF2P5(SN z2ExPY9nqupna)5`A|=PEF$N)q5t&^bH+n#Sz$d#sM%->VIf`gXbm^4>R80K4DQyDj z`$rMc{d}5B=9Zr`YD80hY_tp+wH(xf>Fe?1J*U=W(`A>%rvl{H2CTr3lH0W_av$Y~ zfkW@=#xMG-UXwUB-D=57q;|M6V;!e+bj@2gX?#ry3isH4=?_ek)osHI@@A?t0;UyGEphhjY|BclD)i z+wBZYF;Lx=3g2uW0tbI0O={;8*U!z0302WVQ~Mj!xBP-<;}r9*k7}`=__>FicX#-m z?u5@_E-QSqj^9G6vGc+PKAR6#SS3ZpG+&Zj?dNAl$>IB<9Krv>1~c?rO1uJ`1^ri^ z+d73;$iatiOx0*{Lz#5WvNVKacH~>F!c@DHG|X;3rX84T+T(wF@J(8&S4Xdh6whH_ z`!o7a8TeGj|E8+%IWy@~v9w|cB8JSWF=8G|cL4r;UCpw+AQ#g3DL_PM&^V1bUy|o| zE80Ek-|sYe>q3!Yfx-qZb!wJwf%y&s>a#(vDw4j-tfk?8mk|(Ntnv>7l1r z0@)oexW)c_H=YJ&{GP2@+W}q}F9iKtyl>z3jcUlWi;j-fcHapaw=*K(r6W%|c(K`G z@g;7_`&&Ye$wx{0nUBG^L)(&T>KJ4mkaDkFQ5|C}2FKps^_poF-SBnV1&(#2!9V0y zg0Kf)z~KfHHWsSB*GB&($bqq7Tk>a(7Y*Nr_x63%W?dJ-A~5-n#Ya8U0Sk z(Or9_FD=d}=yX2YuJAIHvJ!fH>*KthuyJyd-`*vCs!0jRc)v2YDS=g+CLp-wrHwk> zYZu5Y=v#T$?$obI=uJ7Dhq!XsK0oQf%%W@dQlYU=dPaIE<7RSHba?o}f>yltY%7Fs zKQ9-T4X>jnoD>0S4KK-nxJrh~dOZq|PgE=t82OBwPbCN z8~oQm_1uOpRaLUK{RMBHQQrZcNB~>cUMN1yy={p@Kp>>hVC6yJuk)N>rURqE;j&Xt z5vD-s59q;$Deu;R;6Ocw=3ggb0heP#nNgUmn&5^Dj0BSFbz>Iya6v zgvWE6*W*n5`z!7<%^j5SLRa7kM)A>fl7+`dG*R%eb~vO9ZuoMG7dNwwd$_UH1ve+Y z6#sxJIO4AO`16#MomKj4XJXPd~t%He6w*BS@+@a={!xeb;ljH}_~mG4-v&@{t{ThR`R!XIp1eNAOU zo8xR_+^*}sQBmAQ4b@@!rrbwYPKLjVx%fNQxq)!cqQhhqQ}Ag$sEPvSs`kSJriK)t zJ_CD<7_gECK)-cubIA5ExJEE zTa&f_wQJp#b8eebna$hNRg+q>)W?f9OxM%!YEtFr7VV3R>mL3T-di3fg+F%eDFz2O zSZwN?``nzd%e60yAkSTlIiyAa+po{IZuOPI>7m`H*DX-TAK@BK%50}^sIe~uxhAM) zoqU_Re6gSZx!emP)!7z|jN*8mM_6o@=@|gvcnQY?48q^(_m|VJYNcWV{mDiu4-JuH z!;uC&?Yd7_mmIFFYa=MAMDJUE4L`41yajI5mv>@j9f0)0fX>BAAS>j5;s*&|2a^vl zLaWEgI~U#dlCy!EBu)vWi*zTVO)(BYyzb%09^rxje;Cw}Bm zs8yH7qfNhGj2?u+LH2@Equ^2qf3mv9ty?A~VE0!KtJ}?rz0nmf$b!d0dsfmd=rf(o zhgm#9&^a2gsIXGGp?a#Sb!KI6T0Wt3;?DsPR!hR$K2;;-vgqqdbq(&`wzBV_GZgIL zfkD;h@7gtm2@Ixb%LB>t+DU4Q-C-VsKOXIg-uGL2viR~2M@)ze%i?Toc&6E$l%b(< zylYePP$SVR&wdnI$PW3dJwcaVIav1wWAqBHy<$EkCUzl&-?DbfR$s-T@7B>2tMiKCk85V<%Wn#7pE~g|e!uBOSel)|uaDoWj7a&*rU}YOVZ9 z_8o<@xcWX$7w2Z1q`6Yzyt~Gj-)=Oh>-0LagZEkF-LC-9LCHuhCeMEGjb?qg;;e

5C| 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�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 k`. - -## RLP - -RLP ("recursive length prefix") encoding is the main serialization format used in Ethereum, and is used everywhere - for blocks, transactions, account state data and wire protocol messages. RLP is formally described here: https://github.com/ethereum/wiki/wiki/RLP - -RLP is intended to be a highly minimalistic serialization format; its sole purpose is to store nested arrays of bytes. Unlike [protobuf](https://developers.google.com/protocol-buffers/docs/pythontutorial), [BSON](http://bsonspec.org/) and other existing solutions, RLP does not attempt to define any specific data types such as booleans, floats, doubles or even integers; instead, it simply exists to store structure, in the form of nested arrays, and leaves it up to the protocol to determine the meaning of the arrays. Key/value maps are also not explicitly supported; the semi-official suggestion for supporting key/value maps is to represent such maps as `[[k1, v1], [k2, v2], ...]` where `k1, k2...` are sorted using the standard ordering for strings. - -The alternative to RLP would have been using an existing algorithm such as protobuf or BSON; however, we prefer RLP because of (1) simplicity of implementation, and (2) guaranteed absolute byte-perfect consistency. Key/value maps in many languages don't have an explicit ordering, and floating point formats have many special cases, potentially leading to the same data leading to different encodings and thus different hashes. By developing a protocol in-house we can be assured that it is designed with these goals in mind (this is a general principle that applies also to other parts of the code, eg. the VM). Note that bencode, used by BitTorrent, may have provided a passable alternative for RLP, although its use of decimal encoding for lengths makes it slightly suboptimal compared to the binary RLP. - -## Compression algorithm - -The wire protocol and the database both use a custom compression algorithm to store data. The algorithm can best be described as run-length-encoding zeroes and leaving other values as they are, with the exception of a few special cases for common values like `sha3('')`. For example: - - >>> compress('horse') - 'horse' - >>> compress('donkey dragon 1231231243') - 'donkey dragon 1231231243' - >>> compress('\xf8\xaf\xf8\xab\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbe{b\xd5\xcd\x8d\x87\x97') - '\xf8\xaf\xf8\xab\xa0\xfe\x9e\xbe{b\xd5\xcd\x8d\x87\x97' - >>> compress("\xc5\xd2F\x01\x86\xf7#<\x92~}\xb2\xdc\xc7\x03\xc0\xe5\x00\xb6S\xca\x82';{\xfa\xd8\x04]\x85\xa4p") - '\xfe\x01' - -Before the compression algorithm existed, many parts of the Ethereum protocol had a number of special cases; for example, `sha3` was often overridden so that `sha3('') = ''`, as that would save 64 bytes from not needing to store code or storage in accounts. However, a change was made recently where all of these special cases were removed, making Ethereum data structures much bulkier by default, instead adding the data saving functionality to a layer outside the blockchain protocol by putting it on the wire protocol and seamlessly inserting it into users' database implementations. This adds modularity, simplifying the consensus layer, and also allows continued upgrades to the compression algorithm to be deployed relatively easily (eg. via network protocol versions). - -## Trie Usage - -Warning: this section assumes knowledge of how bloom filters work. For an introduction, see http://en.wikipedia.org/wiki/Bloom_filter - -Every block header in the Ethereum blockchain contains pointers to three tries: the _state trie_, representing the entire state after accessing the block, the _transaction trie_, representing all transactions in the block keyed by index (ie. key 0: the first transaction to execute, key 1: the second transaction, etc), and the _receipt tree_, representing the "receipts" corresponding to each transaction. A receipt for a transaction is an RLP-encoded data structure: - - [ medstate, gas_used, logbloom, logs ] - -Where: - -* `medstate` is the state trie root after processing the transaction -* `gas_used` is the amount of gas used after processing the transaction -* `logs` is a list of items of the form `[address, [topic1, topic2...], data]` that are produced by the `LOG0` ... `LOG4` opcodes during the execution of the transaction (including by the main call and sub-calls). `address` is the address of the contract that produced the log, the topics are up to 4 32-byte values, and the data is an arbitrarily sized byte array. -* `logbloom` is a bloom filter made up of the addresses and topics of all logs in the transaction. - -There is also a bloom in the block header, which is the OR of all of the blooms for the transactions in the block. The purpose of this construction is to make the Ethereum protocol light-client friendly in as many ways as possible. For more details on Ethereum light clients and their use cases, see the [light client page (principles section)](https://github.com/ethereum/wiki/wiki/Light-client-protocol#principles). - -## Uncle incentivization - -The "Greedy Heaviest Observed Subtree" (GHOST) protocol is an innovation [first introduced](http://eprint.iacr.org/2013/881.pdf) by Yonatan Sompolinsky and Aviv Zohar in December 2013, and is the first serious attempt at solving the issues preventing much faster block times. The motivation behind GHOST is that blockchains with fast confirmation times currently suffer from reduced security due to a high stale rate - because blocks take a certain time to propagate through the network, if miner A mines a block and then miner B happens to mine another block before miner A's block propagates to B, miner B's block will end up wasted ("stale") and will not contribute to network security. Furthermore, there is a centralization issue: if miner A is a mining pool with 30% hashpower and B has 10% hashpower, A will have a risk of producing a stale block 70% of the time (since the other 30% of the time A produced the last block and so will get mining data immediately) whereas B will have a risk of producing a stale block 90% of the time. Thus, if the block interval is short enough for the stale rate to be high, A will be substantially more efficient simply by virtue of its size. With these two effects combined, blockchains which produce blocks quickly are very likely to lead to one mining pool having a large enough percentage of the network hashpower to have de facto control over the mining process. - -As described by Sompolinsky and Zohar, GHOST solves the first issue of network security loss by including stale blocks in the calculation of which chain is the "longest"; that is to say, not just the parent and further ancestors of a block, but also the stale descendants of the block's ancestor (in Ethereum jargon, "uncles") are added to the calculation of which block has the largest total proof of work backing it. - -To solve the second issue of centralization bias, we adopt a different strategy: we provide block rewards to stales: a stale block receives 7/8 (87.5%) of its base reward, and the nephew that includes the stale block receives 1/32 (3.125%) of the base reward as an inclusion bounty. Transaction fees, however, are not awarded to uncles or nephews. - -In Ethereum, stale block can only be included as an uncle by up to the seventh-generation descendant of one of its direct siblings, and not any block with a more distant relation. This was done for several reasons. First, unlimited GHOST would include too many complications into the calculation of which uncles for a given block are valid. Second, unlimited uncle incentivization as used in Ethereum removes the incentive for a miner to mine on the main chain and not the chain of a public attacker. Finally, calculations show that restricting to seven levels provides most of the desired effect without many of the negative consequences. - -* A simulator that measures centralization risks is available at https://github.com/ethereum/economic-modeling/blob/master/ghost.py -* A high-level discussion can be found at https://blog.ethereum.org/2014/07/11/toward-a-12-second-block-time/ - -Design decisions in our block time algorithm include: - -* **12 second block time**: 12 seconds was chosen as a time that is as fast as possible, but is at the same time substantially longer than network latency. A [2013 paper](http://www.tik.ee.ethz.ch/file/49318d3f56c1d525aabf7fda78b23fc0/P2P2013_041.pdf) by Decker and Wattenhofer in Zurich measures Bitcoin network latency, and determines that 12.6 seconds is the time it takes for a new block to propagate to 95% of nodes; however, the paper also points out that the bulk of the propagation time is proportional to block size, and thus in a faster currency we can expect the propagation time to be drastically reduced. The constant portion of the propagation interval is about 2 seconds; however, for safety we assume that blocks take 12 seconds to propagate in our analysis. -* **7 block ancestor limit**: this is part of a design goal of wanting to make block history very quickly "forgettable" after a small number of blocks, and 7 blocks has been proven to provide most of the desired effect -* **1 block descendant limit** (eg. `c(c(p(p(p(head)))))`, where c = child and p = parent, is invalid): this is part of a design goal of simplicity, and the simulator above shows that it does not pose large centralization risks. -* **Uncle validity requirements**: uncles have to be valid headers, not valid blocks. This is done for simplicity, and to maintain the model of a blockchain as being a linear data structure (and not a block-DAG, as in Sompolinsky and Zohar's newer models). Requiring uncles to be valid blocks is also a valid approach. -* **Reward distribution**: 7/8 of the base mining reward to the uncle, 1/32 to the nephew, 0% of transaction fees to either. This will make uncle incentivization ineffective from a centralization perspective if fees dominate; however, this is one of the reasons why Ethereum is meant to continue issuing ether for as long as we continue using PoW. - -## Difficulty Update Algorithm - -The difficulty in Ethereum is currently updated according to the following rule: - - diff(genesis) = 2^32 - - diff(block) = diff.block.parent + floor(diff.block.parent / 1024) * - 1 if block.timestamp - block.parent.timestamp < 9 else - -1 if block.timestamp - block.parent.timestamp >= 9 - -The design goals behind the difficulty update rule are: - -* **Fast updating**: the time between blocks should readjust quickly given increasing or decreasing hashpower -* **Low volatility**: the difficulty should not bounce excessively if the hashpower is constant -* **Simplicity**: the algorithm should be relatively simple to implement -* **Low memory**: the algorithm should not rely on more than a few blocks of history, and should include as few "memory variables" as possible. Assume that the last ten blocks, plus all memory variables placed in the block headers of the last ten blocks, are all that is available for the algorithm to work with -* **Non-exploitability**: the algorithm should not excessively encourage miners to fiddle with timestamps, or mining pools to repeatedly add and remove hashpower, in an attempt to maximize their revenue - -We have already determined that our current algorithm is highly suboptimal on low volatility and non-exploitability, and at the very least we plan to switch the timestamps compares to be the parent and grandparent, so that miners only have the incentive to modify timestamps if they are mining two blocks in a row. Another more powerful formula with simulations is located at https://github.com/ethereum/economic-modeling/blob/master/diffadjust/blkdiff.py (the simulator uses Bitcoin mining power, but uses the per-day average for the entire day; it at one point simulates a 95% crash in a single day). - -## Gas and Fees - -Whereas all transactions in Bitcoin are roughly the same, and thus their cost to the network can be modeled to a single unit, transactions in Ethereum are more complex, and so a transaction fee system needs to take into account many ingredients, including cost of bandwidth, cost of storage and cost of computation. Of particular importance is the fact that the Ethereum programming language is Turing-complete, and so transactions may use bandwidth, storage and computation in arbitrary quantities, and the latter may end up being used in quantities that due to the halting problem cannot even be reliably predicted ahead of time. Preventing denial-of-service attacks via infinite loops is a key objective. - -The basic mechanism behind transaction fees is as follows: - -* Every transaction must specify a quantity of "gas" that it is willing to consume (called `startgas`), and the fee that it is willing to pay per unit gas (`gasprice`). At the start of execution, `startgas * gasprice` ether are removed from the transaction sender's account. -* All operations during transaction execution, including database reads and writes, messages, and every computational step taken by the virtual machine consumes a certain quantity of gas. -* If a transaction execution processes fully, consuming less gas than its specified limit, say with `gas_rem` gas remaining, then the transaction executes normally, and at the end of the execution the transaction sender receives a refund of `gas_rem * gasprice` and the miner of the block receives a reward of `(startgas - gas_rem) * gasprice`. -* If a transaction "runs out of gas" mid-execution, then all execution reverts, but the transaction is nevertheless valid, and the only effect of the transaction is to transfer the entire sum `startgas * gasprice` to the miner. -* When a contract sends a message to the other contract, it also has the option to set a gas limit specifically on the sub-execution arising out of that message. If the sub-execution runs out of gas, then the sub-execution is reverted, but the gas is nevertheless consumed. - -Each of the above components is necessary. For example: - -* If transactions did not need to specify a gas limit, then a malicious user could send a transaction that makes a multi-billion round loop, and no one would be able to process it since processing such a transaction would take longer than a block interval, but miners would not be able to tell beforehand, leading to a denial-of-service vulnerability. -* The alternative to strict gas-counting, time-limiting, does not work because it is too highly subjective (some machines are faster than others, and even among identical machines close-calls will always exist) -* The entire value `startgas * gasprice` has to be taken out at the start as a deposit so that there arise no situations where an account "bankrupts" itself mid-execution and becomes unable to pay for its gas costs. Note that balance checking is not sufficient, because an account can send its balance somewhere else. -* If execution did not revert in the event of an insufficient gas error, then contracts would need to take strong and difficult security measures to prevent themselves from being exploited by transactions or messages that provide only enough gas halfway through, thereby leading to some of the changes in a contract execution being executed but not others. -* If sub-limits did not exist, then hostile accounts could enact a denial-of-service attack against other contracts by entering into agreements with them, and then inserting an infinite loop at the beginning of computation so that any attempts by the victim contract to compensate the attack contract or send a message to it would starve the entire transaction execution. -* Requiring transaction senders to pay for gas instead of contracts substantially increases developer usability. Very early versions of Ethereum had contracts pay for gas, but this led to the rather ugly problem that every contract had to implement "guard" code that would make sure that every incoming message compensated the contract with enough ether to pay for the gas that it consumed. - -Note the following particular features in gas costs: - -* 21000 gas is charged for any transaction as a "base fee". This covers the cost of an elliptic curve operation to recover the sender address from the signature as well as the disk and bandwidth space of storing the transaction. -* A transaction can include an unlimited amount of "data", and there exist opcodes in the virtual machine which allow the contract receiving a transaction to access this data. The gas fee for data is 1 gas per zero byte and 5 gas per nonzero byte. This formula arose because we saw that most transaction data in contracts written by users was organized into a series of 32-byte arguments, most of which had many leading zero bytes, and given that such constructions seem inefficient but are actually efficient due to compression algorithms, we wanted to encourage their use in place of more complicated mechanisms which would try to tightly pack arguments according to the expected number of bytes, leading to very substantial complexity increase at compiler level. This is an exception to the sandwich complexity model, but a justified one due to the ratio of cost to benefit. -* The cost of the SSTORE opcode, which sets values in account storage, is either: (i) 20000 gas when changing a zero value to a nonzero value, (ii) 5000 gas when changing a zero value to a zero value or a nonzero value to a nonzero value, or (iii) 5000 gas when changing a nonzero value to a zero value, plus a 20000 gas refund to be given at the end of successful transaction execution (ie. NOT an execution leading to an out-of-gas exception). Refunds are capped at 50% of the total gas spent by a transaction. This provides a small incentive to clear storage, as we noticed that lacking such an incentive many contracts would leave storage unused, leading to quickly increasing bloat, providing most of the benefits of "charging rent" for storage without the cost of losing the assurance that a contract once placed will continue to exist forever. The delayed refund mechanism is necessary to prevent denial-of-service attacks where the attacker sends a transaction with a low amount of gas that repeatedly clears a large number of storage slots as part of a long-running loop, and then runs out of gas, consuming a large amount of verifiers' computing power without actually clearing storage or spending a lot of gas. The 50% cap is needed to ensure that a miner given a transaction with some quantity of gas can still determine an upper bound on the computational time to execute the transaction. -* There is no gas cost to data in messages provided by contracts. This is because there is no need to actually "copy" any data during a message call, as the call data can simply be viewed as a pointer to the parent contract's memory which will not change while the child execution is in progress. -* Memory is an infinitely expandable array. However, there is a gas cost of 1 per 32 bytes of memory expansion, rounding up. -* Some opcodes, whose computation time is highly argument-dependent, have variable gas costs. For example, the gas cost of EXP is 10 + 10 per byte in the exponent (ie. x^0 = 1 gas, x^1 ... x^255 = 2 gas, x^256 ... x^65535 = 3 gas, etc), and the gas cost of the copy opcodes (CALLDATACOPY, CODECOPY, EXTCODECOPY) is 1 + 1 per 32 bytes copies, rounding up (LOG also has a similar rule). The memory expansion gas cost is not sufficient to cover this, as it opens up a quadratic attack (50000 rounds of CALLDATACOPY of 50000 gas ~= 50000^2 computing effort, but only ~50000 gas before the variable gas cost was introduced) -* The CALL opcode (and CALLCODE for symmetry) costs an additional 9000 gas if the value is nonzero. This is because any value transfer causes significant bloat to history storage for an archival node. Note that the actual fee _charged_ is 6700; on top of this we add a mandatory 2300 gas minimum that is automatically given to the recipient. This is in order to ensure that wallets that receive transactions to at least have enough gas to make a log of the transaction. - -The other important part of the gas mechanism is the economics of the gas price itself. The default approach, used in Bitcoin, is to have purely voluntary fees, relying on miners to act as the gatekeepers and set dynamic minimums; the equivalent in Ethereum would be allowing transaction senders to set arbitrary gas costs. This approach has been received very favorably in the Bitcoin community particularly because it is "market-based", allowing supply and demand between miners and transaction senders determine the price. The problem with this line of reasoning is, however, that transaction processing is not a market; although it is intuitively attractive to construe transaction processing as a service that the miner is offering to the sender, in reality every transaction that a miner includes will need to be processed by every node in the network, so the vast majority of the cost of transaction processing is borne by third parties and not the miner that is making the decision of whether or not to include it. Hence, tragedy-of-the-commons problems are very likely to occur. - -Currently, due to a lack of clear information about how miners will behave in reality, we are going with a fairly simple approach: a voting system. Miners have the right to set the gas limit for the current block to be within ~0.0975% (1/1024) of the gas limit of the last block, and so the resulting gas limit should be the median of miners' preferences. The hope is that in the future we will be able to soft-fork this into a more precise algorithm. - -## Virtual Machine - -The Ethereum virtual machine is the engine in which transaction code gets executed, and is the core differentiating feature between Ethereum and other systems. Note that the _virtual machine_ should be considered separately from the _contract and message model_ - for example, the SIGNEXTEND opcode is a feature of the VM, but the fact that contracts can call other contracts and specify gas limits to sub-calls is part of the contract and message model. Design goals in the EVM include: - -* **Simplicity**: as few and as low-level opcodes as possible, as few data types as possible and as few virtual-machine-level constructs as possible -* **Total determinism**: there should be absolutely no room for ambiguity in any part of the VM specification, and the results should be completely deterministic. Additionally, there should be a precise concept of computational step which can be measured so as to compute gas consumption. -* **Space savings**: EVM assembly should be as compact as possible (eg. the 4000 byte base size of default C programs is NOT acceptable) -* **Specialization to expected applications**: the ability to handle 20-byte addresses and custom cryptography with 32-byte values, modular arithmetic used in custom cryptography, read block and transaction data, interact with state, etc -* **Simple security**: it should be easy to come up with a gas cost model for operations that makes the VM non-exploitable -* **Optimization-friendliness**: it should be easy to apply optimizations so that JIT-compiled and otherwise sped-up versions of the VM can be built. - -Some particular design decisions that were made: - -* **Temporary/permanent storage distinction** - a distinction exists between temporary storage, which exists within each instance of the VM and disappears when VM execution finishes, and permanent storage, which exists on the blockchain state level on a per-account basis. For example, suppose the following tree of execution takes place (using S for permanent storage and M for temporary): (i) A calls B, (ii) B sets `B.S[0] = 5`, `B.M[0] = 9`, (iii) B calls C, (iv) C calls B. At this point, if B tries to read `B.S[0]`, it will receive the value stored in B earlier, 5, but is B tries to read `B.M[0]` it will receive 0 because it is a new instance of the virtual machine with fresh temporary storage. If B now sets `B.M[0] = 13` and `B.S[0] = 17` in this inner call, and then both this inner call and C's call terminate, bringing the execution back to B's outer call, then B reading M will see `B.M[0] = 9` (since the last time this value was set was in the same VM execution instance) and `B.S[0] = 17`. If B's outer call ends and A calls B again, then B will see `B.M[0] = 0` and `B.S[0] = 17`. The purpose of this distinction is to (1) provide each execution instance with its own memory that is not subject to corruption by recursive calls, making secure programming easier, and (2) to provide a form of memory which can be manipulated very quickly, as storage updates are necessarily slow due to the need to modify the trie. -* **Stack/memory model** - the decision was made early on to have three types of computational state (aside from the program counter which points to the next instruction): stack (a standard LIFO stack of 32-byte values), memory (an infinitely expandable temporary byte array) and storage (permanent storage). On the temporary storage side, the alternative to stack and memory is a memory-only paradigm, or some hybrid of registers and memory (not very different, as registers basically are a kind of memory). In such a case, every instruction would have three arguments, eg. `ADD R1 R2 R3: M[R1] = M[R2] + M[R3]`. The stack paradigm was chosen for the obvious reason that it makes the code four times smaller. -* **32 byte word size** - the alternative is 4 or 8 byte words, as in most other architectures, or unlimited, as in Bitcoin. 4 or 8 byte words are too restrictive to store addresses and big values for crypto computations, and unlimited values are too hard to make a secure gas model around. 32 bytes is ideal because it is just large enough to store 32 byte values common in many crypto implementations, as well as addresses (and provides the ability to pack address and value into a single storage index as an optimization), but not so large as to be extremely inefficient. -* **Having our own VM at all** - the alternative is reusing Java, or some Lisp dialect, or Lua. We decided that having a specialized VM was appropriate because (i) our VM spec is much simpler than many other virtual machines, because other virtual machines have to pay a much lower cost for complexity, whereas in our case every additional unit of complexity is a step toward high barriers of entry creating development centralization and potential for security flaws including consensus failures, (ii) it allows us to specialize the VM much more, eg. by having a 32 byte word size, (iii) it allows us not to have a very complex external dependency which may lead to installation difficulties, and (iv) a full security review of Ethereum specific to our particular security needs would necessitate a security review of the external VM anyway, so the effort savings are not that large. -* **Using a variable extendable memory size** - we deemed a fixed memory size unnecessarily restrictive if the size is small and unnecessarily expensive if the size is large, and noted that if statements for memory access are necessary in any case to check for out-of-bounds access, so fixed size would not even make execution more efficient. -* **Not having a stack size limit** - no particular justification either way; note that limits are not strictly necessary in many cases as the combination of gas costs and a block-level gas limit will always act as a ceiling on the consumption of every resource. -* **Having a 1024 call depth limit** - many programing languages break at high stack depths much more quickly than they break at high levels of memory usage or computational load, so the implied limit from the block gas limit may not be sufficient. -* **No types** - done for simplicity. Instead, signed and unsigned opcodes for DIV, SDIV, MOD, SMOD are used instead (it turns out that for ADD and MUL the behavior of signed and unsigned opcodes is equivalent), and the transformations for fixed point arithmetic (high-depth fixed-point arithmetic is another benefit of 32-byte words) are in all cases simple, eg. at 32 bits of depth, `a * b -> (a * b) / 2^32`, `a / b -> a * 2^32 / b`, and +, - and * are unchanged from integer cases. - -The function and purpose of some opcodes in the VM is obvious, however other opcodes are less so. Some particular justifications are given below: - -* **ADDMOD**, **MULMOD**: in most cases, `mulmod(a, b, c) = a * b % c`. However, in the specific case of many classes of elliptic curve cryptography, 32-byte modular arithmetic is used, and doing `a * b % c` directly is therefore actually doing `((a * b) % 2^256) % c`, which gives a completely different result. A formula that calculates `a * b % c` with 32-byte values in 32 bytes of space is rather nontrivial and bulky. -* **SIGNEXTEND**: the purpose of SIGNEXTEND is to facilitate typecasting from a larger signed integer to a smaller signed integer. Small signed integers are useful because JIT-compiled virtual machines may in the future be able to detect long-running chunks of code that deals primarily with 32-byte integers and speed it up considerably. -* **SHA3**: SHA3 is very highly applicable in Ethereum code as secure infinite-sized hash maps that use storage will likely need to use a secure hash function so as to prevent malicious collisions, as well as for verifying Merkle trees and even verifying Ethereum-like data structures. A key point is that its companions `SHA256`, `ECRECOVER` and `RIPEMD160` are included not as opcodes but as pseudo-contracts. The purpose of this is to place them into a separate category so that, if/when we come up with a proper "native extensions" system later, more such contracts can be added without filling up the opcode space. -* **ORIGIN**: the primary use of the ORIGIN opcode, which provides the sender of a transaction, is to allow contracts to make refund payments for gas. -* **COINBASE**: the primary uses of the COINBASE opcode are to (i) allow sub-currencies to contribute to network security if they so choose, and (ii) open up the use of miners as a decentralized economic set for sub-consensus-based applications like Schellingcoin. -* **PREVHASH**: used as a semi-secure source of randomness, and to allow contracts to evaluate Merkle tree proofs of state in the previous block without requiring a highly complex recursive "Ethereum light client in Ethereum" construction. -* **EXTCODESIZE**, **EXTCODECOPY**: the primary uses here are to allow contracts to check the code of other contracts against a template, or even simulating them, before interacting with them. See http://lesswrong.com/lw/aq9/decision_theories_a_less_wrong_primer/ for applications. -* **JUMPDEST**: JIT-compiled virtual machines become much easier to implement when jump destinations are restricted to a few indices (specifically, the computational complexity of a variable-destination jump is roughly O(log(number of valid jump destinations)), although static jumps are always constant-time). Hence, we need (i) a restriction on valid variable jump destinations, and (ii) an incentive to use static over dynamic jumps. To meet both goals, we have the rules that (i) jumps that are immediately preceded by a push can jump anywhere but another jump, and (ii) other jumps can only jump to a JUMPDEST. The restriction against jumping on jumps is needed so that the question of whether a jump is dynamic or static can be determined by simply looking at the previous operation in the code. The lack of a need for JUMPDEST operations for static jumps is the incentive to use them. The prohibition against jumping into push data also speeds up JIT VM compilation and execution. -* **LOG**: LOG is meant to log events, see trie usage section above. -* **CALLCODE**: the purpose of this is to allow contracts to call "functions" in the form of code stored in other contracts, with a separate stack and memory, but using the contract's own storage. This makes it much easier to scalably implement "standard libraries" of code on the blockchain. -* **SUICIDE**: an opcode which allows a contract to quickly delete itself if it is no longer needed. The fact that SUICIDES are processed at the end of transaction execution, and not immediately, is motivated by the fact that having the ability to revert suicides that were already executed would substantially increase the complexity of the cache that would be required in an efficient VM implementation. -* **PC**: although theoretically not necessary, as all instances of the PC opcode can be replaced by simply putting in the actual program counter at that index as a push, using PC in code allows for the creation of position-independent code (ie. compiled functions which can be copy/pasted into other contracts, and do not break if they end up at different indices). diff --git a/pages/design-rationale/[japanese]-design-rationale.md b/pages/design-rationale/[japanese]-design-rationale.md deleted file mode 100644 index 56b1f9b4c..000000000 --- a/pages/design-rationale/[japanese]-design-rationale.md +++ /dev/null @@ -1,610 +0,0 @@ ---- -name: Design Rationale -category: ---- - -Ethereum が既に試されテストされてきた5年前からあるビットコインのような -古くからある暗号通貨の様々なアイディアを借りて出来てきたとしても、 -Ethereumには現在のプロトコルの機能を提供するための大半の一般的な方法とは異なる様々な点がある。 -全くもって新しい経済的なアプローチをEthereumが開発しなければならなかった状況がある。 -何故ならば、既存の他のシステムによって提供されて来なかった機能をEthereumは提供しているためだ。 -この文書の目的は潜在的に自明ではないことを叙述し、もしくはEthereumのプロトコルを創りあげていく経過において、 -議論の的となる物事に対して為されてきた決定についてを叙述し、同様に我々のアプローチと、その他の代替手段の可能性におけるリスクを示すことである。 - -##原理 -Ethereumのプロトコルの仕様は幾つかの原理に基づいている。: - -1. **Sandwich Complexity Model**: -我々はボトムレベルのEthereumの構造は出来る限りシンプルであるべきだと信じている。 -そして、そのEthereuのインターフェイスは(開発者にとっての高位のプログラミングの言語、そしてユーザーにとってユーザーインターフェイスを含めて)出来る限り理解しやすいものであるべきだと信じている。 -複雑であることが避けられないのであれば、複雑なことはプロトコルの"中間層"に押しやられるべきだ。 -核となるコンセンサスの一部ではなく、エンドユーザーからも見ることが出来ない場所である。 -例えば、高位の言語のコンパイラ、Serializationとdeserializationを行うスクリプトの引数、ストレージデータにとる構造のモデル、そのleveldbストレージのインターフェース、そしてwire protocol等だ、しかしながらこれらの設定は絶対的なものではない。 - -2. **自由**:ユーザーはEthereumのプロトコルの目的に制限されるべきではない。 -そして我々はEthereumの特定のコントラクトや、特定の意図を持って作られたトランザクションに対して、賛成か反対かを選択的に述べようとするべきではない。このことは"本質的な中立状態"のコンセプトに基づく原則と似ている。 -この原理に従わない例を1つ上げると、ビットコインのトランザクションプロトコルの中で -ブロックチェーンを"オフレベル"の使い方(例えばデータストレージや、メタープロトコル)を阻害されることや、 -ブロックチェーンを"認められていない”使われ方で使っているアプリケーションへの攻撃の目的のために、 -あからさまな外面的なプロトコルの変更が(例えばOP_RETURNの規制が40バイトのこと)作られることが上げられる。 -Ethereum では、我々はトランザクションのフィーをインセンティブと強く連動するように設計する思想に強く賛成している。 -それはブロックチェーンの肥大を生み出す使い方をしてブロックチェーンを使うユーザーに対しては、彼ら自身にコストを内在化させるような使い方である。(例えば、[ピグー税](http://ja.wikipedia.org/wiki/%E3%83%94%E3%82%B0%E3%83%BC%E7%A8%8E)) - -3. **一般化**: Ethereum におけるプロトコルとOpcodesの仕様は、出来るだけ低レベルのコンセプトを内包するべきである。そのことによって、現在は有用には見えないかもしれないが将来的には有用になりうる任意の使い方で構成されることが出来るようになる。 -そしてそのために効率的に他の必要ではない機能を削ぎ落とすことに依って、ローレベルのコンセプトの設計は一層効率的になりうるだろう。 -この原理に従う例は、DAPPSのフィードの情報(とりわけ軽いクライアント)を取るための、ログ用のLOG OPCODEの選択の例がある。 -内部で早い頃から提案されたように、シンプルに全てのトランザクションとメッセージのログを取ることとは対照的な例だ。 -"メッセージ"のコンセプトには、"関数の呼び出し"、"外部の観察者に対してのイベントリッスン"を含む、多くのコンセプトが集まっていて、メッセージと、トランザクションとは切り分けることが妥当であった。 - -4. **我々は機能を持たない**: 一般化に対しての必然的な帰結として、我々は直感的にプロトコルのパーツとなるような非常にありふれたハイレベルのユースケースの構築を断ることがある。 -もし人々が本当にそれを欲しているならば、常にサブのプロトコル(例えばEtherをベースとしたサブの貨幣や、bitcoin/litecoin/dogecoin/sidechain等)として、契約の内部に作るだろうと考えているためだ。 -例をあげるとBitcoinのロックタイムのような機能がEthereumの中には無い。 -そのような機能は、"署名されたデータパケット"を送ったり、 -そしてそのデータのパケットは特定の契約の意味で有用かもしれない; - -5. **リスクを嫌悪しない**: もしリスクが増大していくような変更がとても大きい利益をもたらすのであれば、我々は高いリスクを受け入れる。(例えば一般化された状態遷移や、50倍の速度のブロック承認時間、コンセンサスの合意性、等だ) -これらの原則は全てEthreumの開発の方針であるが、絶対的でな方針ではない。 -例をあげると、開発の時間を減らし、とても多くの急激な変更を一度に行わないようにしたいと思ってしまってことで -ある変更を行うにあたって遅延をもたらしたことがある。その変更が明らかに将来のリリースに向けてメリットが有ることであったとしても。(例えば Ethereum1.1) - -## ブロックチェーンレベルでのプロトコル - -このセクションでは、Ethereumで為されたいくつかのブロックチェーンレベルでのプロトコルの変更についての詳細を記載する。 -どのようにしてトランザクションが機能しているのか、 -そしてどのようにしてデータがシリアライズされ保存されているのか、アカウントの背後にあるメカニズムについてを記載する。 - -### アカウントと、非UTXOs - -ビットコイン、そしてビットコインに付帯する多くのデリバティブ、ユーザーのバランスについてのデータは、 -使われていないトランザクションのアウトプットに基づく構造の中にある。 -システム内のすべての状態は、"Unspent Outputs"(例:コイン)から成り立っている。 -それは下記のような制約が有効であることのもとに、 -それぞれのコインが所持者と価値を持ち、トランザクションは1つ以上のコインを使い、1つ以上の新しいコインを作り出す。 - -1. あらゆる参照されているインプットは正しく、そして未だ使われていない状態である必要がある。 -2. 全てのインプットの場合において、トランザクションに記載されている署名はインプットの所持者のものと一致していなければならない。 -3. インプットの合計の価値は、アウトプットの合計の価値と等しいか、もしくは少なくなければならない。 - -システムにおける有るユーザーの残高は、上記のようにして、秘密鍵をもっているユーザーが有効な署名を作り出すことが出来るコインの合計の価値である。 - -![](https://bitcoin.org/img/dev/en-transaction-propagation.svg) -(Image from https://bitcoin.org/en/developer-guide) - -Ethereumは、より単純なアプローチに賛同し、ビットコインのスキームを投げ捨てる。状態はそれぞれが残高を所持しているアカウントの一覧を保持し、同様にEthereum特有のコードと内部のストレージデータを保持する。 -そして、もし送り手が、送る分の価値に値する十分な残高を持っているならば、トランザクションは正当なものであり、 -その場合において、送り手のアカウントから送った分の価値は引き落とされ、受け取り手は送られた価値を受け取る。 -もし受取り手のアカウントがコードを持っていたならば、コードは実行され内部のストレージも同時に変更されるかもしれない。 -もしくは受け取り手のアカウントのコードは新たな追加のメッセージを生成し、引き落としや、受け取りに繋がっている他のアカウントに送ることかもしれない。 - -UTXOsのメリットには下記がある。: -1. **高水準ののプライバシー**: -もしあるユーザーが各々のトランザクションで新しいアカウントを使うのであれば、 -アカウントとアドレスとを結びつけることは通常難しいだろう。 -このことはとても通貨にとって適している性質だ。だが、任意のDapps(分散形のアプリ)としては適していない。 -何故なら任意の分散形のアプリは複雑な塊となった情報のユーザーの状態を追いかける必要がよくあるため、 -通貨システムのように簡単なユーザーの状態が切り分けられる状態が、存在しないかもしれないからだ。 - -2. **潜在的にスケーラビリティのある仕組み**: -UTXOsは理論的にある種のスケーラビリティがあるパラダイムとよく適合している。 -何故なら我々は、マークルツリー上で所有権を証明している幾つかのコインの所有者だけに依存しているため -オーナーを含めた誰もがその所有権のデータを忘れると決めた場合でさえも、オーナーだけが損害を受けることで済むからだ。 -アカウントの考え方では、すべての人が有るアカウントに対応するマークルツリーの一片を失うことで -そのアカウントに対して送られているメッセージの実行が不可能になってしまう。 -しかしながらUTXOに依存しないスキームにも、スケーラビリティが確かにある。 - -アカウントによるメリットは下記がある: - -1. **大きなスペースの節約**: 例えばひとつのアカウントが5つのUTXOを持っているとした時、 -UTXOモデルからアカウントモデルに切り替えれば、 -必要なスペースは(20 + 32 + 8) * 5 = 300 bytes (20 はアドレスに, 32 はトランザクションIDに and 8は送信する価値に)から -20 + 8 + 2 = 30 bytes (20 はアドレスに, 8 は送信する価値に、2 はNonce(1度だけ使われる番号)に))となる。 -実際のスペースの節約はこれほど大きなものにはならない、何故ならアカウントはパトリシアツリー上に保存される必要があるためだ。 -しかしそうであったとしても大きな節約だ。 -加えて、トランザクションはより小さくすることが出来る(例えば、Ethereum上の100バイトと、Bitcoin上の200-250バイト)、何故ならばあらゆるトランザクションは1回の参照と1回の署名を行い、1つのアウトプットを出すだけを必要とするからだ。 - -2. **大きな代替性**: ある種のコインの元となるブロックチェーンレベルでないコンセプトの存在に対して、 -レッドリストやブラックリストを行うための仕組みを構築し、何に依拠しているコインなのかに判別を付けることは -技術的にも法的にも実用的な手段でなくなっている。 - -3. **シンプルさ**: -とりわけ一旦一層複雑なスクリプトが含まれたときに、より簡単にコードが書け、分かりやすくすること。 -任意の分散形のアプリケーションをUTXOの考え方という、狭い場所へと押しこむことも出来るが、 -根本的にスクリプトに対してどのようなUTXOに対して与えられたUTXOが使われる事が出来るかといったことを成約する能力を与え、 -スクリプトが判別できる「アプリケーションの状態のルートの変更」のマークルツリーによる証明、を含めることを必要とすることは -そんな概念は、ただアカウントという概念を使うことよりも一層複雑で汚いものだ。 - -4. **定量で軽量なクライアントによる参照** : -軽量なクライアントはあらゆる点において、特定の方向に状態のツリーをみていくことで、 -有るアカウントに関連する全てのデータにアクセスすることが可能である。 -UTXOの考え方では、参照は各々のトランザクションごとに変更してしまうものであり、 -長期的に稼働し、上記に述べたUTXO上の状態のルートを伝播するメカニズムを用いようとするDAppsに対しては、 -とりわけ重荷となる問題である。 - -我々は任意の状態とコードを含んでいるDappsとやり取りしなければならないという問題のために、 -アカウントを導入する事によるメリットは、代替手段を超える大きな方法であると決定している。 -加えて我々の"機能を持たない"という原理の志のもと、人々が本当にプライバシーを気にするのであれば、 -コインを混ぜるミキサーや、コインジョインの仕組みを -プロトコルの署名されたデータパケットを通じて、コントラクトの内側に設計出来るだろうと考えている。 - -1つのアカウントの思想の弱点は、リプレイアタックを防ぐために、 -全てのトランザクションは"nonce"一度だけ使う数値を持たなければならないことだ。 -そのようなアカウントは最後に使われたnonce を追跡し、nonceが最後のnonceが使われた丁度一回後の場合にのみトランザクションを受け入れるようにする。これは、もはや使われなくなったアカウントでさえも、決してアカウントの状態から切り取られることが出来ないということを意味する。この問題の簡単な解決策は、トランザクションがブロックの番号を保持することを求めるようにすることだ。 -一定の時間の後にしかリプレイが出来ないようにして、一定期間ごとにnonceをリセットする。 -マイナーや、他のユーザーは使われていないアカウントを状態から取り除くために、使われていないアカウントへの"ping"を必要とするだろう。ブロックチェーンプロトコル全体の一部として、完全に消し去ることはあまりにもコストの掛かって不可能なオペレーションであるためだ。Ethereum のバージョン1.0では開発の加速のためにこのメカニズムを採用しなかったが、1.1ではこのようなシステムを使うだろう。 - -## マークルパトリシアツリー -マークルパトリシアツリーは、アランレイナーによって構想され、Rippleのプロトコルの中に実装されたもので、 -Ethereumの基礎となるデータの構造であり、全てのアカウントの状態の保存に使われている。 -同様にトランザクションや、それぞれのブロック内のお釣りの保存にも使われている。 -MPTは[マークルツリー](https://en.wikipedia.org/wiki/Merkle_tree) と [パトリシアツリー](https://en.wikipedia.org/wiki/Radix_tree), -の組み合わせであり、両方の要素を取って、下記の要素に従う形で構造を作り出している。 - -1. 全てのユニークなKeyValueの組みは、独自のルートハッシュにマッピングされる。 -そしてツリー上のKeyVelueの組みのメンバーシップを偽装することは不可能である。 -(攻撃者が2^128以上のコンピューターパワーを持たない限り) -2. 変更すること、追加すること、削除することは対数的な時間の中で可能。 -これによって私達に効率的で更新が簡単な全体の状態を記載した我々のツリー上の"フィンガープリント"の方法を提供してくれる。 -EthererumのMPT(Merkle Patricia Tree)は正式に下記に示されている。 https://github.com/ethereum/wiki/wiki/Patricia-Tree - -MPTの上の仕様は下記の決定事項を含む: -1. **2つのクラスのノードを持つ**、KV(キーバリュー)のノードとそこから派生したノード(更なる詳細についてのMPTの仕様を見て欲しい)KVノードがあることでより効率的になる、何故ならばツリーが特定のエリアにまばらに存在することで、KVのノードがショートカットとしての役割を持つため、64層の深さのツリーを保つ必要が無くなるからだ。 - -2. **バイナリではないヘックスの派生ノード**: -これはルックアップの効率を改善するために為された。 -我々は現在準最適な選択を行ってきた、何故ならヘックスツリーのルックアップの効率は -まとまったノードを保存することによるバイナリーでの構想においてもシミュレーション出来からだ。 -しかしながら、ツリーの構造を誤った形で構成することはとても簡単であるために、 -最低でもルートの状態が合わなくなってしまうことには殆どならない。 -我々は1.1のバージョン迄にそのような再構成を審議することを決定した。 -3. **空のバリューと、メンバーシップが無いことの区別を行わない事**: -シンプルさのために為された。組みになっていないバリューは一般的にゼロかか空のがゼロを表すために使われているという -Ethereumのデフォルトの仕様とよく合っているからだ。 -しかしながら他の一般性と、このように僅かばかり準最適な方法を取っていると強く思っている。 -4. **終了したノードと終了していないノードの区別**: -技術的には、"ノードは終わりかけている"のフラグは必要が無い。 -何故ならEthereumの全てのツリーは固定長のキーを保存するために使われているからだ。 -だが、EthereumのMTPの実装が他の暗号プロトコルにそのまま使われるだろうと思い、一般性を高めるために付け加えた。 - -5. **Sha3(k)を使うことに依って、キーが安全なツリーの中に保存されること(状態とアカウントを保存するツリーの中に使われている) ** -このことは、64層の深さのノードから派生した最大限望ましくないチェインを設定して、 -何度もSLOADとSSTOREを呼び出すことによって、DDoS攻撃をツリーに対して行うことを一層難しくしている。 -より一層ツリーを列挙することを難しくために、もし列挙出来る限界をクライアントに設けたいと思うのであれば、 -そのための最もシンプルな方法はデータベースマッピングをsha3(k)->k.RLPに対して行うことだ。 - -## RLP -RLP(Recursive Length Prefix: 再帰的な長さの接頭辞)エンコーディングは、 -Ethereumで使われている主要なシリアライゼーションの形式だ。 -そして、Block,Transaction,アカウントの状態のデータ、そして配線プロトコルのメッセージといっった全ての場所で使われている。 -RLPは正式に下記にて述べられている。https://github.com/ethereum/wiki/wiki/RLP - -RLPは高度に最小主義なシリアライゼーションのフォーマットとして作られた。 -ネストされたバイトアレイを保存する目的のためのみにある。 -Protobufや、BSONや既存の他の解決策と違って、RLPはbooleanやfloatやdoubleや、integerさえも定義しようとしない。 -代わりに只シンプルに、ネストされたアレイの形で構造を保存するために存在し、 -アレイの意味を決定することはプロトコルに任せて、保存状態を残している。 -Key Valueのマップは明示的にサポートされてはいないが、準公式なKeyValueのマッピングのサポートのための提案は、 -k1, k2がある場所において、 [[k1, v1], [k2, v2], ...] をストリングに対する通常の順番を使ってソートすることだ。 - -RLPの代替手段として、ProtobufやBSONのような現在のアルゴリズムに使われていたかもしれないが、 -しかしながら(1)実装のシンプルさ、(2)バイトが完全に一貫していることを保証するために我々はRLPを使うことが良いと考えている。 -多くの言語におけるキーバリューのマップは明らかなオーダーを持たない、そしてフロートのポイントのフォーマットについて多くの特別な場合を持ち、潜在的に同じデータが違うコーディングとなることに繋がっている。そしてそのようにして違うハッシュ値となる。 -プロトコルを内製することによって、我々はこれらのゴールを念頭に置いた仕様を保証することが出来る。(これは例えばVMのようなコードの一部にも当てはまる一般的な原理である。) -BitTorrent にて使われているbencodeは、RLPに代わって通用する代替手段を持つかもしれない、 -だがバイナリーのRLPに比べると長さを表すための小数のエンコーディングはやや準最適である。 - -## 圧縮のアルゴリズム -ワイヤプロトコルと、データベースがどちらもカスタムの圧縮アルゴリズムを、データ保存のために用いている。 -そのアルゴリズムは、ゼロをランレングス符号かし、他の値はそのまま残すものとして、最も分かりやすく表現出来る。 - ->>> compress('horse') -'horse' ->>> compress('donkey dragon 1231231243') -'donkey dragon 1231231243' ->>> compress('\xf8\xaf\xf8\xab\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbe{b\xd5\xcd\x8d\x87\x97') -'\xf8\xaf\xf8\xab\xa0\xfe\x9e\xbe{b\xd5\xcd\x8d\x87\x97' ->>> compress("\xc5\xd2F\x01\x86\xf7#<\x92~}\xb2\xdc\xc7\x03\xc0\xe5\x00\xb6S\xca\x82';{\xfa\xd8\x04]\x85\xa4p") -'\xfe\x01' - -この圧縮のアルゴリズムが存在する前には、多くのEthereum protocol 上の部分では数多くの特別な場合があった。 -例えばsha3が良くsha3('') = ''としてオーバーライドされ, -アカウント内にコードやストレージを保存する必要が無かったことから64バイトを保存しただろう。 -しかしながらスペシャルキャラクターを最近取り除いたことに寄って、 -Ethereumのデータ構造はデフォルトで一層束となった形になった。 -ユーザーのデータベースにワイヤプロトコルを断続無しに導入することによって、 -ブロックチェーンの外のレイヤーに機能的にデータを保存する代わりに、 -データを機能的にブロックチェーンのプロトコルの外側に加える代わりにwire protocolに加える事に依って、 -断続無くEthereumのデータをユーザーのデータベースに挿入することが出来る実装 -このことはコンセンサスのレイヤーにおいて、モジュラリティを追加し、単純化する。 -そして比較的簡単にデプロイを行うための圧縮アルゴリズムに対しての継続的な更新を行うことを可能にしている。 -(例えばネットワークのプロトコルのバージョン更新) - -## ツリーの使い方 - -警告:このセクションではどのようにしてブルームフィルターが働くかの知識を前提としている。 -導入として下記を参照 http://en.wikipedia.org/wiki/Bloom_filter - -全てのEthereumのブロックチェーン上のブロックのヘッダーは、3つの樹に対してのポインターを含んでいる。 -ブロックにアクセスした後の全体のツリー状態を示す、状態のツリー -インデックスに依ってキーとされたブロック上の全てのトランザクションを示している、トランザクションのツリー -(例えば key0: 実行される最初のトランザクション、key1 :2番目のトランザクション、等 ) -そしてあらゆるトランザクションの"お釣り"に対応している、お釣りのツリーだ。 -トランザクションのお釣りはRLPエンコードされた下記のデータの構造となっている。 -構造: -[medstate, gas_used, logbloom, logs] - -詳細: -* medstateは、トランザクションが執行された後のステートツリーのルートである。 -* gas_usedは、トランザクションのプロセスのために使われたgas の量である。 -* logsは、[address, [topic1, topic2... ],data]の形式のデーターのリストを表しており、 -トランザクションの執行の間のLOG0 ... LOG4のopcodeによって作られている。(主要コールとサブのコールを含めて) -addressは、そのログを生成したコントラクト上のアドレスを示している。topicは4 32バイトの値にまでなり、データは任意のサイズのバイトのアレイだ。 -*logbloom は、トランザクション内の全てのログが基づくアドレスとトピックから構成されるbloom filterである。 - -bloom はブロックのヘッダー内、それはブロック内のトランザクションに対するの全てのbloomのORであるブロックヘッダーの中にある。 -この構造の目的は、ライトクライアントにとってEthereumのプロトコルを様々な方法で出来るだけ使いやすい形にするためである。 - -Ethereumにおいてライトクライアントは、デフォルトでブロックのヘッダーをダウンロードし、 -DHTをローカルのハードドライブ上のツリーのノードのデータベースとして使うことに依って、わずかな断片だけを承認していくと考えている。 -幾つかの下記の使い方を含む: -* ライトクライアントはアカウントの状態を特定の時間において知ることを望んでいる -(nonce, balance, code, 又はstorage のインデックス) -* ライトクライアントは単純に再帰的に状態のルートからツリーのノードをダウンロード出来る、任意の値に達する迄。 -* ライトクライアントは、トランザクションが承認されたかを確認したい。 -* ライトクライアントは単純にトランザクションのインデックスとブロックの番号についてネットワークに問い合わせることが出来る。 -そして再帰的にトランザクションのツリーをダウンロードして利用可能かどうかを確かめることが出来る。 -ライトクライアントは合計でデータの有効性を確かめたい。 -それぞれのライトクライアントが、c[i]は1つのトランザクションのindex iをトランザクション T[i](R[i]のお釣りに対応する。) -そして下記のように作動する。 -* R[i-1].medstate、 R[i-1].gas_used(if i = 0 use the parent endstate and 0 gas_used)を生成 -* T[i]のトランザクションの実行 -* 結果として生じるState Root が R[i].medstateであり、その gas_used がR[i].gas_usedであることを確認 -ログと、出来上がったbloomの組みが R[i].logsとR[i].logbloomと合うことを確認 -* bloomがブロックヘッダーレベルのbloomのサブ集合(これはブロックヘッダーレベルのBloomが間違っている事を検出する)であることを確認。そして幾つかのランダムのブロックヘッダーレベルのインデックスを取得し、 -ブルームが1つか他のトランザクションレベルのブルームを持ち、 -もしレスポンスが与えられていなかった場合には、ブロックを拒絶する。 -* ライトクライアントは記録されるイベントを"watch"したいと思う。 -その場合のプロトコルは下記に従う。 -* ライトクライアントは全てのブロックのヘッダーを取得し、ライトクライアントが求めるアドレスかトピックのリストの1つと適合するbloom filterを、ブロックヘッダーが含んでいるかを確認する。 -* 潜在的に適合しているブロックヘッダーを見つけた場合、ライトクライアントは -ブルームフィルターに適合する全てのトランザクションのレシートと、トランザクションに対する証明を取得する。 -* 潜在的に適合しているトランザクションを見つけた場合、ライトクライアントは実際のLOGのRLPを確かめ、それが実際に適合するかどうかを確認する。 - -最初の3つのライトクライアントのプロトコルでは対数量のデータ・アクセスとコンピュテーションが必要となる。 -最初の4つ目では~0(Nの平方根)ブルームフィルターから只2階層だけ、だがこのことは0(log(N))に対して改善が為される。 -もしライトクライアントが様々なプロバイダーに依拠しようとするのであれば、"興味を持っている”トランザクションのインデックスを指し示し、もし間違ったトランザクションを所持していることが公開されれば、プロバイダーへの依存を解除うsる。 -その最初のプロトコルは単純に状態を確認するために有用であr,2爪のプロトコルは、消費者と承認のようなシナリオにおいて、トランザクションが認証されたどうかを確認するために有用である。 -3つ目のプロトコルは、Ethereuのライトクライアントがブロックをとても少ない量のトラストによって承認出来るようにしている。 -ビットコインでは、例えばマイナーはマイナーに対して多大な料のトランザクションの費用を払うブロックを生成することが出来る。 -そして軽量ノードにとってこのことを知る術はない、また、正直な全てのノードが検知することが出来た場合にも -その不当性を証明しなければならない -Ethereumでは、もしブロックが不当な場合には、不当な状態の遷移をどこかのindexで含んでいなければならない、そして -ライトクライアントは、何か間違っていることは無いかindex が見つけられるように認証することとなる。もしくは、データが使用不可能なためにその証明のステップが終わらないからだ、そしてクライアントは警告を上げることが出来る。 - -4つ目のプロトコルはDAPPが効率的に証明される必要のあるある種のイベントを追跡したい場合に有用である。 -例えば分散形の交換所でトレードのログを取るか、もしくはウォレットがトランザクションのログを取る(ライトクライアントが高いレベルのコインベースとアンクルのチェックがマイナーのアカウントに対して十分に働いた場合) -Bitcoinの言葉でいうと、ログは純粋な"Proof of publication"のopcode として考えられる。 - -## Uncleへのインセンティブ -The 強欲で最も重い監視されているサブツリー"(GHOST)プロトコルは、最初にYonatan Sompolinsky とAvivZoharによって2013年12月に導入されたイノベーションだ。[first introduced](http://eprint.iacr.org/2013/881.pdf) -そしてもっと早いブロックの時間を防ぐための問題解決策としての最初の重大な試みでもある。 -GHOSTが開発された動機は、承認時間の早いブロックチェーンが、古くなっていまう可能性が高いためにが -現在セキュリティリスクを抱えていることだ。 -何故ならブロックはネットワークに伝播するまでに一定時間必要であり、 -もしマイナーAがを採掘してマイナーBが他のブロックをマイナーAのブロックが伝播するまでにほった場合には、 -マイナーBのブロックは結局無駄("stale")してしまい、その仕事はネットワークのセキュリティの改善に寄与しないためだ。 -更に言えば、そこには中央集権の問題がある。:もしマイナ-Aがマイニングプール上で30%のハッシュパワーを持ち、Bは10%のハッシュパワーを持っているならば、Aは70%の時間無駄になるブロックを生み出すリスクをもっており、(Aが最後のブロックを生成した他の30%の時間から、そしてマイニングのデータをすぐに手に入れることになるだろう。)一方でBは90%の時間において無駄になるブロックを生成するリスクを取っている。 -このようにして、ブロックのインターバルがブロックが無駄になる確立が十分に高くなるほどに短かったとしても -Aはそのサイズのお陰で大変効率的でシンプルに採掘を行うことが出来る。 - -これらの2つ効果を組み合わせると、ブロックチェーンはブロックを早く生成し、 -1 -早くブロックを作り出していくブロックチェーンが存在することで、 -1つのマイニングプールが、マイニングのプロセスに対してネットワーク全体のハッシュパワーの十分に大きな割合を持つことで -デファクトのコントロールを持つことに繋がって行きやすくなるだろう。 - -Sompolinsky とZoharによって述べられたように、GHOSTはネットワークのセキュリティロスの最初の問題を、 -どのブロックが"最長"のブロックかを計算する中で、無駄となってしまったブロックを含める事によって改善した。 -即ち、ブロックの親と先祖を含めるだけでなく、無駄になった先祖のブロック(Ethereumの隠語で、"uncles")も含めることで、 -どのブロックが合計で最も長いproof of workのための計算に加えられることだ。 - -2つ目の中央集権による偏りの問題を解決するために我々は異なる戦略を採用する: -我々は無駄になったブロックに対しての報酬を無駄となったブロックに付与すること: -無駄となったブロックが7/8(87.5 %)のベースのリワードを受け取る事が出来、 -そして無駄となったブロックを含む甥が、ベースのリワードの1/32(3.125 %)をブロックを含めた報酬として受け取る事が出来る。 -しかしながら、トランザクションの費用は甥にもおじにも与えられることはない。 - -Ethereumでは、無駄となったブロックはおじによってのみ含まれる事ができ、7代目迄のその直接の兄弟の子孫が含まれ、 -そして一層の関係のブロックは含まれない。これはいくつかの理由によって為されている。 -初めに、無限のGHOSTはどのおじが与えられたブロックが有効かという計算を行うに当たって大変複雑となるからだ。 -2つ目には、無限のおじに対してのインセンティブがEthereuで使われることで、 -チェーンへの公衆の攻撃者ではなく、 -メインチェーンのマイナーにとって採掘するインセンティブを失わせることに繋がるからだ。 -最後に、多くのネガティブな影響無しに、7段階目迄に制限していることが大半の望ましい影響を及ぼしていることについての計算を示す。 -* 中央集権のリスクを測ったシミュレーターはこちらで利用可能だ。 -https://github.com/ethereum/economic-modeling/blob/master/ghost.py -* 高度なレベルの議論はこちらで行われている。 -https://blog.ethereum.org/2014/07/11/toward-a-12-second-block-time/ - -ブロックの承認時間のアルゴリズムについての仕様は下記を含む -* **12秒のブロック承認時間**: 出来るだけ早い時間として12秒が選ばれた。 -だが同時に、ネットワークの遅れよりもかなり長い時間である。 -2013年のDecker とWattenhoferによる論文では、Bitcoinのネットワークの遅れが計算されており、 -それは12.6秒が新しいブロックが残りの95%のノードに伝播する迄に必要なためだ。 -しかしながらその文書で指摘されていた伝播に掛かる全体の時間はブロックのサイズに比例するとも指摘されている。 -そのようにして、速い通貨において、伝播のための時間は、劇的に減少することが期待される。 -伝播に掛かる待機時間は凡そ2秒だが、安全のために我々の分析では12秒が伝播のために掛かると考えている。 -* **7ブロックの子孫の制限**: これは幾つかのブロックの後、ブロックの履歴をすぐに"忘れやすい"ものへとするための仕様だ、 -そして7ブロックが最も良い影響を与えることが証明された。 -* **1ブロックの子孫のリミット** (例: c(c(p(p(p(head))))), where c = chile and p = parent, is invalid): -このパートではシンプルさを仕様目標とし、上記のシミュレーターでは大きな中央集権型のリスクを持たないことを示す。 -* **Uncleブロックの正当性の要求**: Uncle(おじ)は認証されたブロックではなく、認証されたブロックヘッダーでなければならない。 -これはシンプルさを達成するためであり、ブロックチェーンのモデルを維持するために線形のデータ構造を取る(block-DAGではなく、SompolinskyとZoharの新しいモデル)。おじが正当なブロックであることを求めるのは同様に正当なアプローチである。 -* **報酬の分散**: 7/8のベースマイニングの報酬はおじにいき、残りの1/32は甥にいき、0%のトランザクション費用が双方に渡る。 -もし費用が独占されているならば、中央集権的な考え方からみるとおじに対してのインセンティブが有効でなくなるだろう。 -しかしながらこれはEthereumで、出来るだけProof of Work を使い、どうしてEtherを発行し続けようとしているのかという一つの理由である。 - -## 困難さをアップデートするアルゴリズム -Ethereumにおいての困難さの更新は下記のルールに従って行われる: -diff(genesis) = 2^32 -diff(block) - diff.block.parent + floor(diff.block.parent/1024)* - -The difficulty in Ethereum is currently updated according to the following rule: - -diff(genesis) = 2^32 -1 if block.timestamp - block.parent.timestamp < 9 else --1 if block.timestamp - block.parent.timestamp >= 9 - -diff(block) = diff.block.parent + floor(diff.block.parent / 1024) * - 1 if block.timestamp - block.parent.timestamp < 9 else - -1 if block.timestamp - block.parent.timestamp >= 9 -The design goals behind the difficulty update rule are: - -このdifficulty のアップデートの仕様は下記である。 -* **速いアップデート**: ブロック同士の間での読込が早ければ速いほど与えられたハッシュパワーの増大と現象にフィットする物となる。 -* **低いボラティリティ**: Difficulty はハッシュパワーがもし定数であるならば大きく変動するべきではない。 -* **シンプルさ**: アルゴリズムは比較的シンプルに実装できるべきである。 -* **メモリーを食わない**: アルゴリズムは幾つかのブロックの履歴に依拠するべきでなない、 -それは幾つかのメモリーの変数を出来る限り含むべきである。 -最後の10ブロックを考えると、最後の10ブロックのブロックのヘッダーに全てのメモリーの変数が置かれる。 -それはアルゴリズムが作用するために利用可能な全てのデータである。 -セキュリティーホールをなくす: アルゴリズムはマイナーに対して -彼らのレベニューを最大化させようという意図で、 -タイムスタンプや、マイニングプールでのハッシュパワーの増減の繰り返しをさせることを過度に奨励すべきではない。 -我々の現在のアルゴリズムは、高い副次的適合性を低いボラティリティと、セキュリティホールの防止策に対して準最適な方法として -既に決定している。そしてタイムスタンプを親や、祖父母のブロックとタイムスタンプを比べるように変更し -もしマイナーが2つの列になったブロックのマイニングを行っているならば、 -マイナーがタイムスタンプの書き換えに対してのみインセンティブを持つようにしようとは全く考えていない。 -もう一つのシミュレーションを伴う強力な定式はこちらにある。 -https://github.com/ethereum/economic-modeling/blob/master/diffadjust/blkdiff.py (シミュレーターはビットコインのマイニングパワーを用いているが、日ごとの平均を全体に対して使っている。1つのポイントでのシミュレーションは95%1日の内にクラッシュする。) - -## GasとFee - -全てのビットコイン内のトランザクションが殆ど同じであるとしても、ネットワークに対するコストは一つのユニットの中で形作られているために、Ethereumのトランザクションはより複雑である。そして、トランザクションのFeeのシステムは、ストレージのコストと、コンピュテーションのコストを含めて様々な要素を考慮に入れて設計されている。 -とりわけ重要な事は Ethereumのプログラミング言語はチューリング完全であることだ。 -そしてトランザクションはbandwidthを使っているかもしれず、ストレージは任意の量のコンピュテーションw行っているかもしれない。 -そして後半では先行して確かにわかったかもしれないが -先行して知ることは決して出来ないコンピューターの停止問題があるが故に、 -無限ループによるサービス妨害攻撃を防ぐために鍵となる目的である。 - -トランザクションの費用の背後にある基本となる作用は下記のとおりだ。 -* 全てのトランザクションは必ず"gas"の量を定義しなければならない。"gas"は(startgasと呼ばれる)使われようとし、 -そのフィーはgasの大きさに応じて支払われる(gasprice)。そして、プログラム開始時に、startgas* gasprice 分のetherが送り手のアカウントのトランザクションから取り除かれる。 -* トランザクションが実行されている際に、全てのオペレーション、databaseの読み書き、メッセージ、全てのコンピューテーションは、 -仮想マシーンによって 一定量のgas を消費することによって行われる。 -もしトランザクションの実行プロセスが完全に、一定量の限界よりも少ない量のガスを消費するのであれば、gas_rem(gasの残り)とともに行われる。そしてトランザクションが通常どおり執行されて、トランザクションの最後には、トランザクションの送り手はga_rem* gasprice分の返金を受け取る。そしてブロックのマイナーは(startgas-gas_rem)*gasprice分の報酬を受け取る。 -* もしトランザクションが"ガス切れ"に実行の最中でなった場合には、全ての実行プロセスは元の状態に戻り、 -トランザクション自体は正しいトランザクションであったにもかかわらず、トランザクションの影響は、 -ただ合計のstartgas*gasprice がマイナーに行き渡るだけとなる。 -* あるコントラクトがメッセージを他のコントラクトに送るときには、それはメッセージから現れたsub実行に対してのgaslimitを設定するオプションを持っている。もしsubの実行プロセスがgas切れになった際には、subの実行プロセスは以前の状態に戻され、 -そうであったにも拘らず、gasは消費される。 - -これらのコンポーネント必須要素である・例えば: - -* もしトランザクションがgasの上限を定めなくて良い場合には、悪意あるユーザーは何10億というループを作り出すトランザクションを送り、そのようなプロセスがブロックの同士の間隔よりも長くなってしまうことで、誰もプロセスを行うことが出来なくなる。 -だが、マイナーが事前にわからないんのであれば、サービス妨害攻撃に対する脆弱性へと繋がる。 - -* gas-countingを規制する他の選択肢は、時間制限である。 -何故ならばあまりにも他の(有るマシーンが他のマシーンよりも早い場合には同一するマシーンのクローズコールが常に存在する。) -Startgas * gaspriceの全体の価値は最初の時点でデポジットとして取り除かれるべきである、それによって -有るアカウントが自身の動作の実行によって、gasのコストが払えなくなって"破産する"こともなくなるような -シチュエーションが起こることを防ぐ事が出来る。 -もし実行がgas が足りないためにやり直す事ができない場合には、コントラクトはより強固で難しいセキュリティの手段を -* 只十分なガスが途中までしか足りていないトランザクションやメッセージによって -それによってコントラクトの実行における幾つかの変更に繋がるが他にはつながらない。 -* もしサブのリミットが存在しない場合には、敵対的なアカウントが、 -他のアカウントに対して合意を導入することによって、最初のコンピュテーションにおいて無限ループを導入し、 -被害者のコントラクトによるどんな攻撃社のコントラクトや、コントラクトに対してメッセージを送ることが全てのトランザクションの実行を枯れさせてしまうかもしれない。 -* トランザクションの送り手がコントラクトの代わりに、gas を送ることを要求することは、開発者の使い勝手をかなり大きく改善した。 -まさにEthereumが始まったばかりのころ、gasに対して費用を払うコントラクトがあったが、 -全てのコントラクトが"guard"するためのコード、即ち全ての受信するメッセージが、消費されるgasに対して支払うための十分なetherがあるかどうかををするためのコードを持たなければならないという、かなり汚い実装となってしまう問題に遭遇した。 - -下記がgasのコストについての仕様である。 -* 21000gas が全てのトランザクションに対して”base fee"としてチャージされる。 -これは楕円曲線のオペレーションを、送り手の署名からアドレスを再現し、 -同様に、トランザクションを保存しておくディスクと一定時間に処理できる情報量の空間を確保しておくための費用である。 -* トランザクションは無限の量のデータを含んでいる、そして仮想マシーンの中にはopcodeが存在している。 -仮想マシーンはコントラクトがデータにアクセスするためのトランザクションを受け取ることを可能としている。 -データに対してのgasの費用はゼロバイトに対して1gas、ノンゼロバイトに対して5 gasである。 -ユーザーによって書かれたコントラクト中の大半のトランザクションにおいて、 -32バイトの引数の列に構成されるとわかったため、この計算式とした。 -大半のコントラクトはゼロバイトになり、そのようなコンストラクションは不十分のように見えるが、 -実際には圧縮アルゴリズムのおかげによって、効率的なものである。 -我々はより複雑な期待されるバイト数に基づいて引数を厳しくパック仕様とするメカニズムのかわりとなる使い方を奨励したいと思っていて、 -まさにかなりの複雑さをコンパイラのレベルで増大させることへと繋がった。 -これは、Sandwich Complexity modelの例外であるが、コストに対するベネフィットが大きいために行われるべきと考えられたことである。 -* SSTOREのopcodeのコストは、アカウントのストレージのバリュ0、どちらかである -(i)20000gasがゼロバリューからノンゼロのバリューに変わる時に掛かる。 -(ii)5000gas がゼロバリューからノンゼロのバリューに変わるときに掛かる。 -(iii)5000gas がノンゼロのバリューからゼロバリューに代わる時に掛かる、加えて20000gasのりファンドが成功したトランザクションの最後尾に与えられる。(例えば 実行gas切れの例外にならないような実行) -Refundsはトランザクションによって消費される全体のガスの50%の部分に制限され、 -このことはストレージを消去するために少ないながらのインセンティブを提供する。 -インセンティブの仕組みが欠けているために、多くのコントラクトがstorageを使わない状態で残すだろうと我々は気づいた。 -我々がそのようなインセンティブのシステムが欠けていることに築き、ストレージが使われないままで残っていると、 -早くブロックチェーンの肥大へと繋がるだろう、そして大半のベネフィットを"利子を徴収する"。 -そして遅れたrefund のメカニズムは、アタッカーによって僅かな量のgasと共にトランザクションが送られ、何度も大きな量のストレージのスロットがクリアーされる類の攻撃に対して - サービスの否定攻撃を防ぐために必要である、 -長いループの一端となる、そしてgas切れとなることで、大量の承認者のコンピューターパワーを実際にはストレージをクリアすることもgas を消費することも無く行わせてしまう。 -この50%のcapは、マイナーに対して定量のガスト共に与えられたトランザクションを、 -マイナーが、トランザクションを実行するためのコンピューターパワーに対して課された上限を図るために必要である。 - -* コントラクトによって与えられたメッセージの中のデータに掛かるgasのコストは無い。 -これはメッセージコールの最中に、呼ばれたデータをコピーする必要は無いからだ、 -何故なら呼ばれたデータは、子の実行が進行中であった最中でも変わることのない -親のコントラクトのメモリーへのポインタとしてシンプルに考えることが出来るためである。 -* メモリーは無限に拡張可能なアレイだ。しかしながら32バイトのメモリーごとのメモリーの拡大に対してgasが掛かる。(切り上げ) -* 幾つかのopcodeではコンピュテーションの時間は大きく引数に依存する、様々なgasのコストを持ちうる。 -例えば、gasのコストとなるEXPが10+10バイトの指数であるとして(例, x^0 = 1 gas, x^1 ....x^255=2gas, x^256 ... x^65535 = 3gas, etc) -Copuするためのopcodesに掛かる(CALLDATACOPY, CODECOPY, EXTCODECOPY)gasのコストは 32バイトのコピー毎に対して、1 + 1掛かる。(切り上げ)(LOGも同様のに似ているルール). -メモリーの拡大に対してのgas残すとは、カバーするために十分ではない、quadraticな攻撃に対して開いている状態であるからである。 -(50000 回の 50000gasを消費するCALLDATACOPYを行い 50000^2のコンピューティングの費用だが、50000以内のgasしかgasのコストの変数が導入される前に提供されていないからだ。) -* CALLのopcode(そしてCALLCODEも同様に)そのバリューがノンゼロの場合には追加の9000gasを消費する。 -その理由はあらゆる価値の以降は、書庫となっているノードのための履歴のストレージに対して大変大きな肥大を招くためだ。 -実際のフィーは6700しかかかっていないが、我々は2300の人工的なgasを追加している、これは自動的に受信者に与えられるものだ。 -これはトランザクションを受け取るウォレットがトランザクションのログを作るために十分がgasを持っていることを保証するためだ。 - -gasのメカニズムについての他に重要な点は、gasの値段自体が経済となっていることだ。 -デフォルトの方法では、bitcoinで使われているように、純粋にボランティアの費用を落ち、 -マイナーがゲートキーパーとして働くことに依拠しており、ダイナミックな最低限の費用を設定することだ。 -Ethereumにおける同様の手段は、トランザクションの送り手が、自由にgasのコストを設定することを許すことだ。 -この方法では、Bitcoinのコミュニティに対して大きく賛同された、とりわけそれが"市場に基づいていて”、 -供給と需要が存在し、マイナー同士とトランザクションの送り手同士で値段を決定することを可能としているからだ。 - -この原理の問題は、しかしながらトランザクションのプロセスは市場には無いことだ、 -マイナーがセンダーに提供するサービスとしてトランザクションのプロセスに対して構文解析を行うことは直感的に魅力的だが、 -実際には全てのマイナーが含むトランザクションはネットワーク全体によって行われる必要がある。それ故にトランザクションに掛かるコストの殆ど大半は第三者に対して生じるものであり、トランザクションがブロックチェーンに含まれるかどうかを決定するマイナーに対してではない。それ故に、こうした一般的な問題はとても良く起こるのだ。 - -現在、現実にはどのようにしてマイナーが作業しているのかについての情報が欠如しているために、私達は大変シンプルなアプローチを行おうとしている。それは投票システムである。 -マイナーは最後のブロックの1/1024のgas limitとなるように、 -gas のlimitを現在のブロックに対して設定する権利を持っており、 -そして結果もたらされるgasのリミットは、マイナー達の設定の中央値となるべきである。 -将来我々がソフトフォークを可能にしてより正確なアルゴリズムとするだろう。 - -### 仮想マシーン -Ethereumの仮想マシーンは、トランザクションのコードを実行させるエンジンである。 -それはEthereumと他のシステムの根本的な違いだ。 -仮想マシーンがコントラクトとメッセージのモデルを分割したものとして考えるべきであることに注意して欲しい。 -例えば、SIGNEXTENDのopcodeはVMの機能の機能だが、実 -際にはコントラクトは他のコントラクトを呼び出し、サブコールに対してのgasの限界を定める事ができ、 -コントラクトとメッセージのモデルの一部におけるsub-callを行う事が出来る。 - -EVM内の設計原理は下記である。 -* **シンプルさ**: 少なく、そしてローレベルのopcodeで出来るだけ行う。なるべく少ないデータ型でなるべく少ない仮想マシーンレベルの設計を行う。 -* **統合的な決定性**: 絶対的なVMの仕様のどの部分においても曖昧な部分は許されない、そしてその結果として -完全に決定的なものとなる。加えて、gasの消費量を計算するために正確なコンピュテーションの段階のコンセプトがあるべきである。 -* **容量の節約**: EVMのアセンブルは出来るだけコンパクトでなければならない。(例; 4000バイトの基本サイズを持つCプログラムは受け入れられない) -* **期待されるアプリケーションに対しての特化性**: 20バイトのアドレスと、32バイトの値を持つカスタムの暗号を取扱うための能力、 -カスタムの暗号化を行うための数学的なモジュール、ブロックとトランザクションのデータを読み込むこと、状態とやりとりする能力 -* **シンプルなセキュリティ**: VMをセキュリティホールが無いものにするためのgasコストを利用するモデルを思いつくことは簡単だろう。 -* **最適化に対して使い勝手が良いこと**:最適化を導入するために簡単であること。JITでコンパイルされたものや、その他の方法で速度が改善されたバージョンのVMが構築出来るようにするためだ。 - -これ迄幾つかの特定の使用に対する決定がなされてきた。 -* **一時的/永続的なストレージの区別** -仮想マシーンのインスタンスの中に存在し、VMの実行が終わると同時に消滅する一時的なストレージと、 -アカウント毎にブロックチェーンに刻まれる状態のレベルで存在する永続的なストレージの2つには明確な区別が存在する。 -例えば、下記のようなツリー型の実行が行われることを考えてみよう。 -(Sは永続的なストレージに対して、そしてMは一時的なストレージに対してである。): -(i) AはBを呼び出す。 -(ii)Bは B.S[0] = 5, B.M[0] = 9 -(iii) B はCを呼び出す -(iv)CはBを呼び出す、ここでBがB.S[0]を呼びだそうとすれば、Bには以前から保存されていた値を受け取る。 -(v)だがmBがBを呼びだそうとし、この点において、もしBがB.M[0]を呼び出せば0を受け取る、なぜならば仮想マシーンの新しいインスタンスは新しい一時的なストレージを持つからだ。 -もし、BがB.M[0] = 13 とB.S[0] = 17 を内部のコールの中で行うと、この内部のコールもCのコールも終了し、 -Bの外部コールへと実行が戻される。 -この区別の目的は、 -(1)互いの実行うインスタンスが再帰的な呼び出しにより破壊されることのない自身のメモリーを与えるため。セキュアとし、プログラミングを簡単にするため。 -(2)とても早くメモリーを操作できる形式を提供すること、何故ならストレージの更新はツリーを変更する必要があるため、遅い必要があるからだ。 -* **スタック/メモリーモデル** -この決定が早くから為されたのは3つのタイプのコンピューターの状態を持つためだ。 -(プログラムのカウンターが次のインストラクションを指していることを脇においてだ。) -その3つの状態はスタック(通常の32バイト値のLIFOスタック)、 -そしてメモリー(無限に拡張可能な一時的なバイトアレイ)と -ストレージ(永続的なストレージ)だ。 -一時的なストレージ上では、スタックとメモリーの構成の代替は、メモリーだけの構成、もしくは -いくつかのレジスタとメモリーのハイブリッドの構成。(レジスタとメモリはあまり違わない、通常はレジスタは一種のメモリのため) -そのような状況において、あらゆるインストラクションは3つの引数を取っている、例えばADD R1 R2 R3: M[R1] = M[R2] + M[R3]. -スタックの考え方に従えば明らかな理由のために選ばれ、4倍以上コードを小さくする事が出来る。 -* **32バイトの文字のサイズ** 4か8バイトの単語の代替として、大半の他の構造で使われているように、もしくは無数にビットコインで使われているように。 -4 or 8 バイトの単語ではあまりにも制限が厳しくアドレスや、暗号の計算のための値を保存することが出来なかったり、 -制限が無い場合にはが安全なgasのモデルを作るためにあまりに厳しい場合がある。 -只十分に多くの暗号の実装で共通している32バイトの値は、十分に大きいからである、、それはアドレスについてもあてはまる(アドレスをパックして、単独のストレージの値へと挿入する最適化の方法として)、だが究極的に非効率というほど大きくはない。 - -* **我々独自のVMを持つこと**:代替案としてJavaを使うことや、幾つかのLispや、Luaのプログラミング言語を使うことが考えられるが、 -我々は特別なVMを持つことが適していると決定した。 -何故ならば -(i)我々のVMの仕様は他の多くのVMよりも大変シンプルだからである。 -何故なら他の仮想マシーンでは複雑さのために大変安いコストを払わなければならない、 -一方で、我々の場合、複雑なユニットを作り出すことは、開発が中央に集中している状況を作り出す高いバリアへと繋がり、 -コンセンサスが出来なくなるような、セキュリティホールの潜在的な可能性となるからだ。 -(ii)より一層VMを特殊に作る上げる事が出来る。例えば32バイトのサイズの宣言を持つことだ。 -(iii)インストール自体が難しくなってしまうというような、複雑な外部依存を持たないでいられる -(iv)我々の特定のセキュリティのニーズにEthereumに対しての全てのセキュリティのレビューを行うために外部のVMのセキュリティのレビューを行うことを余儀なくされてしまうだろう、そしてその努力で得られるものはあまり大きくない。 -* **様々な拡張可能なメモリーのサイズを使うこと。** もしサイズが小さく、もしサイズが大きければ不必要にコストが高くなるのであれば、我々は固定長のメモリーの長さの制約が必要無いと考えた。 -そしてもしメモリーアクセスのための宣言が必要無いのであれば、外部へのアクセスをチェックするどのような場合においても、固定長の長さは実行をより効率的にするだろう。 -* **スタックサイズの制限を持たないこと** 特定の理由が無い。多くの場合gasのコストと、ブロックレベルのgasの制限を組み合わせることに依って、制限は必ずしも必要ないことを心に留めて欲しい、 -これら2つの組み合わせによって、全てのリソースの消費に対して常に天井を設ける働きを実行できる。 -* **コールの深さを1024に制限すること** 多くのプログラミング言語では、スタックが深い点において、 -多くのメモリーの使用かコンピューター負荷によってプログラムが壊れるよりも一層早く、 -そのためにブロック内ののgasの制限による暗黙的なリミットだけでは十分ではない。 - -* **型を持たない*こと* シンプルさのために行った。代わりに、署名されたか署名されていないDIV, SDIV,MOD,SMODを示すopcodeを使った、(それはADDとMULとのためにあり、署名されたものと署名されていないopcoceは同様のものだ。 -そして固定長の場所に対しての算数(深い、固定された場所、数学的に他のベネフィットのある32バイトの文字)は皆シンプルである。 -例えば32ビットの深さでは、a * b -> (a * b )/ 2^32 , a / b -> a * 2^32 / b and +, - and * are unchanged from integer -仮想マシーンにおいて、関数と幾つかのopcodeの目的は明らかである、しかしながら他のopcodeはあまり自明ではない。 -例えば特定の理由は下記のように上げられる。 - -* **ADDMOD**, **MULMOD**: 大半の場合において、addmod(a, b, c) = a * b % cであるがしかしながら、 -楕円曲線暗号の多くのクラスは特定の場合ではそしてそのためにa * b % cを直接行うことで、それ故に実際に行っている。 -そして完全に異なる結果を生み出すこととなる。 -ある形式において、a * b % c を32バイトの値と共に32バイトのスペースにて行うことはかなり重く厚い処理となってしまう。 -* **SIGNEXTEND**: SIGNEXTENDの目的はtypecastingを大きな署名して大きな符号付き整数から、小さな符号付き整数へと型変換するためだ。 -小さな符号付き整数は有用である、何故ならばJITに依ってコンパイルされた仮想マシーンの環境では、 -32バイトの整数を第一義に扱って長く走っているコードの塊を検出し、かなりの速度向上が見込むことが出来るかもしれないからだ。 - -* **SHA3**: Ethereumでは、SHA3はとても応用性が高く、セキュアで無限の大きさのハッシュのマップが出来る。 -ストレージを扱うハッシュのマップは悪意ある衝突を防ぐために、 -セキュアなハッシュのファンクションを使う必要が出てくるだろう、同様にマークルツリーを認証するためにもそしてEthereumのようなデータの構造を認証するためにも使われるだろう。 -鍵となる点は、SHA3はSHA256や、ECRECOVERやRIPEMD160の対であることであり、opcodeではなく、仮のコントラクトして含まれている。 - -その目的は分割されたカテゴリーに暗号化の手段を分けることによって、 -もし、いつか正しい”ネイティブの拡張"によるシステムを考案した時に -より多くのそんなコントラクトを、opcodeの空間を埋めること無く加える事が出来るようにするためだ。 - -* **ORIGIN**: トランザクションの送り手を与えるORIGINのopcodeを使う第一の目的は、コントラクトがgasのためにリファンドの支払いが出来るようにするためだ。 - -* **COINBASE**: COINBASEの第一義的な使い方は、 -(i) 補助貨幣がネットワークのセキュリティの向上に役立つようにするため。 -(ii) Schelling coinのような副次的な分散形のアプリケーションのための、分散形の経済のセットとして -マイナーが使えるようにするようにするためだ。 -* **PREVHASH**: 程々にセキュアなランダムさを生み出すソースとして利用される。 -コントラクトが、マークルツリーの以前のブロック内のproof of stateを、 -とても複雑で再帰的な"Ethereum内、Ethereumライトクライアント"の構造を必要とすること無く -確かめる事が出来るようにするためにある。 - -* **EXTCODESIZE** , **EXTCODECOPY**: 第一義的な使い方はコントラクトが、他のコントラクトとやり取りを開始する前に、 -他のコントラクトのコードがテンプレートの定義に反していないかをチェックするか、 -模倣していないかさえもチェックする事が出来るようにするためにある。 -下記に使い方がある。http://lesswrong.com/lw/aq9/decision_theories_a_less_wrong_primer/  (アプリケーション用) - -* **JUMPDEST**: jumpの行き先が制限されており、幾つかのインデックスに制限されていたときに、 -JITでコンパイルされた仮想マシーンがより一層簡単に実装でき、 -様々な行き先でのコンピュテーションの複雑さがおおまかにO(log(正しいjumpの行き先の数))、だが -固定的なjumpは常に定数時間を要する。) -それ故に、我々は -(i)正当に認証された変数のjumpの行き先に対しての制約 -(ii)動的なjumpに対して静的なjumpを使うことのインセンティブ -2つのゴールを満たすためには、我々は(i)直ぐにプッシュによって先行されるjumpは他のjumpにのみjumpすることが出来る。 -(ii)他のjumpはJUMPDESTにのみjumpを行う事が出来る。 -jumpに対してのjumpを制限することは、jumpは動的なのか静的なのかという質問がただコード内の以前のオペレーションを見るだけで判別することが出来るようになる。 -プッシュデータに対してのjumpを禁じることはJITの仮想マシーンのコンパイルと実行を早める事にも繋がる。 -LOG: LOGはイベントをログするためにある、上記のtrieの使い方のセクションを参照 -* **CALLCODE**: -目的はコントラクトが他のコントラクトに保存されているコード形式となっているfunctionsを呼び出すことが出来るようにし、 -スタックとメモリーが分割されているが、コントラクトを自分のストレージ内で使うこと。 -これはスケール出来るような形で"標準的ライブラリー"のコードをブロックチェーン上に実装することをかなり容易にしている。 -* **SUICIDE**: もしもう必要無いのであればmこのopcodeはコントラクトがすぐに自分自身を消去する。 -最後に実行されるトランザクションにてSUICIDEは実行されるが、すぐに実行されるわけではない、 -なぜならば、既に実行されたsuicide(自殺)を差し戻すことが出来るようにするということは -キャッシュの複雑さを著しく増大させ、仮想マシーンの効率的な実装において大変な困難が強いられるという事実があるためだ。 -* **PC**: 全てのPCのopcodeのインスタンスは、そのインデックスにある実際のプログラムカウンターにpushとして挿入されているため、 -理論的には必ずしも必要ではないが、コード中でPCを使うことに依って、位置に依存しないコードを作る事が出来る。 -(例えば、コピー/ペーストされて他のコントラクトに入ってしまい、コンパイルされた関数が、 -異なるインデックスになってしまっても、プログラムを破壊しない) \ No newline at end of file diff --git a/pages/ethereum-toc/[chinese]-ethereum-toc.md b/pages/ethereum-toc/[chinese]-ethereum-toc.md deleted file mode 100644 index b88ddfd16..000000000 --- a/pages/ethereum-toc/[chinese]-ethereum-toc.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -name: Ethereum TOC -category: ---- - -中文读者可以在以太坊中文社区( www.1tf.org )获知最新信息。 - -白皮书:[以太坊(Ethereum ):下一代智能合约和去中心化应用平台](https://github.com/ethereum/wiki/wiki/White-Paper-%5BChinese%5D) - -[Serpent语言指南](https://github.com/ethereum/wiki/wiki/%5B%E4%B8%AD%E6%96%87%5D-Serpent%E6%8C%87%E5%8D%97) - -[以太坊开发计划](https://github.com/ethereum/wiki/wiki/%E4%BB%A5%E5%A4%AA%E5%9D%8A%E5%BC%80%E5%8F%91%E8%AE%A1%E5%88%92) - -[术语表](https://github.com/ethereum/wiki/wiki/%E6%9C%AF%E8%AF%AD%E8%A1%A8) - -[网络状态监控](https://github.com/ethereum/wiki/wiki/Network-Status-%28Chinese%29) \ No newline at end of file diff --git a/pages/ethereum-toc/[french]-ethereum-toc.md b/pages/ethereum-toc/[french]-ethereum-toc.md deleted file mode 100644 index 85eeef455..000000000 --- a/pages/ethereum-toc/[french]-ethereum-toc.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -name: Ethereum TOC -category: ---- - -# Contrats Intelligents et Plateforme d'Application Décentralisée de nouvelle génération - -Lorsque Satoshi Nakamoto lance Bitcoin le premier réseaux décentralisé cryptographié (Blockchain) en Janvier 2009, il introduit simultanément deux concepts radicaux et très incertains. Le premier est le " bitcoin " , une monnaie décentralisée peer-to-peer qui conserve une valeur sans support financier d'un emetteur centralisé, ni valeur intrinsèque. Jusqu'à présent, le "bitcoin" comme monnaie a retenu l'essentiel de l'attention du public. D'une part en termes d'aspects politiques d'une monnaie sans banque centrale et d'autre part, à cause de son extrême volatilité à la hausse et à la baisse des prix. Le second concept, tout aussi important, qui emerge de l'expérience de Satoshi : un accord public sur l'ordre des transactions sous forme de preuve de travail, le Blockchain. Bitcoin peut être décrit comme un système du «premier à déposer son action» : si une entité dispose 50 BTC et envoie simultanément à A et à B la meme somme 50 BTC, seule l'opération qui sera validée en premiere sera confirmée. En partant de deux opérations, il n'existe pas de methode pour déterminer laquelle est venue en premiere, et pendant des décennies ce manque a entravé le développement d'une monnaie numérique décentralisée . Le blockchain de Satoshi était la première solution décentralisée crédible. Désormais, l'attention commence rapidement à se déplacer vers cette deuxième partie de la technologie, et vers l'utilisation du concept de blockchain pour autre chose que de l'argent. - -Les applications les plus communément citées utilisent un avoir numérique sur le blockchain pour représenter des monnaies et instruments financiers sur-mesure ("colored coins"), la proprieté d'un actif sous-jacent ("smart property"), des actifs non-fongible comme les noms de domaine ("Namecoin") ainsi que des applications plus développées comme une plateforme de bourse décentralisée, de dérivés financiers, de jeux en ligne P2P, d'identité ou de reputation. Un autre domaine important de recherche : les systèmes de "smart contracts" qui transfèrent des actifs numériques selon des règles préétablies. Par exemple, un contract de liquidité pourrait avoir la forme : "A peut retirer un montant X de ses fonds par jours, B peut retirer Y par jours, ensemble A et B peuvent retirer ce qu'ils désirent, enfin A peut restreindre l'habilité de B d'avoir accès à ses fonds. L'extension logique de ce qui précède est l'Organisation Autonome Décentralisée (OAD) - Des contracts intelligents qui contiennent les actifs et les statuts de l'organisation tout entière. Ethereum aspire à fournir un Blockchain fondé sur un language de programmation Turing-complet à part entière qui peut être utilisé pour créer des contracts qui encodent des fonctions d'états de transition arbitraire, permettant à l'utilisateur de créer les systèmes décris précédemment, ainsi que de nombreuses applications que nous n'avons pas encore imaginées, en rédigeant une suite logique en quelques lignes de code. - - - -**Table des matières :** - -1. Histoire -1.1. Bitcoin comme système d'états transitoires -1.2. Mining -1.3. Arbre de Merkle -1.4. Application alternative sur le blockchain -1.5. Scripting - - -2. Ethereum -2.1 Compte Ethereum -2.2 Messages and Transactions -2.3 Fonction de Transition d'Etat Ethereum -2.4 Code d'Execution -2.5 Blockchain et Mining - -3. Applications -3.1 Monnaies -3.2 Dérivés Financiers -3.3 Système d'Identité et de Reputation -3.4 Stockage de Fichiers Décentralisé -3.5 Organisation Autonome décentralisée -3.6 Nouvelles applications - -4. Miscellanées et préoccupations -4.1 Mise en oeuvre GHOST modifiée -4.2 Commissions -4.3 Calculs et Turing-Complet -4.4 Monnaie et émission de monnaie -4.5 Centralisation du minage -4.6 Extensibilité du modèle - -5. Conclusion -5.1 References et suggestions de lecture - - - -**Histoire** - -Le concept d'une monnaie digitale décentralisée, ainsi que les applications alternatives comme l'enregistrement de propriétés, existe depuis des décennies. Les protocols anonymes de monnaie éléctronique des années 1980 et 1990, principalement dépendant de cryptographie primitive connue sous le nom de signature aveugle de Chaum (Chaumian blinding), proposaient une monnaie avec un haut degré de confidentialité. Cependant, le protocole reposait sur un intermediaire centralisé, ce qui freina son adoption. En 1998, Wei Dai introduit b-money, la premiere proposition à introduire la création de monnaie par la résolution de problemes informatiques et un consensus décentralisé. En 2005, Hal Finney introduit le concept de preuves de travail réutilisables "reusable proofs of work", mêlant les travaux de recherche sur b-money à la résolution de la preuve de Hashcash pour créer le concept de cryptomonnaie. Encore une fois le système reposait sur un tiers. - -Parce qu'une monnaie repose sur le système du premier-déposant, où l'ordre de transaction est souvent d'une importance critique, une monnaie décentralisée requiert une solution provenant d'un consensus décentralisé. Les pré-Bitcoins ont dû faire face à l'obstacle de ne résoudre que la moitié du problème en se concentrant, pendant plusieurs années, sur la création d'un consensus multi-partie tolerant les pannes Byzantines. Les protocoles supposaient que tous les participants du système étaient connus et généraient des marges de sécurité de la forme : "S'il y a N Participants, Alors le système peut tolérer N/4 participants malicieux". Toutefois, dans un tel système, les marges de sécurité sont vulnérables aux attaques Sybil, où un individu peut créer des milliers de noeuds simulés sur un serveur ou un botnet et les utiliser pour sécuriser une part majoritaire. - -Satoshi innova en proposant l'association d'un protocol de consensus décentralisé très simple, basé sur des noeuds combinant les transactions dans un 'bloc" toutes les dix minutes créant une chaine de blocs ("blockchain") en expansion permanente, à la preuve de travail ("proof of work") comme mechanisme par lequel les noeuds gagnent le droit de participer au système. Tandis que les noeuds disposant d'une grande capacité de calcul ont une influence proportionnelle, il est plus facile de créer un million de noeuds que de concevoir une puissance de calcul supérieure à la moitié du réseaux. Malgré sa simplicité et sa crudité, le modèle de chaine de bloc du Bitcoin a su s'imposer, et pourrait être le berceau dans les cinq prochaines années de plusieurs centaines de monnaies et de protocols à travers le monde. - - -**Bitcoin comme système d'états transitoires** - -D'un point de vue technique, le registre de Bitcoin peut être perçu comme un système de transition d'états, où: -- Chaque "état" représente le statut de propriété de toutes les bitcoins qui existent. -- Une fonction de transition d'états prenant un état et une transaction, et produisant un nouvel état comme résultat. - -Dans un système bancaire traditionnel par exemple: -- L'état a un instant t serait un bilan financier -- Une transaction serait une requête de transfert de $X de A vers B -- La fonction de transition d'états réduirait le compte de A de $X et augmenterait celui de B de $X. Si A n'avait pas suffisamment de fonds, la fonction retournerait une erreur. - -Par conséquent, on peut formellement définir: - - APPLIQUER(S,TX) -> S' ou ERREUR - -Dans l'exemple précédent: - - APPLIQUER({ Alice: $50, Bob: $50 },"envoyer $20 de Alice vers Bob") = { Alice: $30, Bob: $70 } - -Mais - - APPLIQUER({ Alice: $50, Bob: $50 },"envoyer $70 de Alice vers Bob") = ERREUR - -L'"état" global dans Bitcoin est l'ensemble de toutes les "pièces" (bitcoins, en termes techniques ce sont des "Données de sorties de transactions non-depensées" ou unspent transaction outputs/UTXO en anglais). Chaque pièce a une valeur et un propriétaire (définie par une adresse de 20 octets qui correspond essentiellement a une clé publique de cryptographie). Une transaction contient une ou plusieurs données en entrée, avec chaque données contenant une référence a une UTXO existante et une signature cryptographique produite par la clé privée associée au propriétaire de l'adresse, et une ou plusieurs données de sortie telles que chacune contient une nouvelle UTXO a rajouter a l'état global. - -WIP (translating https://github.com/ethereum/wiki/wiki/White-Paper#bitcoin-as-a-state-transition-system) - -Signature Aveugle de Chaum : -http://www.hit.bme.hu/~buttyan/courses/BMEVIHIM219/2009/Chaum.BlindSigForPayment.1982.PDF -Hashcash : -http://fr.wikipedia.org/wiki/Hashcash -Attaque Sybil : -http://en.wikipedia.org/wiki/Sybil_attack \ No newline at end of file diff --git a/pages/ethereum-toc/[german]-ethereum-toc.md b/pages/ethereum-toc/[german]-ethereum-toc.md deleted file mode 100644 index 27b457994..000000000 --- a/pages/ethereum-toc/[german]-ethereum-toc.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -name: Ethereum TOC -category: ---- - -### Willkommen bei Ethereum, der nächsten Generation von elektronischen Verträgen und der Plattform für dezentrale Anwendungen. - -[Ethereum whitepaper](https://github.com/ethereum/wiki/wiki/%5BGerman%5D-White-Paper) - -[RLP](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP), die Recursive Linear Prefix - Spezifikation für Kodierung der Daten ation, used for data encoding bei Ethereum. - -[Patricia Tree](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree), die Spezifikation des Merkle Patricia Baums (aka Trie), die Struktur zum Speichern und Hashen der Blockkette in Ethereum. - -[Wire protocol](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Wire-Protocol) Spezifikation. - -[CLL](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-CLL), die Spezifikation der "C-ähnlichen Programmiersprache" für die Gestaltung von Verträgen. - -[Dagger](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Dagger), die "proof-of-work" Spezifikation Ethereums. - -[Block Protocol 2.0](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Block-Protocol-2.0) - -[Layers](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Layers) - -[Clearinghaus](https://github.com/ethereum/wiki/wiki/%5BGerman%5D-Clearinghaus) diff --git a/pages/ethereum-toc/[italian]-ethereum-toc.md b/pages/ethereum-toc/[italian]-ethereum-toc.md deleted file mode 100644 index 8431be229..000000000 --- a/pages/ethereum-toc/[italian]-ethereum-toc.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -name: Ethereum TOC -category: ---- - -### Benvenuti. Ethereum: il contratto intelligente di nuova generazione e piattaforma di applicazioni decentralizzate. - -[Libro Bianco di Ethereum](https://github.com/ethereum/wiki/wiki/%5BItalian%5D-Libro-Bianco) - -[RLP](https://google.it), la caratteristica del prefisso lineare ricorsivo, utilizzato per la codifica dei dati attraverso Ethereum. - -[Patricia Tree](https://google.it) la caratteristica dell'albero Merkle Patricia (conosciuta anche come Trie), la struttura utilizzata per archiviare e processare attraverso la funzione di Hash lo stato della catena di blocchi in Ethereum. - -[Protocollo di connessione](https://google.it), caratteristiche. - -[Serpente](https://google.it), il linguaggio di alto livello usato per scrivere contratti. Vedi il tutorial qui. - -[LLL](https://google.it), caratteristica di Basso-Livello "Linguaggio di Basso Livello", usata per scrivere contratti nella serie PoC da Poc-3 - -[Dagger](https://google.com), Prova di lavoro "proof-of-work" di Ethereum. - -[Protocollo di Blocco 2.0](https://google.it) - -[Protocolli](https://google.it) - -[Camera di Compensazione](https://google.it) - -[Introduzione allo sviluppo su Ethereum](https://github.com/ethereum/wiki/wiki/%5BItalian%5D-Introduzione-allo-sviluppo-su-Ethereum) - -[Impostare il proprio ambiente di sviluppo Ethereum](https://github.com/ethereum/wiki/wiki/%5BItalian%5D-Impostare-il-proprio-ambiente-di-sviluppo-Ethereum) \ No newline at end of file diff --git a/pages/ethereum-toc/[spanish]-ethereum-toc.md b/pages/ethereum-toc/[spanish]-ethereum-toc.md deleted file mode 100644 index 1f4770a5b..000000000 --- a/pages/ethereum-toc/[spanish]-ethereum-toc.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -name: Ethereum TOC -category: ---- - -### Bienvenidos a Ethereum, la plataforma para la siguiente generación de contratos inteligentes y aplicaciones descentralizadas. - -[Whitepaper de Ethereum](https://github.com/ethereum/wiki/wiki/White-Paper) - -[RLP](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP), Prefijo Linear Recursivo (Recursive Linear Prefix), usado para codificación de datos a través de Ethereum. - -[Patricia Tree](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree) especificaciones del árbol Merkle Patricia (“Merkle Patria Tree”, también conocido como Trie), la estructura usada para almacenar y procesar a través de funciones Hash el estado de la cadena de bloques en Ethereum. - -[Protocolo de conexión](https://github.com/ethereum/wiki/wiki/Ethereum-Wire-Protocol), especificaciones. - -[CLL](https://github.com/ethereum/wiki/blob/master/CLL.md), Lenguage de alto nivel similar a C usado para crear contratos, especificaciones. - -[Dagger](https://github.com/ethereum/wiki/blob/master/Dagger.md), Prueba de trabajo (Proof-of-work) de Ethereum. - -[Protocolo de Bloques 2.0](https://github.com/ethereum/wiki/blob/master/Block-Protocol-2.0.md) - -[Capas](https://github.com/ethereum/wiki/blob/master/Layers.md) - -[Cámara de compensación](https://github.com/ethereum/wiki/blob/master/Clearinghouse.md) diff --git a/pages/patricia-tree/[english]-patricia-tree.md b/pages/patricia-tree/[english]-patricia-tree.md deleted file mode 100644 index 824c7ea5e..000000000 --- a/pages/patricia-tree/[english]-patricia-tree.md +++ /dev/null @@ -1,141 +0,0 @@ ---- -name: Patricia Tree -category: ---- - -### Merkle Patricia Tree Specification - -Merkle Patricia trees provide a cryptographically authenticated data structure that can be used to store all (key, value) bindings, although for the scope of this paper we are restricting keys and values to strings (to remove this restriction, just use any serialization format for other data types). They are fully deterministic, meaning that a Patricia tree with the same (key,value) bindings is guaranteed to be exactly the same down to the last byte and therefore have the same root hash, provide the holy grail of O(log(n)) efficiency for inserts, lookups and deletes, and are much easier to understand and code than more complex comparison-based alternatives like red-black trees. - -### Preamble: Basic Radix Trees - -In a basic radix tree, every node looks as follows: - - [ value, i0, i1 ... in] - -Where i0 ... in represent the symbols of the alphabet (often binary or hex). value is the terminal value at the node, and the values in the i0 ... in slots are either NULL or pointers to (in our case, hashes of) other nodes. This forms a basic (key, value) store; for example, if you are interested in the value that is currently mapped to dog in the tree, you would first convert dog into the alphabet (giving 646f67 if we're using hex), and then descend down the tree following that path until at the end of the path you read the value. That is, you would first look up the root hash in a key/value store to get the root node, then look up node 6 of the root node to get the node one level down, then look up node 4 of that, then look up node 6 of that, and so on, until, once you followed the path root -> 6 -> 4 -> 6 -> f -> 6 -> 7, you look up the value of the node that you have and return the result. - -The update and delete operations for radix trees are simple, and can be defined roughly as follows: - - def update(node,key,value): - if key == '': - curnode = db.get(node) if node else [ NULL ] * 17 - newnode = curnode.copy() - newnode['value'] = value - else: - curnode = db.get(node) if node else [ NULL ] * 17 - newnode = curnode.copy() - newindex = update(curnode[key[0]],key[1:],value) - newnode[key[0]] = newindex - db.put(hash(newnode),newnode) - return hash(newnode) - - def delete(node,key): - if key == '' or node is NULL: - return NULL - else: - curnode = db.get(node) - newnode = curnode.copy() - newindex = delete(curnode[key[0]],key[1:]) - newnode[key[0]] = newindex - if len(filter(x -> x is not NULL, newnode)) == 0: - return NULL - else: - db.put(hash(newnode),newnode) - return hash(newnode) - -The "Merkle" part of the radix tree arises in the fact that a deterministic cryptographic hash of a node is used as the pointer to the node, rather than some 32-bit or 64-bit memory location as might happen in a more traditional tree implemented in C. This provides a form of cryptographic authentication to the data structrure; if the root hash of a given trie is publicly known, then anyone can provide a proof that the trie has a given value at a specific key by providing the nodes going up each step of the way. it is impossible for an attacker to provide a proof of a (key, value) pair that does not exist since the root hash is ultimately based on all hashes below it, so any modification would change the root hash. - -However, radix trees have one major limitation: their inefficiency. If you want to store just one (key,value) binding where the key is a few hundred characters long, you will need over a kilobyte of extra space to store one level per character, and each lookup or delete will take hundreds of steps. The Patricia tree introduced here solves this issue. - -### Specification: Compact encoding of hex sequence with optional terminator - -The traditional compact way of encoding a hex string is to convert it into binary - that is, a string like 0f1248 would become three bytes \[15, 18, 72\] (or in string representation \x0f\x18H). However, this approach has one slight problem: what if the length of the hex string is odd? In that case, there is no way to distinguish between, say, 0f1248 and f1248. Additionally, our application in the Merkle Patricia tree requires the additional feature that a hex string can also have a special "terminator symbol" at the end (denoted by the 'T'). A terminator symbol can occur only once, and only at the end. An alternative way of thinking about this to not think of there being a terminator symbol, but instead treat bit specifying the existence of the terminator symbol as a bit specifying that the given node encodes a final node, where the value is an actual value, rather than the hash of yet another node. - -To solve both of these issues, we force the first nibble of the final bytestream to encode two flags, specifying oddness of length (ignoring the 'T' symbol) and terminator status; these are placed, respectively, into the two lowest significant bits of the first nibble. In the case of an even-length hex string, we must introduce a second nibble (of value zero) to ensure the hex-string is even in length and thus is representable by a whole number of bytes. Thus we construct the following encoding: - - def compact_encode(hexarray): - term = 1 if hexarray[-1] == 16 else 0 - if term: hexarray = hexarray[:-1] - oddlen = len(hexarray) % 2 - flags = 2 * term + oddlen - if oddlen: - hexarray = [flags] + hexarray - else: - hexarray = [flags] + [0] + hexarray - // hexarray now has an even length whose first nibble is the flags. - o = '' - for i in range(0,len(hexarray),2): - o += chr(16 * hexarray[i] + hexarray[i+1]) - return o - -Examples: - - > [ 1, 2, 3, 4, 5 ] - '\x11\x23\x45' - > [ 0, 1, 2, 3, 4, 5 ] - '\x00\x01\x23\x45' - > [ 0, 15, 1, 12, 11, 8, T ] - '\x20\x0f\x1c\xb8' - > [ 15, 1, 12, 11, 8, T ] - '\x3f\x1c\xb8' - -### Main specification: Merkle Patricia Tree - -Merkle Patricia trees solve the inefficiency issue by adding some extra complexity to the data structure. A node in a Merkle Patricia tree is one of the following: - -1. NULL (represented as the empty string) -2. A two-item array `[ key, v ]` (aka kv node) -3. A 17-item array `[ v0 ... v15, vt ]` (aka diverge node) - -The idea is that in the event that there is a long path of nodes each with only one element, we shortcut the descent by setting up a kv node `[ key, value ]`, where the key gives the hexadecimal path to descend, in the compact encoding described above, and the value is just the hash of the node like in the standard radix tree. Also, we add another conceptual change: internal nodes can no longer have values, only leaves with no children of their own can; however, since to be fully generic we want the key/value store to be able to store keys like 'dog' and 'doge' at the same time, we simply add a terminator symbol (16) to the alphabet so there is never a value "en-route" to another value. - -For a kv node, a two-item array `[ key, v ]`, `v` can be a value or a node. -* When `v` is a value, key must be the result of compact encoding a nibbles list **with** terminator. -* When `v` is a node, key must be the result of compact encoding a nibbles list **without** terminator. - -For a diverge node, a 17-item array `[ v0 ... v15, vt ]`, each item in v0...v15 should always be a node or blank, and vt should always be a value or blank. So to store a value in one item of v0...v15, we should instead store a kv node, where k is the result of compact encoding an empty nibbles list **with** terminator. - -Here is the extended code for getting a node in the Merkle Patricia tree: - - def get_helper(node,key): - if key == []: return node - if node = '': return '' - curnode = rlp.decode(node if len(node) < 32 else db.get(node)) - if len(curnode) == 2: - (k2, v2) = curnode - k2 = compact_decode(k2) - if k2 == key[:len(k2)]: - return get(v2, key[len(k2):]) - else: - return '' - elif len(curnode) == 17: - return get_helper(curnode[key[0]],key[1:]) - - def get(node,key): - key2 = [] - for i in range(len(key)): - key2.push(int(ord(key) / 16)) - key2.push(ord(key) % 16) - key2.push(16) - return get_helper(node,key2) - -Example: suppose we had a tree containing the pairs ('dog', 'puppy'), ('horse', 'stallion'), ('do', 'verb'), ('doge', 'coin'). First, we convert the keys over to hex format: - - [ 6, 4, 6, 15, 16 ] : 'verb' - [ 6, 4, 6, 15, 6, 7, 16 ] : 'puppy' - [ 6, 4, 6, 15, 6, 7, 6, 5, 16 ] : 'coin' - [ 6, 8, 6, 15, 7, 2, 7, 3, 6, 5, 16 ] : 'stallion' - -Now, we build the tree: - - ROOT: [ '\x16', A ] - A: [ '', '', '', '', B, '', '', '', C, '', '', '', '', '', '', '', '' ] - B: [ '\x00\x6f', D ] - D: [ '', '', '', '', '', '', E, '', '', '', '', '', '', '', '', '', 'verb' ] - E: [ '\x17', F ] - F: [ '', '', '', '', '', '', G, '', '', '', '', '', '', '', '', '', 'puppy' ] - G: [ '\x35', 'coin' ] - C: [ '\x20\x6f\x72\x73\x65', 'stallion' ] - -Where a node is referenced inside a node, what is included is H(rlp.encode(x)) where H(x) = sha3(x) if len(x) >= 32 else x and rlp.encode is the [RLP](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP) encoding function. Note that when updating a trie, you will need to store the key/value pair (sha3(x), x) in a persistent lookup table when you create a node with length >= 32, but if the node is shorter than that then you do not need to store anything when length < 32 for the obvious reason that the function f(x) = x is reversible. \ No newline at end of file diff --git a/pages/patricia-tree/[japanese]-patricia-tree.md b/pages/patricia-tree/[japanese]-patricia-tree.md deleted file mode 100644 index d9a9e3450..000000000 --- a/pages/patricia-tree/[japanese]-patricia-tree.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -name: Patricia Tree -category: ---- - -### Merkle Patricia Tree の仕様 - -Merkle Patricia treeは、(キー、値)のすべての結合を保存することのできる、暗号学的な認証データ構造を与えるが, この資料の視点として、キーと値は文字列に制限する(この制限を解除するには、他のデータ種に対し直列化方式を用いるだけでよい)。 これらは、完全に決定的で、つまり、 同じ(キー、値)の結合は全く同じバイト末に至ることを保証し、故に同じroot hashを持ち、挿入、検索、削除にO(log(n))の効率の聖杯を与え, red-block treeのような、もっと複雑な比較ベースの代替よりずっと簡単に理解できる。 - -### 序文: 基本的なRadix Trees - -基本的なradix tree(基数木)では、すべてのノードは、次のようである: - - [ value, i0, i1 ... in] - -i0 ... は、アルファベットの(しばしばバイナリか16進での)シンボルを表現する。 valueは、ノードの終端の値で, i0 ... の値はNULLか、他のノードへのポインタ(我々のケースでは、ハッシュ値)である。 この形式は、基本的な(キー、値)の保存である; 例えば、もしtree中で現在dogにマッピングされている値に興味があるなら、まずdogをアルファベット(もし16進を使うなら646f67となる)に変換し、そのパスを、終わりになるまでずっと降りて行き、値を読む。すなわち、根のノードを得るために、まずキー/値の記録の根のハッシュを調べる, そして1レベル下のノードを得るために、根のノード6を調べる, そして、そのノード4を調べる, そして、そのノード6を調べる, などなど,根 -> 6 -> 4 -> 6 -> f -> 6 -> 7のパスを一度たどるまで行い, 得たノードの値を調べ、その値を返す。 - -radix treeの更新と削除は、簡単で、大まかには次のように定義される: - - def update(node,key,value): - if key == '': - curnode = db.get(node) if node else [ NULL ] * 17 - newnode = curnode.copy() - newnode['value'] = value - else: - curnode = db.get(node) if node else [ NULL ] * 17 - newnode = curnode.copy() - newindex = update(curnode[key[0]],key[1:],value) - newnode[key[0]] = newindex - db.put(hash(newnode),newnode) - return hash(newnode) - - def delete(node,key): - if key == '' or node is NULL: - return NULL - else: - curnode = db.get(node) - newnode = curnode.copy() - newindex = delete(curnode[key[0]],key[1:]) - newnode[key[0]] = newindex - if len(filter(x -> x is not NULL, newnode)) == 0: - return NULL - else: - db.put(hash(newnode),newnode) - return hash(newnode) - -radix treeの"Merkle"部分は、C(訳注:C言語)で、伝統的にtreeの実装で起こるであろう、32ビットや64ビットのメモリの場所ではなく、ノードの決定的な暗号学的ハッシュがノードのポインタとして使われることに起因している 。このことで、データ構造への暗号学的な認証の方法が得られる; もし、与えられたtrieの根のハッシュが公に知られれば、(訳注:(キー・値)ノードから、根までの?)道の各ステップを上がっていくノードを提供することによりtrieが特定のキーに、与えられた値をもつことを、証明することがだれでも可能である。根のハッシュは、その下のすべてのハッシュに究極的には基づいており、故に、どのような変更でも、根のハッシュが変わるので、攻撃者が存在しない(キー、値)の対の証明を与えることは不可能である。 - -しかし、radix treesには、重要な制限がある: 効率性である。 もし、キーが数百文字の長さのたった1つの(キー、値)の結合を保存する場合, 1文字1レベルを保存するのに別の1キロバイト以上のスペースが必要となる, そして、それぞれの検索と削除は、数百ステップとなる。Patricia treeはこの問題を解決するために導入された。 - -### 仕様: 終端オプションありの16進Compact encoding - -16進文字列の伝統的なエンコード方法は、バイナリに変換することである - つまり、0f1248のような文字列は、[15, 18, 72] の3バイトである。しかし、この方法は1つの小さな問題がある: 16進文字列の長さが奇数だったら? このケースでは、0f1248とf1248を区別する方法がない。 加え、 Merkle Patricia treeの我々の適用では、16進文字列が終わりに特別な "終端記号"('T'と表示される)をもつ16進文字列という、追加の特徴が必要である。 終端記号は、1度のみ、唯一最後に発生しうる。このことを考える上での代替の手段は、終端器号があることを考えず、その代わり、 終端器号の存在を示すビットを、与えられたノードが最終のノード、ここでの値は、他のノードのハッシュではなく、本当の値である、をエンコードしたことを示すビットとして扱うことである, - -これら問題を解決するため、 最後のバイトストリームの最初のニブル(4ビット)に対し、長さ('T'記号は無視)が奇数かどうかを示すものと、 終端の状態の、2つのフラグをエンコードする; それらは、それぞれ、最初のニブルの2つの最下位ビットに置かれる。 偶数の長さの16進文字列であれば, 16進文字列の長さが偶数であり、それ故バイトの全数が表現可能であることを保証するため、2番めのニブル(値はゼロ)を導入しなければならない。故に、次のエンコーディングを構築する: - - def compact_encode(hexarray): - term = 1 if hexarray[-1] == 16 else 0 - if term: hexarray = hexarray[:-1] - oddlen = len(hexarray) % 2 - flags = 2 * term + oddlen - if oddlen: - hexarray = [flags] + hexarray - else: - hexarray = [flags] + [0] + hexarray - // hexarrayは最初のニブルがフラグとなった偶数の長さとなっている。 - o = '' - for i in range(0,len(hexarray),2): - o += chr(16 * hexarray[i] + hexarray[i+1]) - return o - -例: - - > [ 1, 2, 3, 4, 5 ] - '\x11\x23\x45' - > [ 0, 1, 2, 3, 4, 5 ] - '\x00\x01\x23\x45' - > [ 0, 15, 1, 12, 11, 8, T ] - '\x20\x0f\x1c\xb8' - > [ 15, 1, 12, 11, 8, T ] - '\x3f\x1c\xb8' - -### メイン仕様: Merkle Patricia Tree - -Merkle Patricia tree は、データ構造にいくつかの特別な複雑さを加えることにより、非効率な問題を解決する。Merkle Patricia treeのノードは、次のうちの1つである: - -1. NULL (空文字を表現する) -2. 2項目の配列 [ キー,値 ] -3. 17項目の配列 [ v0 ... v15, vt ] - -このアイデアは、ただ1つの要素をもつ長いノードのパスが発生した場合、[キー、値]ノードを作ることで下降をショートカットすることである、ここで、キーは上で述べたcompact encodingされた、下降する16進のパスを与え、値は、標準のradix treeのようにただのノードのハッシュである。また、もうひとつ概念の変更を加える: 内部ノードは、もう値をもてない、ただ子を持たない葉のみが、値をもつことができる; しかし、完全に一般的に、キー/値の保存を'dog' と 'doge' を同時に保存できるようにしたいので、単純に終端器号(16)をアルファベットに追加する、そうすることで決してある値が別の値に"立ち寄る"ことがない。 ノードがノード内で参照される場合、もしlen(x) >= 32なら、H(rlp.encode(x)) ここで、H(x) = sha3(x) 、さもなければ xが含まれる 、そしてrlp.encode は [RLP](https://github.com/ethereum/wiki/wiki/%5BJapanese%5D-RLP) エンコード関数である。trieを更新する際,長さ>=32のノードを作成する際、永続的なルックアップテーブルにキー/値のペア (sha3(x), x) を保存せねばならない、しかし、もしノードがそれより短ければ、関数f(x) = xが可逆であるという明らかな理由により、何も保存する必要はない。 - -ここで、2項目配列 `[ key, v ]`, `v` は、値またはサブノードでありうる、を考える。 -* もし `v` が値なら、キーは終端を**含む**ニブルのリストの compact encodingの結果でなければならない。 -* もし `v` がサブノードなら、キーは終端を**含まない**ニブルのリストの compact encodingの結果でなければならない。 - -17項目配列` [ v0 ... v15, vt ]`では, `v0...v15`のそれぞれのアイテムは常にサブノードまたはブランクであり, vtは、常に値かブランクである。故に、`v0...v15`の1アイテムに値を記録する代わりに、(キー、値)のサブノードを保存する、ここでキーは、終端を**含んだ**空のニブルのリストをcompact encodingした結果である。 - -これが、 Merkle Patricia tree中のノードを取得するための、拡張したコードである: - - def get_helper(node,key): - if key == []: return node - if node = '': return '' - curnode = rlp.decode(node if len(node) < 32 else db.get(node)) - if len(curnode) == 2: - (k2, v2) = curnode - k2 = compact_decode(k2) - if k2 == key[:len(k2)]: - return get(v2, key[len(k2):]) - else: - return '' - elif len(curnode) == 17: - return get_helper(curnode[key[0]],key[1:]) - - def get(node,key): - key2 = [] - for i in range(len(key)): - key2.push(int(ord(key) / 16)) - key2.push(ord(key) % 16) - key2.push(16) - return get_helper(node,key2) - -例: ペア('dog', 'puppy'), ('horse', 'stallion'), ('do', 'verb'), ('doge', 'coin')を含むtreeを持つことを想定する。まず、キーを16進形式へ変換する: - - [ 6, 4, 6, 15, 16 ] : 'verb' - [ 6, 4, 6, 15, 6, 7, 16 ] : 'puppy' - [ 6, 4, 6, 15, 6, 7, 6, 5, 16 ] : 'coin' - [ 6, 8, 6, 15, 7, 2, 7, 3, 6, 5, 16 ] : 'stallion' - -そして、treeを構築する: - - ROOT: [ '\x16', A ] - A: [ '', '', '', '', B, '', '', '', C, '', '', '', '', '', '', '', '' ] - B: [ '\x00\x6f', D ] - D: [ '', '', '', '', '', '', E, '', '', '', '', '', '', '', '', '', 'verb' ] - E: [ '\x17', F ] - F: [ '', '', '', '', '', '', G, '', '', '', '', '', '', '', '', '', 'puppy' ] - G: [ '\x35', 'coin' ] - C: [ '\x20\x6f\x72\x73\x65', 'stallion' ] diff --git a/pages/patricia-tree/[romanian]-patricia-tree.md b/pages/patricia-tree/[romanian]-patricia-tree.md deleted file mode 100644 index ce5bfdc45..000000000 --- a/pages/patricia-tree/[romanian]-patricia-tree.md +++ /dev/null @@ -1,137 +0,0 @@ ---- -name: Patricia Tree -category: ---- - -###Specificatiile Arborelui Merkle Patricia - -Arborele Merkle Patricia furnizeaza o structura autentificata cryptografic de date care poate fi folosita pentru stocarea tuturor legaturilor (key, valori), desi pentru scopul acestui document restrictionam valorile si keys la siruri (pentru a inlatura aceasta restrictie, folositi orice format de serializare pentru alte tipuri de date). Ele sunt complet deterministe, insemnand ca un arbore Patricia cu aceeasi legatura (valoare, key) va fi exact la fel pana la ultimul byte si astfel va avea aceeasi radacina hash, va furniza the holy grail al eficientei O(log(n)) pentru insertii, cautari si stergeri, si sunt mult mai usor de inteles si de codat decat alte alternative mai complexe bazate pe comparatii cum ar fi arborii rosu-negru. - -###PREAMBUL : Arborii Radix de baza - -Intr-un arbore de baza radix, fiecare nod arata astfel: - - [ value, i0, i1 ... in] - -Unde i0… in reprezentarea valorii simbolurilor alfabetului (deseori binare sau hex) este valoarea terminala a nodului, si valorile din i0… in sloturi sunt fie NULL fie indicatoare (in cazul nostr hash-uri) pentru alte noduri. Aceasta formeaza un stoc de baza (key, valoare), de exemplu, daca esti interesat de valoarea din arbore a obiectului “dog”, intai va trebui efectuata convertirea in alfabet ( rezultand 646f67 daca folosim hex), iar apoi de coboara pe traiectoria arborelui pana la sfarsitul ei, unde se poate citi valoarea. Adica, intai se cauta hash-ul radacina in stocarea key/value pentru a ajunge la nodul radacina, dupa care se cauta nodul 6 al nodului radacina, pentru a cobori acel nod cu un nivel, apoi se cauta nodul 4 al acestui rezultat, urmand nodul 6, si tot asa, mergand pe urmatoarul traseu root ->6->4->6->f->6->7, iar la sfarsit se cauta valoarea nodului obtinut si se returneaza rezultatul. - -Update-urile si operatiile de stergere pentru arborele radix sunt simple, si pot fi definite mai pe scurt dupa cum urmeaza: - -``` -def update(node,key,value): - if key == '': - curnode = db.get(node) if node else [ NULL ] * 17 - newnode = curnode.copy() - newnode['value'] = value - else: - curnode = db.get(node) if node else [ NULL ] * 17 - newnode = curnode.copy() - newindex = update(curnode[key[0]],key[1:],value) - newnode[key[0]] = newindex - db.put(hash(newnode),newnode) - return hash(newnode) - -def delete(node,key): - if key == '' or node is NULL: - return NULL - else: - curnode = db.get(node) - newnode = curnode.copy() - newindex = delete(curnode[key[0]],key[1:]) - newnode[key[0]] = newindex - if len(filter(x -> x is not NULL, newnode)) == 0: - return NULL - else: - db.put(hash(newnode),newnode) - return hash(newnode) -``` - -Partea “Merkle” din arborele radix provine din faptul ca hash-ul cryptografic deterministic al unui nod este utilizat ca indicator spre nod, si nu dintr-o locatie de memorie 32-bit sau 64-bit cum s-ar putea intampla intr-un arbore mai traditional implementat in C. Acesta furnizeaza o forma de autentificare cryptografica la structura datelor. Daca radacina hash a unui trie este cunoscuta public, atunci oricine poate furniza o dovada a unei (key/valori) perechi care nu exista din moment ce hash-ul radacina este bazat pe toate hash-urile de sub el, deci orice modificari ar schimba radacina hash. - -Cu toate acestea, arborii radix au o limitare majora: ineficienta. In cazul in care se doreste stocarea doar unei legaturi (key/valoare) unde key are o lungime de cateva sute de caractere, va fi necesar un KB de spatiu extra pentru a stoca cate un pivel per caracter, iar fiecare cautare sau stergere va insemna sute de pasi. Arborele Patricia rezolva aceasta problema. - -###Specificatie: Codarea compacta a secventei hex cu terminator optional - -Modul compact traditional de a coda un sir hex este de a-l converti in binar , adica un sir ca 0f1248 ar deveni 3 bytes 15,18,72. Cu toate acestea, aceasta abordare are o mica problema: daca lungimea sirului este impara? In acest caz, nu exista nici o modalitate de a distinge sirurile 0f1248 si f1248. In plus, aplicatia noastra in Arborele Merkle Patricia necesita trasatura aditionala cu care un sir hex poate avea un “simbol special terminator” la sfarsit (denotat de ‘T’). Un simbol terminator poate aparea o singura data, si doar la sfarsitul unui sir. Un mod alternativ de a privi lucrurile ar fi sa nu ne gandim la existenta unui simbol terminator, ""but instead treat bit specifying the existence of the terminator symbol as a bit specifying that the given node encodes a final node, where the value is an actual value, rather than the hash of yet another node."" - -Pentru a rezolva ambele probleme, fortam primul nibble al bytestreamului final pentru a coda doua flags, specificand ca lungimea e impara (ignorand simbolul T) si statusul terminator, acestea sunt plasate, respectiv, in cei mai de jos doi biti ai primului nibble.In eventualitatea in care un sir hex este par, trebuie introdus un al doile nibble (cu valoarea zero) pentru a asigura ca sirul hex este par in lungime si astfel este reprezentabil prin un numar intreg de bytes. Astfel putem construi urmatoarea codare: - -``` -def compact_encode(hexarray): - term = 1 if hexarray[-1] == 16 else 0 - if term: hexarray = hexarray[:-1] - oddlen = len(hexarray) % 2 - flags = 2 * term + oddlen - if oddlen: - hexarray = [flags] + hexarray - else: - hexarray = [flags] + [0] + hexarray - // hexarray now has an even length whose first nibble is the flags. - o = '' - for i in range(0,len(hexarray),2): - o += chr(16 * hexarray[i] + hexarray[i+1]) - return o -``` -Exemple: -``` -> [ 1, 2, 3, 4, 5 ] -'\x11\x23\x45' -> [ 0, 1, 2, 3, 4, 5 ] -'\x00\x01\x23\x45' -> [ 0, 15, 1, 12, 11, 8, T ] -'\x20\x0f\x1c\xb8' -> [ 15, 1, 12, 11, 8, T ] -'\x3f\x1c\xb8' -``` -###Principalele specificatii: Arborele Merkle Patricia - -Arborele Merkle Patricia rezolva problemele prezentate mai sus prin adaugarea unei extra complexitati structurii datelor. Un nod intr-un arbore Merkle Patricia este unul dintre urmatoarele: - -1. NULL (reprezentat ca un sir gol) -2. O multime cu doua elemente [key.valoare] -3. O multime de 17 elemente [v0…v15, vt] - -Ideea este aceea ca in eventualitatea in care exista o ruta lunga de noduri fiecare cu un singur element, facem un shortcut la un descent prin setarea unui nod [key/valoare], unde key coboara traiectoria hexadecimala, in codarea compacta descrisa mai sus, si valoarea este doar hash-ul nodului, la fel ca in arborele radix standard. Deasemenea, mai adaugam o schimbare conceptuala: nodurile interne nu mai au valori, only leaves with no children of their own can, cu toate acestea, pentru a fi generici vrem ca stocarea valoarea/key sa poata stoca keys cum ar fi “dog”, “doge” in acelasi timp, doar adaugam un simbol terminator (16) la alfabet astfel incat sa nu existe niciodata o valoare “en-route” pentru o alta valoare. Unde un nod are o referinta in alt nod, care este inclus H(rlp.encode(x)) unde H(x) = sha3(x) if len(x) >= 32 altfel x si codarea rlp este functia codarii RLP. Retineti ca in momentul updatarii unui trie, va trebui stocata perechea key/valoare (sha3(x), x) intr-un tabel de cautare persistenta cand se creeaza un nod cu lungimea >=32, dar daca nodul este mai scurt de atat nu este necesara cand lungimea <32 pentru ca functia f(x)=x este reversibila. - -Mai jos este codul extins pentru a obtine un nod intr-un arbore Merkle Patricia: -def get_helper(node,key): -``` - if key == []: return node - if node = '': return '' - curnode = rlp.decode(node if len(node) < 32 else db.get(node)) - if len(curnode) == 2: - (k2, v2) = curnode - k2 = compact_decode(k2) - if k2 == key[:len(k2)]: - return get(v2, key[len(k2):]) - else: - return '' - elif len(curnode) == 17: - return get_helper(curnode[key[0]],key[1:]) - -def get(node,key): - key2 = [] - for i in range(len(key)): - key2.push(int(ord(key) / 16)) - key2.push(ord(key) % 16) - key2.push(16) - return get_helper(node,key2) -``` -Exemplu: presupunem ca avem un arbore care contine perechile ('dog', 'puppy'), ('horse', 'stallion'), ('do', 'verb'), ('doge', 'coin'). In primul rand convertim keys in format hex: -``` -[ 6, 4, 6, 15, 16 ] : 'verb' -[ 6, 4, 6, 15, 6, 7, 16 ] : 'puppy' -[ 6, 4, 6, 15, 6, 7, 6, 5, 16 ] : 'coin' -[ 6, 8, 6, 15, 7, 2, 7, 3, 6, 5, 16 ] : 'stallion' -``` -Acum alcatuim arborele: -``` -ROOT: [ '\x16', A ] -A: [ '', '', '', '', B, '', '', '', C, '', '', '', '', '', '', '', '' ] -B: [ '\x00\x6f', D ] -D: [ '', '', '', '', '', '', E, '', '', '', '', '', '', '', '', '', 'verb' ] -E: [ '\x17', F ] -F: [ '', '', '', '', '', '', G, '', '', '', '', '', '', '', '', '', 'puppy' ] -G: [ '\x35', 'coin' ] -C: [ '\x20\x6f\x72\x73\x65', 'stallion' ] -``` \ No newline at end of file diff --git a/pages/rlp/[chinese]-rlp.md b/pages/rlp/[chinese]-rlp.md deleted file mode 100644 index 6bbb33f4f..000000000 --- a/pages/rlp/[chinese]-rlp.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -name: RLP -category: ---- - -RLP (递归长度前缀)提供了一种适用于任意二进制数据数组的编码,RLP已经成为以太坊中对对象进行序列化的主要编码方式。 RLP的唯一目标就是解决结构体的编码问题;对原子数据类型(比如,字符串,整数型,浮点型)的编码则交给更高层的协议;以太坊中要求数字必须是一个大端字节序的、没有零占位的存储的格式(也就是说,一个整数0和一个空数组是等同的)。 - -对于在 RLP 格式中对一个字典数据的编码问题,有两种建议的方式,一种是通过二维数组表达键值对,比如`[[k1,v1],[k2,v2]...]`,并且对键进行字典序排序;另一种方式是通过以太坊文档中提到的高级的[基数树](https://github.com/ethereum/wiki/wiki/Patricia-Tree) 编码来实现。 - -### 定义 - -RLP 编码函数接受一个item。定义如下: - -* 将一个字符串作为一个item(比如,一个 byte 数组) -* 一组item列表(list)作为一个item - -例如,一个空字符串可以是一个item,一个字符串"cat"也可以是一个item,一个含有多个字符串的列表也行,复杂的数据结构也行,比如这样的`["cat",["puppy","cow"],"horse",[[]],"pig",[""],"sheep"]`。注意在本文后续内容中,说"字符串"的意思其实就相当于"一个确定长度的二进制字节信息数据";而不要假设或考虑关于字符的编码问题。 - -RLP 编码定义如下: - -* 对于 `[0x00, 0x7f]` 范围内的单个字节, RLP 编码内容就是字节内容本身。 -* 否则,如果是一个 0-55 字节长的字符串,则RLP编码有一个特别的数值 **0x80** 加上字符串长度,再加上字符串二进制内容。这样,第一个字节的表达范围为 `[0x80, 0xb7]`. -* 如果字符串长度超过 55 个字节,RLP 编码由定值 **0xb7** 加上字符串长度的长度,加上字符串长度长度,加上字符串二进制内容组成。比如,一个长度为 1024 的字符串,将被编码为`\xb9\x04\x00` 后面再加上字符串内容。第一字节的表达范围是`[0xb8, 0xbf]`。 -* 如果列表的内容(它的所有项的组合长度)是0-55个字节长,它的RLP编码由0xC0加上所有的项的RLP编码串联起来的长度得到的单个字节,后跟所有的项的RLP编码的串联组成。 第一字节的范围因此是[0xc0, 0xf7] -* 如果列表的内容超过55字节,它的RLP编码由0xC0加上所有的项的RLP编码串联起来的长度的长度得到的单个字节,后跟所有的项的RLP编码串联起来的长度的长度,再后跟所有的项的RLP编码的串联组成。 第一字节的范围因此是[0xf8, 0xff] 。 - -用Python代码表达以上逻辑: - -```python -def rlp_encode(input): - if isinstance(input,str): - if len(input) == 1 and chr(input) < 128: return input - else: return encode_length(len(input),128) + input - elif isinstance(input,list): - output = '' - for item in input: output += rlp_encode(item) - return encode_length(len(output),192) + output - -def encode_length(L,offset): - if L < 56: - return chr(L + offset) - elif L < 256**8: - BL = to_binary(L) - return chr(len(BL) + offset + 55) + BL - else: - raise Exception("input too long") - -def to_binary(x): - return '' if x == 0 else to_binary(int(x / 256)) + chr(x % 256) -``` - -### 例子 - -字符串 "dog" = [ 0x83, 'd', 'o', 'g' ] - -列表 [ "cat", "dog" ] = `[ 0xc8, 0x83, 'c', 'a', 't', 0x83, 'd', 'o', 'g' ]` - -空字符串 ('null') = `[ 0x80 ]` - -空列表 = `[ 0xc0 ]` - -数字15 ('\x0f') = `[ 0x0f ]` - -数字 1024 ('\x04\x00') = `[ 0x82, 0x04, 0x00 ]` - -The [set theoretical representation](http://en.wikipedia.org/wiki/Set-theoretic_definition_of_natural_numbers) of two, `[ [], [[]], [ [], [[]] ] ] = [ 0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc1, 0xc0 ]` - -字符串 "Lorem ipsum dolor sit amet, consectetur adipisicing elit" = `[ 0xb8, 0x38, 'L', 'o', 'r', 'e', 'm', ' ', ... , 'e', 'l', 'i', 't' ]` diff --git a/pages/rlp/[english]-rlp.md b/pages/rlp/[english]-rlp.md deleted file mode 100644 index 4575949f8..000000000 --- a/pages/rlp/[english]-rlp.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -name: RLP -category: ---- - -The purpose of RLP (Recursive Length Prefix) is to encode arbitrarily nested arrays of binary data, and RLP is the main encoding method used to serialize objects in Ethereum. The only purpose of RLP is to encode structure; encoding specific atomic data types (eg. strings, ints, floats) is left up to higher-order protocols; in Ethereum integers must be represented in big endian binary form with no leading zeroes (thus making the integer value zero be equivalent to the empty byte array). - -If one wishes to use RLP to encode a dictionary, the two suggested canonical forms are to either use `[[k1,v1],[k2,v2]...]` with keys in lexicographic order or to use the higher-level [Patricia Tree](https://github.com/ethereum/wiki/wiki/Patricia-Tree) encoding as Ethereum does. - -### Definition - -The RLP encoding function takes in an item. An item is defined as follows: - -* A string (ie. byte array) is an item -* A list of items is an item - -For example, an empty string is an item, as is the string containing the word "cat", a list containing any number of strings, as well as more complex data structures like `["cat",["puppy","cow"],"horse",[[]],"pig",[""],"sheep"]`. Note that in the context of the rest of this article, "string" will be used as a synonym for "a certain number of bytes of binary data"; no special encodings are used and no knowledge about the content of the strings is implied. - -RLP encoding is defined as follows: - -* For a single byte whose value is in the `[0x00, 0x7f]` range, that byte is its own RLP encoding. -* Otherwise, if a string is 0-55 bytes long, the RLP encoding consists of a single byte with value **0x80** plus the length of the string followed by the string. The range of the first byte is thus `[0x80, 0xb7]`. -* If a string is more than 55 bytes long, the RLP encoding consists of a single byte with value **0xb7** plus the length of the length of the string in binary form, followed by the length of the string, followed by the string. For example, a length-1024 string would be encoded as `\xb9\x04\x00` followed by the string. The range of the first byte is thus `[0xb8, 0xbf]`. -* If the total payload of a list (i.e. the combined length of all its items) is 0-55 bytes long, the RLP encoding consists of a single byte with value **0xc0** plus the length of the list followed by the concatenation of the RLP encodings of the items. The range of the first byte is thus `[0xc0, 0xf7]`. -* If the total payload of a list is more than 55 bytes long, the RLP encoding consists of a single byte with value **0xf7** plus the length of the length of the payload in binary form, followed by the length of the payload, followed by the concatenation of the RLP encodings of the items. The range of the first byte is thus `[0xf8, 0xff]`. - -In code, this is: - -```python -def rlp_encode(input): - if isinstance(input,str): - if len(input) == 1 and chr(input) < 128: return input - else: return encode_length(len(input),128) + input - elif isinstance(input,list): - output = '' - for item in input: output += rlp_encode(item) - return encode_length(len(output),192) + output - -def encode_length(L,offset): - if L < 56: - return chr(L + offset) - elif L < 256**8: - BL = to_binary(L) - return chr(len(BL) + offset + 55) + BL - else: - raise Exception("input too long") - -def to_binary(x): - return '' if x == 0 else to_binary(int(x / 256)) + chr(x % 256) -``` - -### Examples - -The string "dog" = [ 0x83, 'd', 'o', 'g' ] - -The list [ "cat", "dog" ] = `[ 0xc8, 0x83, 'c', 'a', 't', 0x83, 'd', 'o', 'g' ]` - -The empty string ('null') = `[ 0x80 ]` - -The empty list = `[ 0xc0 ]` - -The encoded integer 15 ('\x0f') = `[ 0x0f ]` - -The encoded integer 1024 ('\x04\x00') = `[ 0x82, 0x04, 0x00 ]` - -The [set theoretical representation](http://en.wikipedia.org/wiki/Set-theoretic_definition_of_natural_numbers) of two, `[ [], [[]], [ [], [[]] ] ] = [ 0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc1, 0xc0 ]` - -The string "Lorem ipsum dolor sit amet, consectetur adipisicing elit" = `[ 0xb8, 0x38, 'L', 'o', 'r', 'e', 'm', ' ', ... , 'e', 'l', 'i', 't' ]` diff --git a/pages/rlp/[german]-rlp.md b/pages/rlp/[german]-rlp.md deleted file mode 100644 index fd165990d..000000000 --- a/pages/rlp/[german]-rlp.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -name: RLP -category: ---- - -Der Zweck von RLP ist es, beliebig verschachtelte Arrays von binären Daten zu kodieren. RLP wird als Hauptcodierungsverfahren verwendet, um Objekte in Ethereum in serieller Reihenfolge zu kodieren. Das heisst RLP kodiert Strukturen, spezielle Datentypen wie [Strings] (http://de.wikipedia.org/wiki/Zeichenkette), [Integers] (http://de.wikipedia.org/wiki/Integer_%28Datentyp%29) und [Floats] (http://de.wikipedia.org/wiki/Gleitkommazahl), bis hin zu höheren Protokollebenen. Integer werden in Ethereum standardmäßig im [Big Endian] (http://de.wikipedia.org/wiki/Byte-Reihenfolge) Binärfomat verarbeitet. -Wenn man RLP z.B. zum Kodieren eines Wörterbuchs verwendet, sind die beiden vorgeschalgenen Standardformen entweder `[[k1, v1], [k2, v2] ...]` mit Schlüsselwörtern in lexikographische Ordnung oder besser die Kodierung des [Patricia Baums] (https://github.com/ethereum/wiki/wiki/Patricia-Tree) (wie es Ethereum tut). - -### Definition -Die RLP-Koding erfolgt in einem Element. Ein Element wird wie folgt definiert: - -* Ein String (z.B. eine Byte Array) ist ein Element -* Eine Liste von Elementen ist ein Elemet - -Elemente können z.B. sein: -- ein leerer String -- ein String mit dem Wort "cat" -- eine Liste von beliebig vielen anderen Zeichen -- komplexere Daten wie `["cat",["puppy","cow"],"horse",[[]],"pig",[""],"sheep"]`. - -Bitte beachten: In dem Rest dieses Artikels wird "String" als Synonym für "eine bestimmte Anzahl von Bytes von binären Daten" verwendet. Es wird keine besondere Kodierung betrachtet und auch nichts über den Inhalt des Strings ausgesagt. - -Die RLP-Kodierung funktioniert wie folgt: -* Für ein einzelnes Byte innerhalb des Bereiches `[0x00, 0x7f]` erfolgt eine individuelle RLP-Kodierung. -* Ist ein String 0 bis 55 Byte lang enthält die RLP-Kodierung den Wert **0x80** + die Länge des Strings, gefolgt vom Stringinhalt. Der Wertebereich des ersten Bytes ist `[0x80, 0xb7]`. -* Ist ein String länger als 55 Byte, enthält die RLP-Kodierung das erste Byte mit dem Wert **0xb7** + die Länge für String+Stringlänge in Binärformat, gefolgt von der Länge des Strings, gefolgt vom Stringinhalt. Z.B. ein 1024 Byte langer String wird kodiert als `\xb9\x04\x00` gefolgt vom Stringinhalt. Der Wertebereich des ersten Bytes ist `[0xb8, 0xbf]`. -* Ist die Gesamtlänge der Nutzdaten einer Liste (z.B. die kombinierte Länge aller Elemente) zwischen 0 und 55 Bytes, enthält die RLP-Kodierung das Byte mit dem Inhalt **0xc0** + die Länge der Liste, gefolgt von der Verkettung der RLP-Kodierungen der Elemente. Der Wertebereich des ersten Bytes ist `[0xc0, 0xf7]`. -* Ist die Gesamtlänge der Nutzdaten einer Liste mehr als 55 Byte, enthält die RLP-Kodierung das Byte mit dem Inhalt **0xf7** + die Länge für Liste+Listenlänge in Binärformat, gefolgt von der Länge der Liste, gefolgt von der Verkettung der RLP-Kodierungen der Elemente. Der Wertebereich des ersten Bytes ist `[0xf8, 0xff]`. -Als Code sieht das so aus: -```python -def rlp_encode(input): - if isinstance(input,str): - if len(input) == 1 and chr(input) < 128: return input - else: return encode_length(len(input),128) + input - elif isinstance(input,list): - output = encode_length(len(input),192) - for item in input: output += rlp_encode(item) - return output -def encode_length(L,offset): - if L < 56: - return chr(L + offset) - elif L < 256**8: - BL = to_binary(L) - return chr(len(BL) + offset + 55) + BL - else: - raise Exception("input too long") -def to_binary(x): - return '' if x == 0 else to_binary(int(x / 256)) + chr(x % 256) -``` -### Beispiele - -Der String "dog" = [ 0x83, 'd', 'o', 'g' ] - -Die Liste [ "cat", "dog" ] = `[ 0xc8, 0x83, 'c', 'a', 't', 0x83, 'd', 'o', 'g' ]` - -Der leere String ('null') = `[ 0x80 ]` - -Die leere Liste = `[ 0xc0 ]` - -Der Integer 15 = `[ 0x0f ]` - -Der Integer 1024 = `[ 0x82, 0x04, 0x00 ]` - -Die [mengentheoretischen Darstellung] (http://en.wikipedia.org/wiki/Set-theoretic_definition_of_natural_numbers) von zwei, `[ [], [[]], [ [], [[]] ] ] = [ 0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc1, 0xc0 ]` - -Der String "Lorem ipsum dolor sit amet, consectetur adipisicing elit" = `[ 0xb8, 0x38, 'L', 'o', 'r', 'e', 'm', ' ', ... , 'e', 'l', 'i', 't' ]` diff --git a/pages/rlp/[japanese]-rlp.md b/pages/rlp/[japanese]-rlp.md deleted file mode 100644 index c5bc9f400..000000000 --- a/pages/rlp/[japanese]-rlp.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -name: RLP -category: ---- - -RLPの目的は任意のネストされたバイナリデータをエンコードすることです。RLPはEthereumにおいてシリアライズされたオブジェクトをエンコードするメインの方法です。RLPの目的は構造をエンコードすることです:特殊なアトミックなデータ型(例えば文字列型、整数型、浮動小数点型)のエンコードはもっと上位のプロトコルに任せます;Ethereumでは整数型は先頭のゼロが無いビッグエンディアンのバイナリで表されます(よって、整数型のゼロは空のバイトアレイとなります)。 - -もし辞書をエンコードするのにRLPを使いたいと思うならば、二つの正規のフォームが使えます。`[[k1,v1],[k2,v2]...]`のような辞書順にならんだキーを使用する方法と、Ethereumで使用されている上位の[Patricia Tree](https://github.com/ethereum/wiki/wiki/Patricia-Tree)を用いたエンコードを使用する方法です。 - - -### 定義 - -RLPエンコード関数はアイテムを受け入れます。アイテムは以下のように定義されます: - -* 文字列型(すなわちバイトアレイ)はアイテムである -* アイテムのリストはアイテムである - -例えば、空の文字列はアイテムです。同様に "cat"という単語による文字列もアイテムです。任意の個数の文字列型のリストもアイテムです。そして、`["cat",["puppy","cow"],"horse",[[]],"pig",[""],"sheep"]`のようなもっと複雑なデータ構造もアイテムです。この論説の残りの部分の文脈において、"文字列型"は"あるバイト数のバイナリデータ"と同義語であることに注意しましょう; 特殊なエンコードは用いられておらず、文字列型の内容が何を意味しているかの知識は必要ではありません。 - -RLPエンコーディングは以下のように定義されます: - -* `[0x00, 0x7f]`の間にある1バイトの値は、そのバイトがそのまま自分自身のRLPエンコーディングとなります。 -* もし、文字列が0-55バイトの長さの場合は、RLPエンコーディングは**0x80**と文字列の長さを足した1バイトと、その後に続く文字列で構成されます。よって、最初の1バイトは`[0x80, 0xb7]`の範囲となります。 -* もし文字列が55バイトより長い場合、RLPエンコーディングは以下の3つで構成されます。文字列の長さをバイナリで表した時に必要となるバイト数を**0xb7**に足した値の1バイト。続けて、文字列の長さ、それに続く文字列です。例えば1024の長さを持つ文字列の場合、`\xb9\x04\x00`と、その後に続く文字列にエンコードされます。よって、最初の1バイトは`[0xb8, 0xbf]`の範囲となります。 -* もし、リストの全ペイロード(すなわち、全てのアイテムを合わせた長さ)が0-55バイトの長さである場合、RLPエンコーディングは、**0xc0**にリストの長さを足した1倍との値と、それに続くアイテムをRLPエンコーディングして続けたもので構成されます。よって、最初の1バイトの範囲は`[0xc0, 0xf7]`となります。 -* もし、リストの全ペイロードの長さが55バイト以上の場合、RLPエンコーディングは以下の構成になります。最初に **0xf7** にペイロードの長さをバイナリで表した時に必要となるバイト数を足した1バイト。続けて、ペイロードの長さ。最後にアイテムをRLPエンコーディングした物を続けたものとなります。よって、最初の1バイトの範囲は`[0xf8, 0xff]`となります。 - - -コードで表すと以下のようになります: - -```python -def rlp_encode(input): - if isinstance(input,str): - if len(input) == 1 and chr(input) < 128: return input - else: return encode_length(len(input),128) + input - elif isinstance(input,list): - output = '' - for item in input: output += rlp_encode(item) - return encode_length(len(output),192) + output - -def encode_length(L,offset): - if L < 56: - return chr(L + offset) - elif L < 256**8: - BL = to_binary(L) - return chr(len(BL) + offset + 55) + BL - else: - raise Exception("input too long") - -def to_binary(x): - return '' if x == 0 else to_binary(int(x / 256)) + chr(x % 256) -``` - -### 例 - -文字列 "dog" = [ 0x83, 'd', 'o', 'g' ] - -リスト [ "cat", "dog" ] = `[ 0xc8, 0x83, 'c', 'a', 't', 0x83, 'd', 'o', 'g' ]` - -空文字列 ('null') = `[ 0x80 ]` - -空リスト = `[ 0xc0 ]` - -整数 15 ('\x0f') のエンコード = `[ 0x0f ]` - -整数 1024 ('\x04\x00') のエンコード = `[ 0x82, 0x04, 0x00 ]` - -[ 集合論的表現 ](http://en.wikipedia.org/wiki/Set-theoretic_definition_of_natural_numbers) `[ [], [[]], [ [], [[]] ] ] = [ 0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc1, 0xc0 ]` - -文字列 "Lorem ipsum dolor sit amet, consectetur adipisicing elit" = `[ 0xb8, 0x38, 'L', 'o', 'r', 'e', 'm', ' ', ... , 'e', 'l', 'i', 't' ]` \ No newline at end of file diff --git a/pages/rlp/[romanian]-rlp.md b/pages/rlp/[romanian]-rlp.md deleted file mode 100644 index 38b38565c..000000000 --- a/pages/rlp/[romanian]-rlp.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -name: RLP -category: ---- - -Scopul RLP este acela de a coda matrici grupate arbitrar de date binare, si RLP este principala metoda folosita pentru a serializa obiecte in Ethereum. Singurul scop al RLP este acela de a coda structuri, codarea unor tipuri specifice de date atomice (strings, ints, float) sunt lasate pentru alte protocoale de ordin superior; in Ethereum standardul este reprezentarea numerelor intregi in forma endiana binara. Daca cineva doreste sa utilizeze RLP pentru a coda un dictionar, cele doua forme canonice sugerate vor folosi `[[k1,v1],[k2,v2]...]` keys in ordine lexicografica sau vor folosi codarea Patricia Tree, ca la Ethereum. - -###Definitie - -Functia de encodare RLP preia un element. Un element este definit dupa cum urmeaza: -- Un sir (ex. o matrice octet) este un element -- O lista de elemente este un element -De exemplu, un sir gol este un element, cum este sirul care conține cuvantul "pisica", o lista ce contine orice numar de siruri, ca si structuri de date mai complexe precum` ["pisica",["catelus","vaca"],"cal",[[]],"porc",[""],"oaie"]`. Retineti ca in contextul acestui articol, “sir” va fi folosit ca un sinonim pentru “un anumit numar de bytes de date binare”, nu sunt folosite codari speciale si nu implica resurse legate de continutul sirurilor. -Codarea RLP este definita dupa cum urmeaza: --Pentru un singur byte a carui valoare se incadreaza in `[0x00, 0x7f]` , acel byte este propria sa codare RLP. --Altfel, daca un sir are o lungime de 0-55 bytes, codarea RLP consta intr-un singur byte cu o valoare de 0x80 plus lungimea sirului, urmata de sir. Astfel, primul byte se incadreaza in intervalul `[0x80, 0xb7]`. --Daca un sir este mai lung de 55 bytes, codarea RLP consta intr-un singur byte cu valoarea 0xb7 plus lungimea lungimii sirului in forma binara, urmata de lungimea sirului,urmata de sir. De exemplu, un sir de o lungime 1024 ar fi codat \xb9\x04\x00 , urmat de sir. Intervalul in care se incadreaza primul byte este, deci, `[0xb8, 0xbf]`. - -- Daca sarcina utila a unei liste (payload) (ex. Suma lungimilor elementelor sale) are o lungime de 0-55 bytes, codarea RLP consta intr-un singur byte cu valoarea de 0xc0 plus lungimea listei urmata de concatenarea/juxtapunerea codarii RLP a elementelor. Intervalul in care se incadreaza primul byte este `[0xc0, 0xf7]`. -- Daca sarcina utila a unei liste (payload) este mai mare de 55 bytes, codarea RLP consta intr-un singur byte cu valoarea de 0xf7 plus lungimea lungimii listei in forma binara, urmata de lungimea listei , urmata de concatenarea/juxtapunerea codarii RLP a elementelor. Intervalul in care este plasat primul octet este `[0xf8, 0xff]`. - -Codul, arata astfel: -```python -def rlp_encode(input): - if isinstance(input,str): - if len(input) == 1 and chr(input) < 128: return input - else: return encode_length(len(input),128) + input - elif isinstance(input,list): - output = encode_length(len(input),192) - for item in input: output += rlp_encode(item) - return output - -def encode_length(L,offset): - if L < 56: - return chr(L + offset) - elif L < 256**8: - BL = to_binary(L) - return chr(len(BL) + offset + 55) + BL - else: - raise Exception("input too long") - -def to_binary(x): - return '' if x == 0 else to_binary(int(x / 256)) + chr(x % 256) -``` - -###Exemple: - -Sirul “dog”= `[ 0x83, 'd', 'o', 'g' ]` - -Lista [ "cat", "dog" ] = `[ 0xc8, 0x83, 'c', 'a', 't', 0x83, 'd', 'o', 'g' ]` - -Sirul gol ('null') = `[ 0x80 ]` - -Lista goala =`[ 0xc0 ]` - -Numarul intreg 15= `[ 0x0f ]` - -Numarul intreg 1024 =`[ 0x82, 0x04, 0x00 ]` - -Reprezentarea teoretica a setului de 2 , [ [], [[]], [ [], [[]] ] ] = `[ 0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc1, 0xc0 ]` - -Sirul "Lorem ipsum dolor sit amet, consectetur adipisicing elit" = `[ 0xb8, 0x38, 'L', 'o', 'r', 'e', 'm', ' ', ... , 'e', 'l', 'i', 't' ]` diff --git a/pages/white-paper/[chinese]-white-paper.md b/pages/white-paper/[chinese]-white-paper.md deleted file mode 100644 index 1456f5b13..000000000 --- a/pages/white-paper/[chinese]-white-paper.md +++ /dev/null @@ -1,477 +0,0 @@ ---- -name: White Paper -category: ---- - -### 以太坊(Ethereum ):下一代智能合约和去中心化应用平台 - -翻译:巨蟹 、少平 - -译者注:中文读者可以到以太坊爱好者网站(www.ethfans.org)和论坛(www.bbs.ethfans.org)获取最新的以太坊信息。 - -当中本聪在2009年1月启动比特币区块链时,他同时向世界引入了两种未经测试的革命性的新概念。第一种就是比特币(bitcoin),一种去中心化的点对点的网上货币,在没有任何资产担保、内在价值或者中心发行者的情况下维持着价值。到目前为止,比特币已经吸引了大量的公众注意力, 就政治方面而言它是一种没有中央银行的货币并且有着剧烈的价格波动。然而,中本聪的伟大试验还有与比特币同等重要的一部分:基于工作量证明的区块链概念使得人们可以就交易顺序达成共识。作为应用的比特币可以被描述为一个先申请(first-to-file)系统:如果某人有50BTC并且同时向A和B发送这50BTC,只有被首先被确认的交易才会生效。没有固有方法可以决定两笔交易哪一笔先到,这个问题阻碍了去中心化数字货币的发展许多年。中本聪的区块链是第一个可靠的去中心化解决办法。现在,开发者们的注意力开始迅速地转向比特币技术的第二部分,区块链怎样应用于货币以外的领域。 - -常被提及的应用包括使用链上数字资产来代表定制货币和金融工具(彩色币),某种基础物理设备的所有权(智能资产),如域名一样的没有可替代性的资产(域名币)以及如去中心化交易所,金融衍生品,点到点赌博和链上身份和信誉系统等更高级的应用。另一个常被问询的重要领域是“智能合约”- 根据事先任意制订的规则来自动转移数字资产的系统。例如,一个人可能有一个存储合约,形式为“A可以每天最多提现X个币,B每天最多Y个,A和B一起可以随意提取,A可以停掉B的提现权”。这种合约的符合逻辑的扩展就是去中心化自治组织(DAOs)-长期的包含一个组织的资产并把组织的规则编码的智能合约。以太坊的目标就是提供一个带有内置的成熟的图灵完备语言的区块链,用这种语言可以创建合约来编码任意状态转换功能,用户只要简单地用几行代码来实现逻辑,就能够创建以上提及的所有系统以及许多我们还想象不到的的其它系统。 - -### 目录 - -* 历史 - * 作为状态转换系统的比特币 - * 挖矿 - * 默克尔树 - * 替代区块链应用 - * 脚本 -* 以太坊 - * 以太坊账户 - * 消息和交易 - * 以太坊状态转换功能 - * 代码执行 - * 区块链和挖矿 -* 应用 - * 令牌系统 - * 金融衍生品 - * 身份和信誉系统 - * 去中心化文件存储 - * 去中心化自治组织 - * 进一步的应用 -* 杂项和关注 - * 改进版幽灵协议的实施 - * 费用 - * 计算和图灵完备 - * 货币和发行 - * 挖矿的中心化 - * 扩展性 -* 综述:去中心化应用 -* 结论 - * 注解和进阶阅读 - -### 历史 - -去中心化的数字货币概念,正如财产登记这样的替代应用一样,早在几十年以前就被提出来了。1980和1990年代的匿名电子现金协议,大部分是以乔姆盲签技术(Chaumian blinding)为基础的。这些电子现金协议提供具有高度隐私性的货币,但是这些协议都没有流行起来,因为它们都依赖于一个中心化的中介机构。1998年,戴伟(Wei Dai)的b-money首次引入了通过解决计算难题和去中心化共识创造货币的思想,但是该建议并未给出如何实现去中心化共识的具体方法。2005年,芬尼(Hal Finney)引入了“可重复使用的工作量证明机制”(reusable proofs of work)概念,它同时使用b-money的思想和Adam Back提出的计算困难的哈希现金(Hashcash)难题来创造密码学货币。但是,这种概念再次迷失于理想化,因为它依赖于可信任的计算作为后端。 - -因为货币是一个先申请应用,交易的顺序至关重要,所以去中心化的货币需要找到实现去中心化共识的方法。比特币以前的所有电子货币协议所遇到的主要障碍是,尽管对如何创建安全的拜占庭问题容错(Byzantine-fault-tolerant)多方共识系统的研究已经历时多年,但是上述协议只解决了问题的一半。这些协议假设系统的所有参与者是已知的,并产生如“如果有N方参与到系统中,那么系统可以容忍N/4的恶意参与者”这样形式的安全边界。然而这个假设的问题在于,在匿名的情况下,系统设置的安全边界容易遭受女巫攻击,因为一个攻击者可以在一台服务器或者僵尸网络上创建数以千计的节点,从而单方面确保拥有多数份额。 - -中本聪的创新是引入这样一个理念:将一个非常简单的基于节点的去中心化共识协议与工作量证明机制结合在一起。节点通过工作量证明机制获得参与到系统的权利,每十分钟将交易打包到“区块”中,从而创建出不断增长的区块链。拥有大量算力的节点有更大的影响力,但获得比整个网络更多的算力比创建一百万个节点困难得多。尽管比特币区块链模型非常简陋,但是实践证明它已经足够好用了,在未来五年,它将成为全世界两百个以上的货币和协议的基石。 - -### 作为状态转换系统的比特币 - -![](https://camo.githubusercontent.com/e7a1fc59abdd42654fa8c54c0f847eb2c8fda72e/687474703a2f2f766974616c696b2e63612f66696c65732f73746174657472616e736974696f6e2e706e673f32) - -从技术角度讲,比特币账本可以被认为是一个状态转换系统,该系统包括所有现存的比特币所有权状态和“状态转换函数”。状态转换函数以当前状态和交易为输入,输出新的状态。例如,在标准的银行系统中,状态就是一个资产负债表,一个从A账户向B账户转账X美元的请求是一笔交易,状态转换函数将从A账户中减去X美元,向B账户增加X美元。如果A账户的余额小于X美元,状态转换函数就会返回错误提示。所以我们可以如下定义状态转换函数: - - APPLY(S,TX) ­> S' or ERROR - -在上面提到的银行系统中,状态转换函数如下: - - APPLY({ Alice: $50, Bob: $50 },"send $20 from Alice to Bob") = { Alice: $30,Bob: $70 } - -但是: - - APPLY({ Alice: $50, Bob: $50 },"send $70 from Alice to Bob") = ERROR - -比特币系统的“状态”是所有已经被挖出的、没有花费的比特币(技术上称为“未花费的交易输出,unspent transaction outputs 或UTXO”)的集合。每个UTXO都有一个面值和所有者(由20个字节的本质上是密码学公钥的地址所定义[1])。一笔交易包括一个或多个输入和一个或多个输出。每个输入包含一个对现有UTXO的引用和由与所有者地址相对应的私钥创建的密码学签名。每个输出包含一个新的加入到状态中的UTXO。 - -在比特币系统中,状态转换函数`APPLY(S,TX)->S’`大体上可以如下定义: - -1. 交易的每个输入: - * 如果引用的UTXO不存在于现在的状态中(`S`),返回错误提示 - * 如果签名与UTXO所有者的签名不一致,返回错误提示 -2. 如果所有的UTXO输入面值总额小于所有的UTXO输出面值总额,返回错误提示 -3. 返回新状态`S’`,新状态`S`中移除了所有的输入UTXO,增加了所有的输出UTXO。 - -第一步的第一部分防止交易的发送者花费不存在的比特币,第二部分防止交易的发送者花费其他人的比特币。第二步确保价值守恒。比特币的支付协议如下。假设Alice想给Bob发送11.7BTC。事实上,Alice不可能正好有11.7BTC。假设,她能得到的最小数额比特币的方式是:6+4+2=12。所以,她可以创建一笔有3个输入,2个输出的交易。第一个输出的面值是11.7BTC,所有者是Bob(Bob的比特币地址),第二个输出的面值是0.3BTC,所有者是Alice自己,也就是找零。 - -### 挖矿 - -![](https://camo.githubusercontent.com/e8e2a0c15c17b066e7f17056f7697819b9a1aa33/687474703a2f2f766974616c696b2e63612f66696c65732f626c6f636b5f706963747572652e706e67) - -如果我们拥有可信任的中心化服务机构,状态转换系统可以很容易地实现,可以简单地将上述功能准确编码。然而,我们想把比特币系统建成为去中心化的货币系统,为了确保每个人都同意交易的顺序,我们需要将状态转换系统与一个共识系统结合起来。比特币的去中心化共识进程要求网络中的节点不断尝试将交易打包成“区块”。网络被设计为大约每十分钟产生一个区块,每个区块包含一个时间戳、一个随机数、一个对上一个区块的引用(即哈希)和上一区块生成以来发生的所有交易列表。这样随着时间流逝就创建出了一个持续增长的区块链,它不断地更新,从而能够代表比特币账本的最新状态。 - -依照这个范式,检查一个区块是否有效的算法如下: - -1. 检查区块引用的上一个区块是否存在且有效。 -2. 检查区块的时间戳是否晚于以前的区块的时间戳,而且早于未来2小时[2]。 -3. 检查区块的工作量证明是否有效。 -4. 将上一个区块的最终状态赋于`S[0]`。 -5. 假设TX是区块的交易列表,包含n笔交易。对于属于0……n-1的所有i,进行状态转换`S[i+1] = APPLY(S[i],TX[i])`。如果任何一笔交易i在状态转换中出错,退出程序,返回错误。 -6. 返回正确,状态`S[n]`是这一区块的最终状态。 - -本质上,区块中的每笔交易必须提供一个正确的状态转换,要注意的是,“状态”并不是编码到区块的。它纯粹只是被校验节点记住的抽象概念,对于任意区块都可以从创世状态开始,按顺序加上每一个区块的每一笔交易,(妥妥地)计算出当前的状态。另外,需要注意矿工将交易收录进区块的顺序。如果一个区块中有A、B两笔交易,B花费的是A创建的UTXO,如果A在B以前,这个区块是有效的,否则,这个区块是无效的。 - -区块验证算法的有趣部分是“工作量证明”概念:对每个区块进行SHA256哈希处理,将得到的哈希视为长度为256比特的数值,该数值必须小于不断动态调整的目标数值,本书写作时目标数值大约是2^190。工作量证明的目的是使区块的创建变得困难,从而阻止女巫攻击者恶意重新生成区块链。因为SHA256是完全不可预测的伪随机函数,创建有效区块的唯一方法就是简单地不断试错,不断地增加随机数的数值,查看新的哈希数值是否小于目标数值。如果当前的目标数值是2^192,就意味着平均需要尝试2^64次才能生成有效的区块。一般而言,比特币网络每隔2016个区块重新设定目标数值,保证平均每十分钟生成一个区块。为了对矿工的计算工作进行奖励,每一个成功生成区块的矿工有权在区块中包含一笔凭空发给他们自己25BTC的交易。另外,如果交易的输入大于输出,差额部分就作为“交易费用”付给矿工。顺便提一下,对矿工的奖励是比特币发行的唯一机制,创世状态中并没有比特币。 - -为了更好地理解挖矿的目的,让我们分析比特币网络出现恶意攻击者时会发生什么。因为比特币的密码学基础是非常安全的,所以攻击者会选择攻击没有被密码学直接保护的部分:交易顺序。攻击者的策略非常简单: - -1. 向卖家发送100BTC购买商品(尤其是无需邮寄的电子商品)。 -2. 等待直至商品发出。 -3. 创建另一笔交易,将相同的100BTC发送给自己的账户。 -4. 使比特币网络相信发送给自己账户的交易是最先发出的。 - -一旦步骤(1)发生,几分钟后矿工将把这笔交易打包到区块,假设是第270000个区块。大约一个小时以后,在此区块后面将会有五个区块,每个区块间接地指向这笔交易,从而确认这笔交易。这时卖家收到货款,并向买家发货。因为我们假设这是数字商品,攻击者可以即时收到货。现在,攻击者创建另一笔交易,将相同的100BTC发送到自己的账户。如果攻击者只是向全网广播这一消息,这一笔交易不会被处理。矿工会运行状态转换函数`APPLY(S,TX)`,发现这笔交易将花费已经不在状态中的UTXO。所以,攻击者会对区块链进行分叉,将第269999个区块作为父区块重新生成第270000个区块,在此区块中用新的交易取代旧的交易。因为区块数据是不同的,这要求重新进行工作量证明。另外,因为攻击者生成的新的第270000个区块有不同的哈希,所以原来的第270001到第270005的区块不指向它,因此原有的区块链和攻击者的新区块是完全分离的。在发生区块链分叉时,区块链长的分支被认为是诚实的区块链,合法的的矿工将会沿着原有的第270005区块后挖矿,只有攻击者一人在新的第270000区块后挖矿。攻击者为了使得他的区块链最长,他需要拥有比除了他以外的全网更多的算力来追赶(即51%攻击)。 - -### 默克尔树 - -![](https://camo.githubusercontent.com/52e0d1b4436e61cca69cd3e3e62dda7b9bcb3b54/68747470733a2f2f7777772e657468657265756d2e6f72672f67685f77696b692f7370765f626974636f696e2e706e67) - -左:仅提供默克尔树(Merkle tree)上的少量节点已经足够给出分支的合法证明。 -右:任何对于默克尔树的任何部分进行改变的尝试都会最终导致链上某处的不一致。 - -比特币系统的一个重要的可扩展特性是:它的区块存储在多层次的数据结构中。一个区块的哈希实际上只是区块头的哈希,区块头是包含时间戳、随机数、上个区块哈希和存储了所有的区块交易的默克尔树的根哈希的长度大约为200字节的一段数据。 - -默克尔树是一种二叉树,由一组叶节点、一组中间节点和一个根节点构成。最下面的大量的叶节点包含基础数据,每个中间节点是它的两个子节点的哈希,根节点也是由它的两个子节点的哈希,代表了默克尔树的顶部。默克尔树的目的是允许区块的数据可以零散地传送:节点可以从一个源下载区块头,从另外的源下载与其有关的树的其它部分,而依然能够确认所有的数据都是正确的。之所以如此是因为哈希向上的扩散:如果一个恶意用户尝试在树的下部加入一个伪造的交易,所引起的改动将导致树的上层节点的改动,以及更上层节点的改动,最终导致根节点的改动以及区块哈希的改动,这样协议就会将其记录为一个完全不同的区块(几乎可以肯定是带着不正确的工作量证明的)。 - -默克尔树协议对比特币的长期持续性可以说是至关重要的。在2014年4月,比特币网络中的一个全节点-存储和处理所有区块的全部数据的节点-需要占用15GB的内存空间,而且还以每个月超过1GB的速度增长。目前,这一存储空间对台式计算机来说尚可接受,但是手机已经负载不了如此巨大的数据了。未来只有商业机构和爱好者才会充当完整节点。简化支付确认(SPV)协议允许另一种节点存在,这样的节点被成为“轻节点”,它下载区块头,使用区块头确认工作量证明,然后只下载与其交易相关的默克尔树“分支”。这使得轻节点只要下载整个区块链的一小部分就可以安全地确定任何一笔比特币交易的状态和账户的当前余额。 - -### 其它的区块链应用 - -将区块链的思想应用到其它领域的想法早就出现了。在2005年,尼克萨博提出了“用所有权为财产冠名”的概念,文中描述了复制数据库技术的发展如何使基于区块链的系统可以应用于登记土地所有权,创建包括例如房产权、违法侵占和乔治亚州土地税等概念的详细框架。然而,不幸的是在那时还没有实用的复制数据库系统,所以这个协议被没有被付诸实践。不过,自2009年比特币系统的去中心化共识开发成功以来,许多区块链的其它应用开始快速出现。 - -* **域名币(namecoin)**- 创建于2010年,被称为去中心化的名称注册数据库。像Tor、Bitcoin和BitMessage这样的去中心化协议,需要一些确认账户的方法,这样其他人才能够与用户进行交互。但是,在所有的现存的解决方案中仅有的可用的身份标识是象`1LW79wp5ZBqaHW1jL5TciBCrhQYtHagUWy`这样的伪随机哈希。理想的情况下,人们希望拥有一个带有象“george”这样的名称的账户。然而,问题是如果有人可以创建“george”账户,那么其他人同样也可以创建“george”账户来假扮。唯一的解决方法是先申请原则(first-to-file),只有第一个注册者可以成功注册,第二个不能再次注册同一个账户。这一问题就可以利用比特币的共识协议。域名币是利用区块链实现名称注册系统的最早的、最成功的系统。 -* **彩色币(Colored coins)**- 彩色币的目的是为人们在比特币区块链上创建自己的数字货币,或者,在更重要的一般意义上的货币 – 数字令牌提供服务。依照彩色币协议,人们可以通过为某一特别的比特币UTXO指定颜色,发行新的货币。该协议递归地将其它UTXO定义为与交易输入UTXO相同的颜色。这就允许用户保持只包含某一特定颜色的UTXO,发送这些UTXO就像发送普通的比特币一样,通过回溯全部的区块链判断收到的UTXO颜色。 -* **元币(Metacoins)**- 元币的理念是在比特币区块链上创建新的协议,利用比特币的交易保存元币的交易,但是采用了不同的状态转换函数APPLY’。因为元币协议不能阻止比特币区块链上的无效的元币交易,所以增加一个规则如果APPLY'(S,TX)返回错误,这一协议将默认APPLY'(S,TX) = S。这为创建任意的、先进的不能在比特币系统中实现的密码学货币协议提供了一个简单的解决方法,而且开发成本非常低,因为挖矿和网络的问题已经由比特币协议处理好了。 - -因此,一般而言,建立共识协议有两种方法:建立一个独立的网络和在比特币网络上建立协议。虽然像域名币这样的应用使用第一种方法已经获得了成功,但是该方法的实施非常困难,因为每一个应用需要创建独立的区块链和建立、测试所有状态转换和网络代码。另外,我们预测去中心化共识技术的应用将会服从幂律分布,大多数的应用太小不足以保证自由区块链的安全,我们还注意到大量的去中心化应用,尤其是去中心化自治组织,需要进行应用之间的交互。 - -另一方面,基于比特币的方法存在缺点,它没有继承比特币可以进行简化确认支付(SPV) 的特性。比特币可以实现简化确认支付,因为比特币可以将区块链深度作为有效性确认代理。在某一点上,一旦一笔交易的祖先们距离现在足够远时,就可以认为它们是合法状态的一部分。与之相反,基于比特币区块链的元币协议不能强迫区块链不包括不符合元币协议的交易。因此,安全的元币协议的简化支付确认需要后向扫描所有的区块,直到区块链的初始点,以确认某一交易是否有效。目前,所有基于比特币的元币协议的“轻”实施都依赖可信任的服务器提供数据,这对主要目的之一是消除信任需要的密码学货币而言,只是一个相当次优的结果。 - -### 脚本 - -即使不对比特币协议进行扩展,它也能在一定程度上实现”智能合约”。比特币的UTXO可以被不只被一个公钥拥有,也可以被用基于堆栈的编程语言所编写的更加复杂的脚本所拥有。在这一模式下,花费这样的UTXO,必须提供满足脚本的数据。事实上,基本的公钥所有权机制也是通过脚本实现的:脚本将椭圆曲线签名作为输入,验证交易和拥有这一UTXO的地址,如果验证成功,返回1,否则返回0。更加复杂的脚本用于其它不同的应用情况。例如,人们可以创建要求集齐三把私钥中的两把才能进行交易确认的脚本(多重签名),对公司账户、储蓄账户和某些商业代理来说,这种脚本是非常有用的。脚本也能用来对解决计算问题的用户发送奖励。人们甚至可以创建这样的脚本“如果你能够提供你已经发送一定数额的的狗币给我的简化确认支付证明,这一比特币UTXO就是你的了”,本质上,比特币系统允许不同的密码学货币进行去中心化的兑换。 - -然而,比特币系统的脚本语言存在一些严重的限制: - -* **缺少图灵完备性** – 这就是说,尽管比特币脚本语言可以支持多种计算,但是它不能支持所有的计算。最主要的缺失是循环语句。不支持循环语句的目的是避免交易确认时出现无限循环。理论上,对于脚本程序员来说,这是可以克服的障碍,因为任何循环都可以用多次重复if 语句的方式来模拟,但是这样做会导致脚本空间利用上的低效率,例如,实施一个替代的椭圆曲线签名算法可能将需要256次重复的乘法,而每次都需要单独编码。 -* **价值盲(Value-blindness)**。UTXO脚本不能为账户的取款额度提供精细的的控制。例如,预言机合约(oracle contract)的一个强大应用是对冲合约,A和B各自向对冲合约中发送价值1000美元的比特币,30天以后,脚本向A发送价值1000美元的比特币,向B发送剩余的比特币。虽然实现对冲合约需要一个预言机(oracle)决定一比特币值多少美元,但是与现在完全中心化的解决方案相比,这一机制已经在减少信任和基础设施方面有了巨大的进步。然而,因为UTXO是不可分割的,为实现此合约,唯一的方法是非常低效地采用许多有不同面值的UTXO(例如对应于最大为30的每个k,有一个2^k的UTXO)并使预言机挑出正确的UTXO发送给A和B。 -* **缺少状态** – UTXO只能是已花费或者未花费状态,这就没有给需要任何其它内部状态的多阶段合约或者脚本留出生存空间。这使得实现多阶段期权合约、去中心化的交换要约或者两阶段加密承诺协议(对确保计算奖励非常必要)非常困难。这也意味着UTXO只能用于建立简单的、一次性的合约,而不是例如去中心化组织这样的有着更加复杂的状态的合约,使得元协议难以实现。二元状态与价值盲结合在一起意味着另一个重要的应用-取款限额-是不可能实现的。 -* **区块链盲(Blockchain-blindness)**- UTXO看不到区块链的数据,例如随机数和上一个区块的哈希。这一缺陷剥夺了脚本语言所拥有的基于随机性的潜在价值,严重地限制了博彩等其它领域应用。 - -我们已经考察了在密码学货币上建立高级应用的三种方法:建立一个新的区块链,在比特币区块链上使用脚本,在比特币区块链上建立元币协议。建立新区块链的方法可以自由地实现任意的特性,成本是开发时间和培育努力。使用脚本的方法非常容易实现和标准化,但是它的能力有限。元币协议尽管非常容易实现,但是存在扩展性差的缺陷。在以太坊系统中,我们的目的是建立一个能够同时具有这三种模式的所有优势的通用框架。 - -## 以太坊 - -以太坊的目的是基于脚本、竞争币和链上元协议(on-chain meta-protocol)概念进行整合和提高,使得开发者能够创建任意的基于共识的、可扩展的、标准化的、特性完备的、易于开发的和协同的应用。以太坊通过建立终极的抽象的基础层-内置有图灵完备编程语言的区块链-使得任何人都能够创建合约和去中心化应用并在其中设立他们自由定义的所有权规则、交易方式和状态转换函数。域名币的主体框架只需要两行代码就可以实现,诸如货币和信誉系统等其它协议只需要不到二十行代码就可以实现。智能合约-包含价值而且只有满足某些条件才能打开的加密箱子-也能在我们的平台上创建,并且因为图灵完备性、价值知晓(value-awareness)、区块链知晓(blockchain-awareness)和多状态所增加的力量而比比特币脚本所能提供的智能合约强大得多。 - -### 以太坊账户 - -在以太坊系统中,状态是由被称为“账户”(每个账户由一个20字节的地址)的对象和在两个账户之间转移价值和信息的状态转换构成的。以太坊的账户包含四个部分: - -· 随机数,用于确定每笔交易只能被处理一次的计数器 -· 账户目前的以太币余额 -· 账户的合约代码,如果有的话 -· 账户的存储(默认为空) -以太币(Ether)是以太坊内部的主要加密燃料,用于支付交易费用。一般而言,以太坊有两种类型的账户:外部所有的账户(由私钥控制的)和合约账户(由合约代码控制)。外部所有的账户没有代码,人们可以通过创建和签名一笔交易从一个外部账户发送消息。每当合约账户收到一条消息,合约内部的代码就会被激活,允许它对内部存储进行读取和写入,和发送其它消息或者创建合约。 - -### 消息和交易 - -以太坊的消息在某种程度上类似于比特币的交易,但是两者之间存在三点重要的不同。第一,以太坊的消息可以由外部实体或者合约创建,然而比特币的交易只能从外部创建。第二,以太坊消息可以选择包含数据。第三,如果以太坊消息的接受者是合约账户,可以选择进行回应,这意味着以太坊消息也包含函数概念。 - -以太坊中“交易”是指存储从外部账户发出的消息的签名数据包。交易包含消息的接收者、用于确认发送者的签名、以太币账户余额、要发送的数据和两个被称为STARTGAS和GASPRICE的数值。为了防止代码的指数型爆炸和无限循环,每笔交易需要对执行代码所引发的计算步骤-包括初始消息和所有执行中引发的消息-做出限制。STARTGAS就是限制,GASPRICE是每一计算步骤需要支付矿工的费用。如果执行交易的过程中,“用完了瓦斯”,所有的状态改变恢复原状态,但是已经支付的交易费用不可收回了。如果执行交易中止时还剩余瓦斯,那么这些瓦斯将退还给发送者。创建合约有单独的交易类型和相应的消息类型;合约的地址是基于账号随机数和交易数据的哈希计算出来的。 - -消息机制的一个重要后果是以太坊的“头等公民”财产-合约与外部账户拥有同样权利,包括发送消息和创建其它合约的权利。这使得合约可以同时充当多个不同的角色,例如,用户可以使去中心化组织(一个合约)的一个成员成为一个中介账户(另一个合约),为一个偏执的使用定制的基于量子证明的兰波特签名(第三个合约)的个人和一个自身使用由五个私钥保证安全的账户(第四个合约)的共同签名实体提供居间服务。以太坊平台的强大之处在于去中心化的组织和代理合约不需要关心合约的每一参与方是什么类型的账户。 - -### 以太坊状态转换函数 - -以太坊的状态转换函数:`APPLY(S,TX) -> S'`,可以定义如下: - -1. 检查交易的格式是否正确(即有正确数值)、签名是否有效和随机数是否与发送者账户的随机数匹配。如否,返回错误。 -2. 计算交易费用:`fee=STARTGAS * GASPRICE`,并从签名中确定发送者的地址。从发送者的账户中减去交易费用和增加发送者的随机数。如果账户余额不足,返回错误。 -3. 设定初值`GAS = STARTGAS`,并根据交易中的字节数减去一定量的瓦斯值。 -4. 从发送者的账户转移价值到接收者账户。如果接收账户还不存在,创建此账户。如果接收账户是一个合约,运行合约的代码,直到代码运行结束或者瓦斯用完。 -5. 如果因为发送者账户没有足够的钱或者代码执行耗尽瓦斯导致价值转移失败,恢复原来的状态,但是还需要支付交易费用,交易费用加至矿工账户。 -6. 否则,将所有剩余的瓦斯归还给发送者,消耗掉的瓦斯作为交易费用发送给矿工。 -例如,假设合约的代码如下: - -```python -if !self.storage[calldataload(0)]: - self.storage[calldataload(0)] = calldataload(32) -``` - -需要注意的是,在现实中合约代码是用底层以太坊虚拟机(EVM)代码写成的。上面的合约是用我们的高级语言Serpent语言写成的,它可以被编译成EVM代码。假设合约存储器开始时是空的,一个值为10以太,瓦斯为2000,瓦斯价格为0.001以太并且64字节数据,第一个三十二字节的快代表号码2和第二个代表词`CHARLIE`。的交易发送后,状态转换函数的处理过程如下: - -1. 检查交易是否有效、格式是否正确。 -2. 检查交易发送者至少有2000*0.001=2个以太币。如果有,从发送者账户中减去2个以太币。 -3. 初始设定gas=2000,假设交易长为170字节,每字节的费用是5,减去850,所以还剩1150。 -4. 从发送者账户减去10个以太币,为合约账户增加10个以太币。 -5. 运行代码。在这个合约中,运行代码很简单:它检查合约存储器索引为2处是否已使用,注意到它未被使用,然后将其值置为CHARLIE。假设这消耗了187单位的瓦斯,于是剩余的瓦斯为1150 - 187 = 963。 -6. 向发送者的账户增加963*0.001=0.963个以太币,返回最终状态。 -如果没有合约接收交易,那么所有的交易费用就等于GASPRICE乘以交易的字节长度,交易的数据就与交易费用无关了。另外,需要注意的是,合约发起的消息可以对它们产生的计算分配瓦斯限额,如果子计算的瓦斯用完了,它只恢复到消息发出时的状态。因此,就像交易一样,合约也可以通过对它产生的子计算设置严格的限制,保护它们的计算资源。 - -### 代码执行 - -以太坊合约的代码使用低级的基于堆栈的字节码的语言写成的,被称为“以太坊虚拟机代码”或者“EVM代码”。代码由一系列字节构成,每一个字节代表一种操作。一般而言,代码执行是无限循环,程序计数器每增加一(初始值为零)就执行一次操作,直到代码执行完毕或者遇到错误,`STOP`或者`RETURN`指令。操作可以访问三种存储数据的空间: - -* **堆栈**,一种后进先出的数据存储,32字节的数值可以入栈,出栈。 -* **内存**,可无限扩展的字节队列。 -* **合约的长期存储**,一个秘钥/数值的存储,其中秘钥和数值都是32字节大小,与计算结束即重置的堆栈和内存不同,存储内容将长期保持。 - -代码可以象访问区块头数据一样访问数值,发送者和接受到的消息中的数据,代码还可以返回数据的字节队列作为输出。 - -EVM代码的正式执行模型令人惊讶地简单。当以太坊虚拟机运行时,它的完整的计算状态可以由元组`(block_state, transaction, message, code, memory, stack, pc, gas)`来定义,这里`block_state`是包含所有账户余额和存储的全局状态。每轮执行时,通过调出代码的第`pc`(程序计数器)个字节,当前指令被找到,每个指令都有定义自己如何影响元组。例如,`ADD`将两个元素出栈并将它们的和入栈,将`gas`(瓦斯)减一并将`pc`加一,`SSTORE`将顶部的两个元素出栈并将第二个元素插入到由第一个元素定义的合约存储位置,同样减少最多200的gas值并将`pc`加一,虽然有许多方法通过即时编译去优化以太坊,但以太坊的基础性的实施可以用几百行代码实现。 - -### 区块链和挖矿 - -虽然有一些不同,但以太坊的区块链在很多方面类似于比特币区块链。它们的区块链架构的不同在于,以太坊区块不仅包含交易记录和最近的状态,还包含区块序号和难度值。以太坊中的区块确认算法如下: - -1. 检查区块引用的上一个区块是否存在和有效。 -2. 检查区块的时间戳是否比引用的上一个区块大,而且小于15分钟。 -3. 检查区块序号、难度值、 交易根,叔根和瓦斯限额(许多以太坊特有的底层概念)是否有效。 -4. 检查区块的工作量证明是否有效。 -5. 将`S[0]`赋值为上一个区块的`STATE_ROOT`。 -6. 将`TX`赋值为区块的交易列表,一共有`n`笔交易。对于属于`0……n-1`的`i`,进行状态转换`S[i+1] = APPLY(S[i],TX[i])`。如果任何一个转换发生错误,或者程序执行到此处所花费的瓦斯(gas)超过了`GASLIMIT`,返回错误。 -7. 用`S[n]`给`S_FINAL`赋值, 向矿工支付区块奖励。 -8 检查`S-FINAL`是否与`STATE_ROOT`相同。如果相同,区块是有效的。否则,区块是无效的。 - -这一确认方法乍看起来似乎效率很低,因为它需要存储每个区块的所有状态,但是事实上以太坊的确认效率可以与比特币相提并论。原因是状态存储在树结构中(tree structure),每增加一个区块只需要改变树结构的一小部分。因此,一般而言,两个相邻的区块的树结构的大部分应该是相同的,因此存储一次数据,可以利用指针(即子树哈希)引用两次。一种被称为“帕特里夏树”(“Patricia Tree”)的树结构可以实现这一点,其中包括了对默克尔树概念的修改,不仅允许改变节点,而且还可以插入和删除节点。另外,因为所有的状态信息是最后一个区块的一部分,所以没有必要存储全部的区块历史-这一方法如果能够可以应用到比特币系统中,经计算可以对存储空间有10-20倍的节省。 - -## 应用 - -一般来讲,以太坊之上有三种应用。第一类是金融应用,为用户提供更强大的用他们的钱管理和参与合约的方法。包括子货币,金融衍生品,对冲合约,储蓄钱包,遗嘱,甚至一些种类的全面的雇佣合约。第二类是半金融应用,这里有钱的存在但也有很重的非金钱的方面,一个完美的例子是为解决计算问题而设的自我强制悬赏。最后,还有在线投票和去中心化治理这样的完全的非金融应用。 - -### 令牌系统 - -链上令牌系统有很多应用,从代表如美元或黄金等资产的子货币到公司股票,单独的令牌代表智能资产,安全的不可伪造的优惠券,甚至与传统价值完全没有联系的用来进行积分奖励的令牌系统。在以太坊中实施令牌系统容易得让人吃惊。关键的一点是理解,所有的货币或者令牌系统,从根本上来说是一个带有如下操作的数据库:从A中减去X单位并把X单位加到B上,前提条件是(1)A在交易之前有至少X单位以及(2)交易被A批准。实施一个令牌系统就是把这样一个逻辑实施到一个合约中去。 - -用Serpent语言实施一个令牌系统的基本代码如下: - -```python -def send(to, value): - if self.storage[from] >= value: - self.storage[from] = self.storage[from] value - self.storage[to] = self.storage[to] + value -``` - -这从本质上来说是本文将要进一步描述的“银行系统”状态转变功能的一个最小化实施。需要增加一些额外的代码以提供在初始和其它一些边缘情况下分发货币的功能,理想情况下会增加一个函数让其它合约来查询一个地址的余额。就足够了。理论上,基于以太坊的充当子货币的令牌系统可能包括一个基于比特币的链上元币所缺乏的重要功能:直接用这种货币支付交易费的能力。实现这种能力的方法是在合约里维护一个以太币账户以用来为发送者支付交易费,通过收集被用来充当交易费用的内部货币并把它们在一个不断运行的拍卖中拍卖掉,合约不断为该以太币账户注资。这样用户需要用以太币“激活”他们的账户,但一旦账户中有以太币它将会被重复使用因为每次合约都会为其充值。 - -### 金融衍生品和价值稳定的货币 - -金融衍生品是“智能合约”的最普遍的应用,也是最易于用代码实现的之一。实现金融合约的主要挑战是它们中的大部分需要参照一个外部的价格发布器;例如,一个需求非常大的应用是一个用来对冲以太币(或其它密码学货币)相对美元价格波动的智能合约,但该合约需要知道以太币相对美元的价格。最简单地方法是通过由某特定机构(例如纳斯达克)维护的“数据提供“合约进行,该合约的设计使得该机构能够根据需要更新合约,并提供一个接口使得其它合约能够通过发送一个消息给该合约以获取包含价格信息的回复。 - -当这些关键要素都齐备,对冲合约看起来会是下面的样子: - -1. 等待A输入1000以太币。. -2. 等待B 输入1000以太币。 -3. 通过查询数据提供合约,将1000以太币的美元价值,例如,x美元,记录至存储器。 -4. 30天后,允许A或B“重新激活“合约以发送价值x美元的以太币(重新查询数据提供合约以获取新价格并计算)给A并将剩余的以太币发送给B。 -这样的合约在密码学商务中有非同寻常的潜力。密码学货币经常被诟病的一个问题就是其价格的波动性;虽然大量的用户和商家可能需要密码学资产所带来的安全和便利,可他们不太会乐意面对一天中资产跌去23%价值的情形。直到现在,最为常见的推荐方案是发行者背书资产;思想是发行者创建一种子货币,对此种子货币他们有权发行和赎回,给予(线下)提供给他们一个单位特定相关资产(例如黄金,美元)的人一个单位子货币。发行者承诺当任何人送还一个单位密码学资产时。发还一个单位的相关资产。这种机制能够使任何非密码学资产被“升级“为密码学资产,如果发行者值得信任的话。 -然而实践中发行者并非总是值得信任的,并且一些情况下银行体系太脆弱,或者不够诚实守信从而使这样的服务无法存在。金融衍生品提供了一种替代方案。这里将不再有提供储备以支撑一种资产的单独的发行者,取而代之的是一个由赌一种密码学资产的价格会上升的投机者构成的去中心化市场。与发行者不同,投机者一方没有讨价还价的权利,因为对冲合约把他们的储备冻结在了契约中。注意这种方法并非是完全去中心化的,因为依然需要一个可信任的提供价格信息的数据源,尽管依然有争议这依然是在降低基础设施需求(与发行者不同,一个价格发布器不需要牌照并且似乎可归为自由言论一类)和降低潜在欺诈风险方面的一个巨大的进步。 - -### 身份和信誉系统 - -最早的替代币,域名币,尝试使用一个类比特币块链来提供一个名称注册系统,在那里用户可以将他们的名称和其它数据一起在一个公共数据库注册。最常用的应用案例把象“bitcoin.org“(或者再域名币中,”bitcoin.bit“)一样的域名与一个IP地址对应的域名系统。其它的应用案例包括电子邮件验证系统和潜在的更先进的信誉系统。这里是以太坊中提供与域名币类似的的名称注册系统的基础合约: - -```python -def register(name, value): - if !self.storage[name]: - self.storage[name] = value -``` - -合约非常简单;就是一个以太坊网络中的可以被添加但不能被修改或移除的数据库。任何人都可以把一个名称注册为一个值并永远不变。一个更复杂的名称注册合约将包含允许其他合约查询的“功能条款“,以及一个让一个名称的”拥有者“(即第一个注册者)修改数据或者转让所有权的机制。甚至可以在其上添加信誉和信任网络功能。 - -### 去中心化存储 - -在过去的几年里出现了一些大众化的在线文件存储初创公司,最突出的是Dropbox,它寻求允许用户上传他们的硬盘备份,提供备份存储服务并允许用户访问从而按月向用户收取费用。然而,在这一点上这个文件存储市场有时相对低效;对现存服务的粗略观察表明,特别地在“神秘谷“20-200GB这一既没有免费空间也没有企业级用户折扣的水平上,主流文件存储成本每月的价格意味着支付在一个月里支付整个硬盘的成本。以太坊合约允许去中心化存储生态的开发,这样用户通过将他们自己的硬盘或未用的网络空间租出去以获得少量收益,从而降低了文件存储的成本。 - -这样的设施的基础性构件就是我们所谓的“去中心化Dropbox合约“。这个合约工作原理如下。首先,某人将需要上传的数据分成快,对每一块数据加密以保护隐私,并且以此构建一个默克尔树。然后创建一个含以下规则的合约,每N个块,合约将从默克尔树中抽取一个随机索引(使用能够被合约代码访问的上一个块的哈希来提供随机性), 然后给第一个实体X以太以支撑一个带有类似简化验证支付(SPV)的在树中特定索引处的块的所有权证明。当一个用户想重新下载他的文件,他可以使用微支付通道协议(例如每32k字节支付1萨博)恢复文件;从费用上讲最高效的方法是支付者不到最后不发布交易,而是用一个略微更合算的带有同样随机数的交易在每32k字节之后来代替原交易。 - -这个协议的一个重要特征是,虽然看起来象是一个人信任许多不准备丢失文件的随机节点,但是他可以通过秘密分享把文件分成许多小块,然后通过监视合同得知每个小块都还被某个节点的保存着。如果一个合约依然在付款,那么就提供了某个人依然在保存文件的证据。 - -### 去中心化自治组织 - -通常意义上“去中心化自治组织(DAO, decentralized autonomous organization)”的概念指的是一个拥有一定数量成员或股东的虚拟实体,依靠比如67%多数来决定花钱以及修改代码。成员会集体决定组织如何分配资金。分配资金的方法可能是悬赏,工资或者更有吸引力的机制比如用内部货币奖励工作。这仅仅使用密码学块链技术就从根本上复制了传统公司或者非营利组织的法律意义以实现强制执行。至此许多围绕DAO的讨论都是围绕一个带有接受分红的股东和可交易的股份的“去中心化自治公司(DAC,decentralized autonomous corporation)”的“资本家”模式;作为替代者,一个被描述为“去中心化自治社区(decentralized autonomous community)”的实体将使所有成员都在决策上拥有同等的权利并且在增减成员时要求67%多数同意。每个人都只能拥有一个成员资格这一规则需要被群体强制实施。 - -下面是一个如何用代码实现DO的纲要。最简单地设计就是一段如果三分之二成员同意就可以自我修改的代码。虽然理论上代码是不可更改的,然而通过把代码主干放在一个单独的合约内并且把合约调用的地址指向一个可更改的存储依然可以容易地绕开障碍而使代码变得可修改,在一个这样的DAO合约的简单实现中有三种交易类型,由交易提供的数据区分: - -* `[0,i,K,V]` 注册索引为i 的对存储地址索引为K 至 v 的内容的更改建议。 -* `[0,i]` 注册对建议i 的投票。 -* `[2,i]` 如有足够投票则确认建议i。 - -然后合约对每一项都有具体的条款。它将维护一个所有开放存储的更改记录以及一个谁投票表决的表。还有一个所有成员的表。当任何存储内容的更改获得了三分之二多数同意,一个最终的交易将执行这项更改。一个更加复杂的框架会增加内置的选举功能以实现如发送交易,增减成员,甚至提供委任制民主一类的投票代表(即任何人都可以委托另外一个人来代表自己投票,而且这种委托关系是可以传递的,所以如果A委托了B然后B委托了C那么C将决定A的投票)。这种设计将使DAO作为一个去中心化社区有机地成长, 使人们最终能够把挑选合适人选的任务交给专家,与当前系统不同,随着社区成员不断改变他们的站队假以时日专家会容易地出现和消失。 -一个替代的模式是去中心化公司,那里任何账户可以拥有0到更多的股份,决策需要三分之二多数的股份同意。一个完整的框架将包括资产管理功能-可以提交买卖股份的订单以及接受这种订单的功能(前提是合约里有订单匹配机制)。代表依然以委任制民主的方式存在,产生了“董事会”的概念。 - -更先进的组织治理机制可能会在将来实现;现在一个去中心化组织(DO)可以从去中心化自治组织(DAO)开始描述。DO和DAO的区别是模糊的,一个大致的分割线是治理是否可以通过一个类似政治的过程或者一个“自动”过程实现,一个不错的直觉测试是“无通用语言”标准:如果两个成员不说同样的语言组织还能正常运行吗?显然,一个简单的传统的持股式公司会失败,而象比特币协议这样的却很可能成功,罗宾·汉森的“futarchy”,一个通过预测市场实现组织化治理的机制是一个真正的说明“自治”式治理可能是什么样子的好例子。注意一个人无需假设所有DAO比所有DO优越;自治只是一个在一些特定场景下有很大优势的,但在其它地方未必可行的范式,许多半DAO可能存在。 - -### 进一步的应用 - -1. **储蓄钱包**。 假设Alice想确保她的资金安全,但她担心丢失或者被黑客盗走私钥。她把以太币放到和Bob签订的一个合约里,如下所示,这合同是一个银行: - * Alice单独每天最多可提取1%的资金。 - * Bob单独每天最多可提取1%的资金,但Alice可以用她的私钥创建一个交易取消Bob的提现权限。 - * Alice 和 Bob 一起可以任意提取资金。 -一般来讲,每天1%对Alice足够了,如果Alice想提现更多她可以联系Bob寻求帮助。如果Alice的私钥被盗,她可以立即找到Bob把她的资金转移到一个新合同里。如果她弄丢了她的私钥,Bob可以慢慢地把钱提出。如果Bob表现出了恶意,她可以关掉他的提现权限。 - -2. **作物保险**。一个人可以很容易地以天气情况而不是任何价格指数作为数据输入来创建一个金融衍生品合约。如果一个爱荷华的农民购买了一个基于爱荷华的降雨情况进行反向赔付的金融衍生品,那么如果遇到干旱,该农民将自动地收到赔付资金而如果有足量的降雨他会很开心因为他的作物收成会很好。 - -3. **一个去中心化的数据发布器**。 对于基于差异的金融合约,事实上通过过“谢林点”协议将数据发布器去中心化是可能的。谢林点的工作原理如下:N方为某个指定的数据提供输入值到系统(例如ETH/USD价格),所有的值被排序,每个提供25%到75%之间的值的节点都会获得奖励,每个人都有激励去提供他人将提供的答案,大量玩家可以真正同意的答案明显默认就是正确答案,这构造了一个可以在理论上提供很多数值,包括ETH/USD价格,柏林的温度甚至某个特别困难的计算的结果的去中心化协议。 - -5.**云计算**。EVM技术还可被用来创建一个可验证的计算环境,允许用户邀请他人进行计算然后选择性地要求提供在一定的随机选择的检查点上计算被正确完成的证据。这使得创建一个任何用户都可以用他们的台式机,笔记本电脑或者专用服务器参与的云计算市场成为可能,现场检查和安全保证金可以被用来确保系统是值得信任的(即没有节点可以因欺骗获利)。虽然这样一个系统可能并不适用所有任务;例如,需要高级进程间通信的任务就不易在一个大的节点云上完成。然而一些其它的任务就很容易实现并行;SETI@home, folding@home和基因算法这样的项目就很容易在这样的平台上进行。 - -6.**点对点赌博**。任意数量的点对点赌博协议都可以搬到以太坊的区块链上,例如Frank Stajano和Richard Clayton的Cyberdice。 最简单的赌博协议事实上是这样一个简单的合约,它用来赌下一个区块的哈稀值与猜测值之间的差额, 据此可以创建更复杂的赌博协议,以实现近乎零费用和无欺骗的赌博服务。 - -7.**预测市场**。 不管是有神谕还是有谢林币,预测市场都会很容易实现,带有谢林币的预测市场可能会被证明是第一个主流的作为去中心化组织管理协议的“futarchy”应用。 - -8.链上去中心化市场,以身份和信誉系统为基础。 - -## 杂项和关注 - -### 改进版幽灵协议的实施 - - “幽灵“协议("Greedy Heaviest Observed Subtree" (GHOST) protocol)是由Yonatan Sompolinsky 和 Aviv Zohar在2013年12月引入的创新。幽灵协议提出的动机是当前快速确认的块链因为区块的高作废率而受到低安全性困扰;因为区块需要花一定时间(设为t)扩散至全网,如果矿工A挖出了一个区块然后矿工B碰巧在A的区块扩散至B之前挖出了另外一个区块,矿工B的区块就会作废并且没有对网络安全作出贡献。此外,这里还有中心化问题:如果A是一个拥有全网30%算力的矿池而B拥有10%的算力,A将面临70%的时间都在产生作废区块的风险而B在90%的时间里都在产生作废区块。因此,如果作废率高,A将简单地因为更高的算力份额而更有效率,综合这两个因素,区块产生速度快的块链很可能导致一个矿池拥有实际上能够控制挖矿过程的算力份额。 - -正如Sompolinsky 和 Zohar所描述的,通过在计算哪条链“最长”的时候把废区块也包含进来,幽灵协议解决了降低网络安全性的第一个问题;这就是说,不仅一个区块的父区块和更早的祖先块,祖先块的作废的后代区块(以太坊术语中称之为“叔区块”)也被加进来以计算哪一个区块拥有支持其的最大工作量证明。我们超越了Sompolinsky 和 Zohar所描述的协议以解决第二个问题 – 中心化倾向,以太坊付给以“叔区块”身份为新块确认作出贡献的废区块87.5%的奖励,把它们纳入计算的“侄子区块”将获得奖励的12.5%,不过,交易费用不奖励给叔区块。 -以太坊实施了一个只下探到第五层的简化版本的幽灵协议。其特点是,废区块只能以叔区块的身份被其父母的第二代至第五代后辈区块,而不是更远关系的后辈区块(例如父母区块的第六代后辈区块,或祖父区块的第三代后辈区块)纳入计算。这样做有几个原因。首先,无条件的幽灵协议将给计算给定区块的哪一个叔区块合法带来过多的复杂性。其次,带有以太坊所使用的补偿的无条件的幽灵协议剥夺了矿工在主链而不是一个公开攻击者的链上挖矿的激励。最后,计算表明带有激励的五层幽灵协议即使在出块时间为15s的情况下也实现了了95%以上的效率,而拥有25%算力的矿工从中心化得到的益处小于3%。 - -### 费用 - -因为每个发布的到区块链的交易都占用了下载和验证的成本,需要有一个包括交易费的规范机制来防范滥发交易。比特币使用的默认方法是纯自愿的交易费用,依靠矿工担当守门人并设定动态的最低费用。因为这种方法是“基于市场的”,使得矿工和交易发送者能够按供需来决定价格,所以这种方法在比特币社区被很顺利地接受了。然而,这个逻辑的问题在于,交易处理并非一个市场;虽然根据直觉把交易处理解释成矿工给发送者提供的服务是很有吸引力的,但事实上一个矿工收录的交易是需要网络中每个节点处理的,所以交易处理中最大部分的成本是由第三方而不是决定是否收录交易的矿工承担的。于是,非常有可能发生公地悲剧。 - -然而,当给出一个特殊的不够精确的简化假设时,这个基于市场的机制的漏洞很神奇地消除了自己的影响。论证如下。假设: - -1. 一个交易带来 k 步操作, 提供奖励 kR给任何收录该交易的矿工,这里 R 由交易发布者设定, k 和 R 对于矿工都是事先(大致上)可见的。 -2. 每个节点处理每步操作的成本都是 C (即所有节点的效率一致)。 -3. 有 N 个挖矿节点,每个算力一致(即全网算力的1/N)。 -4. 没有不挖矿的全节点。 - -当预期奖励大于成本时,矿工愿意挖矿。这样,因为矿工有1/N 的机会处理下一个区块,所以预期的收益是 kR/N , 矿工的处理成本简单为 kC. 这样当 kR/N > kC, 即 R > NC时。矿工愿意收录交易。注意 R 是由交易发送者提供的每步费用,是矿工从处理交易中获益的下限。 NC 是全网处理一个操作的成本。所以,矿工仅有动机去收录那些收益大于成本的交易。 -然而,这些假设与实际情况有几点重要的偏离: - -1. 因为额外的验证时间延迟了块的广播因而增加了块成为废块的机会,处理交易的矿工比其它的验证节点付出了更高的成本。 -2. 不挖矿的全节点是存在的。 -3. 实践中算力分布可能最后是极端不平均的。 -4. 以破坏网络为己任的投机者,政敌和疯子确实存在,并且他们能够聪明地设置合同使得他们的成本比其它验证节点低得多。 -上面第1点驱使矿工收录更少的交易,第2点增加了 NC; 因此这两点的影响至少部分互相抵消了. 第3点和第4点是主要问题;作为解决方案我们简单地建立了一个浮动的上限:没有区块能够包含比BLK_LIMIT_FACTOR 倍长期指数移动平均值更多的操作数。具体地: - -`blk.oplimit = floor((blk.parent.oplimit * (EMAFACTOR - 1) + floor(parent.opcount * BLK_LIMIT_FACTOR)) /EMA_FACTOR)` - -BLK_LIMIT_FACTOR 和 EMA_FACTOR 是暂且被设为 65536 和 1.5 的常数,但可能会在更深入的分析后调整。 -回复 - -### 计算和图灵完备 - -需要强调的是以太坊虚拟机是图灵完备的; 这意味着EVM代码可以实现任何可以想象的计算,包括无限循环。EVM代码有两种方式实现循环。首先, JUMP 指令可以让程序跳回至代码前面某处,还有允许如 `while x < 27: x = x * 2 ` 一样的条件语句的JUMPI 指令实现条件跳转。其次,合约可以调用其它合约,有通过递归实现循环的潜力。这很自然地导致了一个问题:恶意用户能够通过迫使矿工和全节点进入无限循环而不得不关机吗? 这问题出现是因为计算机科学中一个叫停机问题的问题:一般意义上没有办法知道,一个给定的程序是否能在有限的时间内结束运行。 - -正如在状态转换章节所述,我们的方案通过为每一个交易设定运行执行的最大计算步数来解决问题,如果超过则计算被恢复原状但依然要支付费用。消息以同样的方式工作。为显示这一方案背后的动机,请考虑下面的例子: - -* 一个攻击者创建了一个运行无限循环的合约,然后发送了一个激活循环的交易给矿工,矿工将处理交易,运行无限循环直到瓦斯耗尽。即使瓦斯耗尽交易半途停止,交易依然正确(回到原处)并且矿工依然从攻击者哪里挣到了每一步计算的费用。 -* 一个攻击者创建一个非常长的无限循环意图迫使矿工长时间内一直计算致使在计算结束前若干区块已经产生于是矿工无法收录交易以赚取费 用。然而,攻击者需要发布一个 STARTGAS 值以限制可执行步数,因而矿工将提前知道计算将耗费过多的步数。 -* 一个攻击者看到一个包含诸如 send(A,self.storage); self.storage = 0格式的合约然后发送带有只够执行第一步的费用的而不够执行第二步的交易(即提现但不减少账户余额)。合约作者无需担心防卫类似攻击,因为如果执行中途停止则所有变更都被回复。 -* 一个金融合约靠提取九个专用数据发布器的中值来工作以最小化风险,一个攻击者接管了其中一个数据提供器,然后把这个按DAO章节所述的可变地址调用机制设计成可更改的数据提供器转为运行一个无限循环,以求尝试逼迫任何从此金融合约索要资金的尝试都会因瓦斯耗尽而中止。然而,该金融合约可以在消息里设置瓦斯限制以防范此类问题。 -图灵完备的替代是图灵不完备,这里 JUMP 和 JUMPI 指令不存在并且在某个给定时间每个合约只允许有一个拷贝存在于调用堆栈内。在这样的系统里,上述的费用系统和围绕我们的方案的效率的不确定性可能都是不需要的,因为执行一个合约的成本将被它的大小决定。此外,图灵不完备甚至不是一个大的限制,在我们内部设想的所有合约例子中,至今只有一个需要循环,而且即使这循环也可以被26个单行代码段的重复所代替。考虑到图灵完备带来的严重的麻烦和有限的益处,为什么不简单地使用一种图灵不完备语言呢?事实上图灵不完备远非一个简洁的解决方案。为什么?请考虑下面的合约: - -```python -C0: call(C1); call(C1); -C1: call(C2); call(C2); -C2: call(C3); call(C3); -... -C49: call(C50); call(C50); -C50: (作一个图灵机的步计算和记录结果在合约的长期存储) -``` - -现在,发送一个这样的交易给A,这样,在51个交易中,我们有了一个需要花费2^50 步计算的合约,矿工可能尝试通过为每一个合约维护一个最高可执行步数并且对于递归调用其它合约的合约计算可能执行步数从而预先检测这样的逻辑炸弹,但是这会使矿工禁止创建其它合约的合约(因为上面26个合约的创建和执行可以很容易地放入一个单独合约内)。另外一个问题点是一个消息的地址字段是一个变量,所以通常来讲可能甚至无法预先知道一个合约将要调用的另外一个合约是哪一个。于是,最终我们有了一个惊人的结论:图灵完备的管理惊人地容易,而在缺乏同样的控制时图灵不完备的管理惊人地困难- 那为什么不让协议图灵完备呢? - -### 货币和发行 - -以太坊网络包含自身的内置货币以太币,以太币扮演双重角色,为各种数字资产交易提供主要的流动性,更重要的是提供了了支付交易费用的一种机制。为便利及避免将来的争议期间(参见当前的mBTC/uBTC/聪的争论),不同面值的名称将被提前设置: - -* 1: 伟 -* 10^12: 萨博 -* 10^15: 芬尼 -* 10^18: 以太 - -这应该被当作是“元”和“分”或者“比特币”和“聪”的概念的扩展版,在不远的将来,我们期望“以太”被用作普通交易,“芬尼”用来进行微交易,“萨博”和“伟”用来进行关于费用和协议实施的讨论。 - -发行模式如下: - -* 通过发售活动,以太币将以每BTC 1337-2000以太的价格发售,一个旨在为以太坊组织筹资并且为开发者支付报酬的机制已经在其它一些密码学货币平台上成功使用。早期购买者会享受较大的折扣,发售所得的BTC将完全用来支付开发者和研究者的工资和悬赏,以及投入密码学货币生态系统的项目。 -* 0.099x (x为发售总量)将被分配给BTC融资或其它的确定性融资成功之前参与开发的早期贡献者,另外一个0.099x将分配给长期研究项目。 -* 自上线时起每年都将有0.26x(x为发售总量)被矿工挖出。 - -### 发行分解 -永久线性增长模型降低了在比特币中出现的财富过于集中的风险,并且给予了活在当下和将来的人公平的机会去获取货币,同时保持了对获取和持有以太币的激励,因为长期来看“货币供应增长率”是趋于零的。我们还推断,随着时间流逝总会发生因为粗心和死亡等原因带来的币的遗失,假设币的遗失是每年货币供应量的一个固定比例,则最终总的流通中的货币供应量会稳定在一个等于年货币发行量除以遗失率的值上(例如,当遗失率为1%时,当供应量达到30x时,每年有0.3x被挖出同时有0.3x丢失,达到一个均衡)。 - -![](http://bitcoin8btc.qiniudn.com/wp-content/uploads/2014/10/table.png) -除了线性的发行方式外,和比特币一样以太币的的供应量增长率长期来看也趋于零。 - -![](http://bitcoin8btc.qiniudn.com/wp-content/uploads/2014/10/supply.png) - -### 挖矿的中心化 - -比特币挖矿算法基本上是让矿工千万次地轻微改动区块头,直到最终某个节点的改动版本的哈希小于目标值(目前是大约2190)。然而,这种挖矿算法容易被两种形式的中心化攻击。第一种,挖矿生态系统被专门设计的因而在比特币挖矿这一特殊任务上效率提高上千倍的ASICs(专用集成电路)和电脑芯片控制。这意味着比特币挖矿不再是高度去中心化的和追求平等主义的,而是需要巨额资本的有效参与。第二种,大部分比特币矿工事实上不再在本地完成区块验证;而是依赖中心化的矿池提供区块头。这个问题可以说很严重:在本文写作时,最大的两个矿池间接地控制了大约全网50%的算力,虽然当一个矿池或联合体尝试51%攻击时矿工可以转换到其它矿池这一事实减轻了问题的严重性。 - -以太坊现在的目的是使用一个基于为每1000个随机数随机产生唯一哈希的函数的挖矿算法,用足够宽的计算域,去除专用硬件的优势。这样的策略当然不会使中心化的收益减少为零,但是也不需要。注意每单个用户使用他们的私人笔记本电脑或台式机就可以几乎免费地完成一定量的挖矿活动,但当到了100%的CPU使用率之后更多地挖矿就会需要他们支付电力和硬件成本。ASIC挖矿公司需要从第一个哈希开始就为电力和硬件支付成本。所以,如果中心化收益能够保持在(E + H) /E 以下,那么即使ASICs被制造出来普通矿工依然有生存空间。另外,我们计划将挖矿算法设计成挖矿需要访问整个区块链,迫使矿工存储完成的区块链或者至少能够验证每笔交易。这去除了对中心化矿池的需要;虽然矿池依然可以扮演平滑收益分配的随机性的角色,但这功能可以被没有中心化控制的P2P矿池完成地同样好。这样即使大部分普通用户依然倾向选择轻客户端,通过增加网络中的全节点数量也有助于抵御中心化。 - -### 扩展性 - -扩展性问题是以太坊常被关注的地方,与比特币一样,以太坊也遭受着每个交易都需要网络中的每个节点处理这一困境的折磨。比特币的当前区块链大小约为20GB,以每小时1MB的速度增长。如果比特币网络处理Visa级的2000tps的交易,它将以每三秒1MB的速度增长(1GB每小时,8TB每年)。以太坊可能也会经历相似的甚至更糟的增长模式,因为在以太坊区块链之上还有很多应用,而不是像比特币只是简单的货币,但以太坊全节点只需存储状态而不是完整的区块链历史这一事实让情况得到了改善。 - -大区块链的问题是中心化风险。如果块链大小增加至比如100TB,可能的场景将是只有非常小数目的大商家会运行全节点,而常规用户使用轻的SPV节点。这会增加对全节点合伙欺诈牟利(例如更改区块奖励,给他们自己BTC)的风险的担忧。轻节点将没有办法立刻检测到这种欺诈。当然,至少可能存在一个诚实的全节点,并且几个小时之后有关诈骗的信息会通过Reddit这样的渠道泄露,但这时已经太晚:任凭普通用户做出怎样的努力去废除已经产生的区块,他们都会遇到与发动一次成功的51%攻击同等规模的巨大的不可行的协调问题。在比特币这里,现在这是一个问题,但Peter Todd建议的一个改动可以缓解这个问题。 - -近期,以太坊会使用两个附加的策略以应对此问题。首先,因为基于区块链的挖矿算法,至少每个矿工会被迫成为一个全节点,这保证了一定数量的全节点。其次,更重要的是,处理完每笔交易后,我们会把一个中间状态树的根包含进区块链。即使区块验证是中心化的,只要有一个诚实的验证节点存在,中心化的问题就可以通过一个验证协议避免。如果一个矿工发布了一个不正确的区块,这区块要么是格式错,要么状态S[n]是错的。因为S[0]是正确的,必然有第一个错误状态S[i]但S[i-1]是正确的,验证节点将提供索引i,一起提供的还有处理APPLY(S[i-1],TX[i]) -> S[i]所需的帕特里夏树节点的子集。这些节点将受命进行这部分计算,看产生的S[i]与先前提供的值是否一致。 - -另外,更复杂的是恶意矿工发布不完整区块进行攻击,造成没有足够的信息去确定区块是否正确。解决方案是质疑-回应协议:验证节点对目标交易索引发起质疑,接受到质疑信息的轻节点会对相应的区块取消信任,直到另外一个矿工或者验证者提供一个帕特里夏节点子集作为正确的证据。 - -## 综述:去中心化应用 - - - -上述合约机制使得任何一个人能够在一个虚拟机上建立通过全网共识来运行命令行应用(从根本上来说是),它能够更改一个全网可访问的状态作为它的“硬盘”。然而,对于多数人来说,用作交易发送机制的命令行接口缺乏足够的用户友好使得去中心化成为有吸引力的替代方案。最后,一个完整的“去中心化应用”应该包括底层的商业逻辑组件【无论是否在以太坊完整实施,使用以太坊和其它系统组合(如一个P2P消息层,其中一个正在计划放入以太坊客户端)或者仅有其它系统的方式】和上层的图形用户接口组件。以太坊客户端被设计成一个网络浏览器,但包括对“eth” Javascript API对象的支持,可被客户端里看到的特定的网页用来与以太坊区块链交互。从“传统”网页的角度看来,这些网页是完全静态的内容,因为区块链和其它去中心化协议将完全代替服务器来处理用户发起的请求。最后,去中心化协议有希望自己利用某种方式使用以太坊来存储网页。 - -## 结论 - - - -以太坊协议最初是作为一个通过高度通用的语言提供如链上契约,提现限制和金融合约,赌博市场等高级功能的升级版密码学货币来构思的。以太坊协议将不直接“支持”任何应用,但图灵完备编程语言的存在意味着理论上任意的合约都可以为任何交易类型和应用创建出来。然而关于以太坊更有趣的是,以太坊协议比单纯的货币走得更远,围绕去中心化存储,去中心化计算和去中心化预测市场以及数十个类似概念建立的协议和去中心化应用,有潜力从根本上提升计算行业的效率,并通过首次添加经济层为其它的P2P协议提供有力支撑,最终,同样会有大批与金钱毫无关系的应用出现。 - -以太坊协议实现的任意状态转换概念提供了一个具有独特潜力的平台;与封闭式的,为诸如数据存储,赌博或金融等单一目的设计的协议不同,以太坊从设计上是开放式的,并且我们相信它极其适合作为基础层服务于在将来的年份里出现的极其大量的金融和非金融协议。 - -## 注解与进阶阅读 - -### 注解 - -1.一个有经验的读者会注意到事实上比特币地址是椭圆曲线公钥的哈希,而非公钥本身,然而事实上从密码学术语角度把公钥哈希称为公钥完全合理。这是因为比特币密码学可以被认为是一个定制的数字签名算法,公钥由椭圆曲线公钥的哈希组成,签名由椭圆曲线签名连接的椭圆曲线公钥组成,而验证算法包括用作为公钥提供的椭圆曲线公钥哈希来检查椭圆曲线公钥,以及之后的用椭圆曲线公钥来验证椭圆曲线签名。 - -2.技术上来说,前11个区块的中值。 - -3.在内部,2和“CHARLIE”都是数字,后一个有巨大的base256编码格式,数字可以从0到2^256-1。 - -### 进阶阅读 - -1. Intrinsic value: https://tinyurl.com/BitcoinMag-IntrinsicValue - -2. Smart property: https://en.bitcoin.it/wiki/Smart_Property - -3. Smart contracts: https://en.bitcoin.it/wiki/Contracts - -4. B-money: http://www.weidai.com/bmoney.txt - -5. Reusable proofs of work: http://www.finney.org/~hal/rpow/ - -6. Secure property titles with owner authority: http://szabo.best.vwh.net/securetitle.html - -7. Bitcoin whitepaper: http://bitcoin.org/bitcoin.pdf - -8. Namecoin: https://namecoin.org/ - -9. Zooko’s triangle: http://en.wikipedia.org/wiki/Zooko’s_triangle - -10. Colored coins whitepaper: https://tinyurl.com/coloredcoin-whitepaper - -11. Mastercoin whitepaper: https://github.com/mastercoin-MSC/spec - -12. Decentralized autonomous corporations, Bitcoin Magazine: https://tinyurl.com/Bootstrapping-DACs - -13. Simplified payment verification:https://en.bitcoin.it/wiki/Scalability#Simplifiedpaymentverification - -14. Merkle trees: http://en.wikipedia.org/wiki/Merkle_tree - -15. Patricia trees: http://en.wikipedia.org/wiki/Patricia_tree - -16. GHOST: http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf - -17. StorJ and Autonomous Agents, Jeff Garzik: https://tinyurl.com/storj-agents - -18. Mike Hearn on Smart Property at Turing Festival: http://www.youtube.com/watch?v=Pu4PAMFPo5Y - -19. Ethereum RLP: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP - -20. Ethereum Merkle Patricia trees: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree - -21. Peter Todd on Merkle sum trees:http://sourceforge.net/p/bitcoin/mailman/message/31709140/ \ No newline at end of file diff --git a/pages/white-paper/[english]-white-paper.md b/pages/white-paper/[english]-white-paper.md deleted file mode 100644 index 28b0258fa..000000000 --- a/pages/white-paper/[english]-white-paper.md +++ /dev/null @@ -1,500 +0,0 @@ ----gg -name: White Paper -category: Basics ---- - -### A Next-Generation Smart Contract and Decentralized Application Platform - -Satoshi Nakamoto's development of Bitcoin in 2009 has often been hailed as a radical development in money and currency, being the first example of a digital asset which simultaneously has no backing or "[intrinsic value](http://bitcoinmagazine.com/8640/an-exploration-of-intrinsic-value-what-it-is-why-bitcoin-doesnt-have-it-and-why-bitcoin-does-have-it/)" and no centralized issuer or controller. However, another, arguably more important, part of the Bitcoin experiment is the underlying blockchain technology as a tool of distributed consensus, and attention is rapidly starting to shift to this other aspect of Bitcoin. Commonly cited alternative applications of blockchain technology include using on-blockchain digital assets to represent custom currencies and financial instruments (["colored coins"](https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit)), the ownership of an underlying physical device (["smart property"](https://en.bitcoin.it/wiki/Smart_Property)), non-fungible assets such as domain names (["Namecoin"](http://namecoin.org)), as well as more complex applications involving having digital assets being directly controlled by a piece of code implementing arbitrary rules (["smart contracts"](http://szabo.best.vwh.net/smart_contracts_idea.html)) or even blockchain-based "[decentralized autonomous organizations](http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/)" (DAOs). What Ethereum intends to provide is a blockchain with a built-in fully fledged Turing-complete programming language that can be used to create "contracts" that can be used to encode arbitrary state transition functions, allowing users to create any of the systems described above, as well as many others that we have not yet imagined, simply by writing up the logic in a few lines of code. - -### Table of Contents - -* [History](#history) - * [Bitcoin As A State Transition System](#bitcoin-as-a-state-transition-system) - * [Mining](#mining) - * [Merkle Trees](#merkle-trees) - * [Alternative Blockchain Applications](#alternative-blockchain-applications) - * [Scripting](#scripting) -* [Ethereum](#ethereum) - * [Ethereum Accounts](#ethereum-accounts) - * [Messages and Transactions](#messages-and-transactions) - * [Ethereum State Transition Function](#ethereum-state-transition-function) - * [Code Execution](#code-execution) - * [Blockchain and Mining](#blockchain-and-mining) -* [Applications](#applications) - * [Token Systems](#token-systems) - * [Financial derivatives](#financial-derivatives-and-stable-value-currencies) - * [Identity and Reputation Systems](#identity-and-reputation-systems) - * [Decentralized File Storage](#decentralized-file-storage) - * [Decentralized Autonomous Organizations](#decentralized-autonomous-organizations) - * [Further Applications](#further-applications) -* [Miscellanea And Concerns](#miscellanea-and-concerns) - * [Modified GHOST Implementation](#modified-ghost-implementation) - * [Fees](#fees) - * [Computation And Turing-Completeness](#computation-and-turing-completeness) - * [Currency And Issuance](#currency-and-issuance) - * [Mining Centralization](#mining-centralization) - * [Scalability](#scalability) -* [Conclusion](#conclusion) -* [References and Further Reading](#references-and-further-reading) - -## Introduction to Bitcoin and Existing Concepts - -### History - -The concept of decentralized digital currency, as well as alternative applications like property registries, has been around for decades. The anonymous e-cash protocols of the 1980s and the 1990s, mostly reliant on a cryptographic primitive known as Chaumian blinding, provided a currency with a high degree of privacy, but the protocols largely failed to gain traction because of their reliance on a centralized intermediary. In 1998, Wei Dai's [b-money](http://www.weidai.com/bmoney.txt) became the first proposal to introduce the idea of creating money through solving computational puzzles as well as decentralized consensus, but the proposal was scant on details as to how decentralized consensus could actually be implemented. In 2005, Hal Finney introduced a concept of "[reusable proofs of work](http://www.finney.org/~hal/rpow/)", a system which uses ideas from b-money together with Adam Back's computationally difficult Hashcash puzzles to create a concept for a cryptocurrency, but once again fell short of the ideal by relying on trusted computing as a backend. In 2009, a decentralized currency was for the first time implemented in practice by Satoshi Nakamoto, combining established primitives for managing ownership through public key cryptography with a consensus algorithm for keeping track of who owns coins, known as "proof of work". - -The mechanism behind proof of work was a breakthrough in the space because it simultaneously solved two problems. First, it provided a simple and moderately effective consensus algorithm, allowing nodes in the network to collectively agree on a set of canonical updates to the state of the Bitcoin ledger. Second, it provided a mechanism for allowing free entry into the consensus process, solving the political problem of deciding who gets to influence the consensus, while simultaneously preventing sybil attacks. It does this by substituting a formal barrier to participation, such as the requirement to be registered as a unique entity on a particular list, with an economic barrier - the weight of a single node in the consensus voting process is directly proportional to the computing power that the node brings. Since then, an alternative approach has been proposed called _proof of stake_, calculating the weight of a node as being proportional to its currency holdings and not computational resources; the discussion of the relative merits of the two approaches is beyond the scope of this paper but it should be noted that both approaches can be used to serve as the backbone of a cryptocurrency. - -### Bitcoin As A State Transition System - -![statetransition.png](https://raw.githubusercontent.com/vbuterin/diagrams/master/statetransition.png) - -From a technical standpoint, the ledger of a cryptocurrency such as Bitcoin can be thought of as a state transition system, where there is a "state" consisting of the ownership status of all existing bitcoins and a "state transition function" that takes a state and a transaction and outputs a new state which is the result. In a standard banking system, for example, the state is a balance sheet, a transaction is a request to move $X from A to B, and the state transition function reduces the value in A's account by $X and increases the value in B's account by $X. If A's account has less than $X in the first place, the state transition function returns an error. Hence, one can formally define: - - APPLY(S,TX) -> S' or ERROR - -In the banking system defined above: - - APPLY({ Alice: $50, Bob: $50 },"send $20 from Alice to Bob") = { Alice: $30, Bob: $70 } - -But: - - APPLY({ Alice: $50, Bob: $50 },"send $70 from Alice to Bob") = ERROR - -The "state" in Bitcoin is the collection of all coins (technically, "unspent transaction outputs" or UTXO) that have been minted and not yet spent, with each UTXO having a denomination and an owner (defined by a 20-byte address which is essentially a cryptographic public key[1]). A transaction contains one or more inputs, with each input containing a reference to an existing UTXO and a cryptographic signature produced by the private key associated with the owner's address, and one or more outputs, with each output containing a new UTXO to be added to the state. - -The state transition function `APPLY(S,TX) -> S'` can be defined roughly as follows: - -1. For each input in `TX`: - * If the referenced UTXO is not in `S`, return an error. - * If the provided signature does not match the owner of the UTXO, return an error. -2. If the sum of the denominations of all input UTXO is less than the sum of the denominations of all output UTXO, return an error. -3. Return `S` with all input UTXO removed and all output UTXO added. - -The first half of the first step prevents transaction senders from spending coins that do not exist, the second half of the first step prevents transaction senders from spending other people's coins, and the second step enforces conservation of value. In order to use this for payment, the protocol is as follows. Suppose Alice wants to send 11.7 BTC to Bob. First, Alice will look for a set of available UTXO that she owns that totals up to at least 11.7 BTC. Realistically, Alice will not be able to get exactly 11.7 BTC; say that the smallest she can get is 6+4+2=12. She then creates a transaction with those three inputs and two outputs. The first output will be 11.7 BTC with Bob's address as its owner, and the second output will be the remaining 0.3 BTC "change", with the owner being Alice herself. - -### Mining - -![block_picture.jpg](https://raw.githubusercontent.com/vbuterin/diagrams/master/block.png) - -If we had access to a trustworthy centralized service, this system would be trivial to implement; it could simply be coded exactly as described, using a centralized server's hard drive to keep track of the state. However, with Bitcoin we are trying to build a decentralized currency system, so we will need to combine the state transaction system with a consensus system in order to ensure that everyone agrees on the order of transactions. Bitcoin's decentralized consensus process requires nodes in the network to continuously attempt to produce packages of transactions called "blocks". The network is intended to produce roughly one block every ten minutes, with each block containing a timestamp, a nonce, a reference to (ie. hash of) the previous block and a list of all of the transactions that have taken place since the previous block. Over time, this creates a persistent, ever-growing, "blockchain" that constantly updates to represent the latest state of the Bitcoin ledger. - -The algorithm for checking if a block is valid, expressed in this paradigm, is as follows: - -1. Check if the previous block referenced by the block exists and is valid. -2. Check that the timestamp of the block is greater than that of the previous block[2] and less than 2 hours into the future -3. Check that the proof of work on the block is valid. -4. Let `S[0]` be the state at the end of the previous block. -5. Suppose `TX` is the block's transaction list with `n` transactions. For all `i` in `0...n-1`, set `S[i+1] = APPLY(S[i],TX[i])` If any application returns an error, exit and return false. -6. Return true, and register `S[n]` as the state at the end of this block. - -Essentially, each transaction in the block must provide a valid state transition from what was the canonical state before the transaction was executed to some new state. Note that the state is not encoded in the block in any way; it is purely an abstraction to be remembered by the validating node and can only be (securely) computed for any block by starting from the genesis state and sequentially applying every transaction in every block. Additionally, note that the order in which the miner includes transactions into the block matters; if there are two transactions A and B in a block such that B spends a UTXO created by A, then the block will be valid if A comes before B but not otherwise. - -The one validity condition present in the above list that is not found in other systems is the requirement for "proof of work". The precise condition is that the double-SHA256 hash of every block, treated as a 256-bit number, must be less than a dynamically adjusted target, which as of the time of this writing is approximately 2187. The purpose of this is to make block creation computationally "hard", thereby preventing sybil attackers from remaking the entire blockchain in their favor. Because SHA256 is designed to be a completely unpredictable pseudorandom function, the only way to create a valid block is simply trial and error, repeatedly incrementing the nonce and seeing if the new hash matches. - -At the current target of ~2187, the network must make an average of ~269 tries before a valid block is found; in general, the target is recalibrated by the network every 2016 blocks so that on average a new block is produced by some node in the network every ten minutes. In order to compensate miners for this computational work, the miner of every block is entitled to include a transaction giving themselves 25 BTC out of nowhere. Additionally, if any transaction has a higher total denomination in its inputs than in its outputs, the difference also goes to the miner as a "transaction fee". Incidentally, this is also the only mechanism by which BTC are issued; the genesis state contained no coins at all. - -In order to better understand the purpose of mining, let us examine what happens in the event of a malicious attacker. Since Bitcoin's underlying cryptography is known to be secure, the attacker will target the one part of the Bitcoin system that is not protected by cryptography directly: the order of transactions. The attacker's strategy is simple: - -1. Send 100 BTC to a merchant in exchange for some product (preferably a rapid-delivery digital good) -2. Wait for the delivery of the product -3. Produce another transaction sending the same 100 BTC to himself -4. Try to convince the network that his transaction to himself was the one that came first. - -Once step (1) has taken place, after a few minutes some miner will include the transaction in a block, say block number 270000. After about one hour, five more blocks will have been added to the chain after that block, with each of those blocks indirectly pointing to the transaction and thus "confirming" it. At this point, the merchant will accept the payment as finalized and deliver the product; since we are assuming this is a digital good, delivery is instant. Now, the attacker creates another transaction sending the 100 BTC to himself. If the attacker simply releases it into the wild, the transaction will not be processed; miners will attempt to run `APPLY(S,TX)` and notice that `TX` consumes a UTXO which is no longer in the state. So instead, the attacker creates a "fork" of the blockchain, starting by mining another version of block 270000 pointing to the same block 269999 as a parent but with the new transaction in place of the old one. Because the block data is different, this requires redoing the proof of work. Furthermore, the attacker's new version of block 270000 has a different hash, so the original blocks 270001 to 270005 do not "point" to it; thus, the original chain and the attacker's new chain are completely separate. The rule is that in a fork the longest blockchain is taken to be the truth, and so legitimate miners will work on the 270005 chain while the attacker alone is working on the 270000 chain. In order for the attacker to make his blockchain the longest, he would need to have more computational power than the rest of the network combined in order to catch up (hence, "51% attack"). - -### Merkle Trees - -![SPV in bitcoin](https://raw.githubusercontent.com/ethereum/www/master-postsale/src/extras/gh_wiki/spv_bitcoin.png) - -_Left: it suffices to present only a small number of nodes in a Merkle tree to give a proof of the validity of a branch._ - -_Right: any attempt to change any part of the Merkle tree will eventually lead to an inconsistency somewhere up the chain._ - -An important scalability feature of Bitcoin is that the block is stored in a multi-level data structure. The "hash" of a block is actually only the hash of the block header, a roughly 200-byte piece of data that contains the timestamp, nonce, previous block hash and the root hash of a data structure called the Merkle tree storing all transactions in the block. A Merkle tree is a type of binary tree, composed of a set of nodes with a large number of leaf nodes at the bottom of the tree containing the underlying data, a set of intermediate nodes where each node is the hash of its two children, and finally a single root node, also formed from the hash of its two children, representing the "top" of the tree. The purpose of the Merkle tree is to allow the data in a block to be delivered piecemeal: a node can download only the header of a block from one source, the small part of the tree relevant to them from another source, and still be assured that all of the data is correct. The reason why this works is that hashes propagate upward: if a malicious user attempts to swap in a fake transaction into the bottom of a Merkle tree, this change will cause a change in the node above, and then a change in the node above that, finally changing the root of the tree and therefore the hash of the block, causing the protocol to register it as a completely different block (almost certainly with an invalid proof of work). - -The Merkle tree protocol is arguably essential to long-term sustainability. A "full node" in the Bitcoin network, one that stores and processes the entirety of every block, takes up about 15 GB of disk space in the Bitcoin network as of April 2014, and is growing by over a gigabyte per month. Currently, this is viable for some desktop computers and not phones, and later on in the future only businesses and hobbyists will be able to participate. A protocol known as "simplified payment verification" (SPV) allows for another class of nodes to exist, called "light nodes", which download the block headers, verify the proof of work on the block headers, and then download only the "branches" associated with transactions that are relevant to them. This allows light nodes to determine with a strong guarantee of security what the status of any Bitcoin transaction, and their current balance, is while downloading only a very small portion of the entire blockchain. - -### Alternative Blockchain Applications - -The idea of taking the underlying blockchain idea and applying it to other concepts also has a long history. In 2005, Nick Szabo came out with the concept of "[secure property titles with owner authority](http://szabo.best.vwh.net/securetitle.html)", a document describing how "new advances in replicated database technology" will allow for a blockchain-based system for storing a registry of who owns what land, creating an elaborate framework including concepts such as homesteading, adverse possession and Georgian land tax. However, there was unfortunately no effective replicated database system available at the time, and so the protocol was never implemented in practice. After 2009, however, once Bitcoin's decentralized consensus was developed a number of alternative applications rapidly began to emerge. - -* **Namecoin** - created in 2010, [Namecoin](https://namecoin.org/) is best described as a decentralized name registration database. In decentralized protocols like Tor, Bitcoin and BitMessage, there needs to be some way of identifying accounts so that other people can interact with them, but in all existing solutions the only kind of identifier available is a pseudorandom hash like `1LW79wp5ZBqaHW1jL5TCiBCrhQYtHagUWy`. Ideally, one would like to be able to have an account with a name like "george". However, the problem is that if one person can create an account named "george" then someone else can use the same process to register "george" for themselves as well and impersonate them. The only solution is a first-to-file paradigm, where the first registerer succeeds and the second fails - a problem perfectly suited for the Bitcoin consensus protocol. Namecoin is the oldest, and most successful, implementation of a name registration system using such an idea. -* **Colored coins** - the purpose of [colored coins](https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit) is to serve as a protocol to allow people to create their own digital currencies - or, in the important trivial case of a currency with one unit, digital tokens, on the Bitcoin blockchain. In the colored coins protocol, one "issues" a new currency by publicly assigning a color to a specific Bitcoin UTXO, and the protocol recursively defines the color of other UTXO to be the same as the color of the inputs that the transaction creating them spent (some special rules apply in the case of mixed-color inputs). This allows users to maintain wallets containing only UTXO of a specific color and send them around much like regular bitcoins, backtracking through the blockchain to determine the color of any UTXO that they receive. -* **Metacoins** - the idea behind a metacoin is to have a protocol that lives on top of Bitcoin, using Bitcoin transactions to store metacoin transactions but having a different state transition function, `APPLY'`. Because the metacoin protocol cannot prevent invalid metacoin transactions from appearing in the Bitcoin blockchain, a rule is added that if `APPLY'(S,TX)` returns an error, the protocol defaults to `APPLY'(S,TX) = S`. This provides an easy mechanism for creating an arbitrary cryptocurrency protocol, potentially with advanced features that cannot be implemented inside of Bitcoin itself, but with a very low development cost since the complexities of mining and networking are already handled by the Bitcoin protocol. Metacoins have been used to implement some classes of financial contracts, name registration and decentralized exchange. - -Thus, in general, there are two approaches toward building a consensus protocol: building an independent network, and building a protocol on top of Bitcoin. The former approach, while reasonably successful in the case of applications like Namecoin, is difficult to implement; each individual implementation needs to bootstrap an independent blockchain, as well as building and testing all of the necessary state transition and networking code. Additionally, we predict that the set of applications for decentralized consensus technology will follow a power law distribution where the vast majority of applications would be too small to warrant their own blockchain, and we note that there exist large classes of decentralized applications, particularly decentralized autonomous organizations, that need to interact with each other. - -The Bitcoin-based approach, on the other hand, has the flaw that it does not inherit the simplified payment verification features of Bitcoin. SPV works for Bitcoin because it can use blockchain depth as a proxy for validity; at some point, once the ancestors of a transaction go far enough back, it is safe to say that they were legitimately part of the state. Blockchain-based meta-protocols, on the other hand, cannot force the blockchain not to include transactions that are not valid within the context of their own protocols. Hence, a fully secure SPV meta-protocol implementation would need to backward scan all the way to the beginning of the Bitcoin blockchain to determine whether or not certain transactions are valid. Currently, all "light" implementations of Bitcoin-based meta-protocols rely on a trusted server to provide the data, arguably a highly suboptimal result especially when one of the primary purposes of a cryptocurrency is to eliminate the need for trust. - -### Scripting - -Even without any extensions, the Bitcoin protocol actually does facilitate a weak version of a concept of "smart contracts". UTXO in Bitcoin can be owned not just by a public key, but also by a more complicated script expressed in a simple stack-based programming language. In this paradigm, a transaction spending that UTXO must provide data that satisfies the script. Indeed, even the basic public key ownership mechanism is implemented via a script: the script takes an elliptic curve signature as input, verifies it against the transaction and the address that owns the UTXO, and returns 1 if the verification is successful and 0 otherwise. Other, more complicated, scripts exist for various additional use cases. For example, one can construct a script that requires signatures from two out of a given three private keys to validate ("multisig"), a setup useful for corporate accounts, secure savings accounts and some merchant escrow situations. Scripts can also be used to pay bounties for solutions to computational problems, and one can even construct a script that says something like "this Bitcoin UTXO is yours if you can provide an SPV proof that you sent a Dogecoin transaction of this denomination to me", essentially allowing decentralized cross-cryptocurrency exchange. - -However, the scripting language as implemented in Bitcoin has several important limitations: - -* **Lack of Turing-completeness** - that is to say, while there is a large subset of computation that the Bitcoin scripting language supports, it does not nearly support everything. The main category that is missing is loops. This is done to avoid infinite loops during transaction verification; theoretically it is a surmountable obstacle for script programmers, since any loop can be simulated by simply repeating the underlying code many times with an if statement, but it does lead to scripts that are very space-inefficient. For example, implementing an alternative elliptic curve signature algorithm would likely require 256 repeated multiplication rounds all individually included in the code. -* **Value-blindness** - there is no way for a UTXO script to provide fine-grained control over the amount that can be withdrawn. For example, one powerful use case of an oracle contract would be a hedging contract, where A and B put in $1000 worth of BTC and after 30 days the script sends $1000 worth of BTC to A and the rest to B. This would require an oracle to determine the value of 1 BTC in USD, but even then it is a massive improvement in terms of trust and infrastructure requirement over the fully centralized solutions that are available now. However, because UTXO are all-or-nothing, the only way to achieve this is through the very inefficient hack of having many UTXO of varying denominations (eg. one UTXO of 2k for every k up to 30) and having the oracle pick which UTXO to send to A and which to B. -* **Lack of state** - UTXO can either be spent or unspent; there is no opportunity for multi-stage contracts or scripts which keep any other internal state beyond that. This makes it hard to make multi-stage options contracts, decentralized exchange offers or two-stage cryptographic commitment protocols (necessary for secure computational bounties). It also means that UTXO can only be used to build simple, one-off contracts and not more complex "stateful" contracts such as decentralized organizations, and makes meta-protocols difficult to implement. Binary state combined with value-blindness also mean that another important application, withdrawal limits, is impossible. -* **Blockchain-blindness** - UTXO are blind to blockchain data such as the nonce, the timestamp and previous block hash. This severely limits applications in gambling, and several other categories, by depriving the scripting language of a potentially valuable source of randomness. - -Thus, we see three approaches to building advanced applications on top of cryptocurrency: building a new blockchain, using scripting on top of Bitcoin, and building a meta-protocol on top of Bitcoin. Building a new blockchain allows for unlimited freedom in building a feature set, but at the cost of development time, bootstrapping effort and security. Using scripting is easy to implement and standardize, but is very limited in its capabilities, and meta-protocols, while easy, suffer from faults in scalability. With Ethereum, we intend to build an alternative framework that provides even larger gains in ease of development as well as even stronger light client properties, while at the same time allowing applications to share an economic environment and blockchain security. - -## Ethereum - -The intent of Ethereum is to create an alternative protocol for building decentralized applications, providing a different set of tradeoffs that we believe will be very useful for a large class of decentralized applications, with particular emphasis on situations where rapid development time, security for small and rarely used applications, and the ability of different applications to very efficiently interact, are important. Ethereum does this by building what is essentially the ultimate abstract foundational layer: a blockchain with a built-in Turing-complete programming language, allowing anyone to write smart contracts and decentralized applications where they can create their own arbitrary rules for ownership, transaction formats and state transition functions. A bare-bones version of Namecoin can be written in two lines of code, and other protocols like currencies and reputation systems can be built in under twenty. Smart contracts, cryptographic "boxes" that contain value and only unlock it if certain conditions are met, can also be built on top of the platform, with vastly more power than that offered by Bitcoin scripting because of the added powers of Turing-completeness, value-awareness, blockchain-awareness and state. - -### Ethereum Accounts - -In Ethereum, the state is made up of objects called "accounts", with each account having a 20-byte address and state transitions being direct transfers of value and information between accounts. An Ethereum account contains four fields: - -* The **nonce**, a counter used to make sure each transaction can only be processed once -* The account's current **ether balance** -* The account's **contract code**, if present -* The account's **storage** (empty by default) - -"Ether" is the main internal crypto-fuel of Ethereum, and is used to pay transaction fees. In general, there are two types of accounts: **externally owned accounts**, controlled by private keys, and **contract accounts**, controlled by their contract code. An externally owned account has no code, and one can send messages from an externally owned account by creating and signing a transaction; in a contract account, every time the contract account receives a message its code activates, allowing it to read and write to internal storage and send other messages or create contracts in turn. - -Note that "contracts" in Ethereum should not be seen as something that should be "fulfilled" or "complied with"; rather, they are more like "autonomous agents" that live inside of the Ethereum execution environment, always executing a specific piece of code when "poked" by a message or transaction, and having direct control over their own ether balance and their own key/value store to keep track of persistent variables. - -### Messages and Transactions - -The term "transaction" is used in Ethereum to refer to the signed data package that stores a message to be sent from an externally owned account. Transactions contain: - -* The recipient of the message -* A signature identifying the sender -* The amount of ether to transfer from the sender to the recipient -* An optional data field -* A `STARTGAS` value, representing the maximum number of computational steps the transaction execution is allowed to take -* A `GASPRICE` value, representing the fee the sender pays per computational step - -The first three are standard fields expected in any cryptocurrency. The data field has no function by default, but the virtual machine has an opcode using which a contract can access the data; as an example use case, if a contract is functioning as an on-blockchain domain registration service, then it may wish to interpret the data being passed to it as containing two "fields", the first field being a domain to register and the second field being the IP address to register it to. The contract would read these values from the message data and appropriately place them in storage. - -The `STARTGAS` and `GASPRICE` fields are crucial for Ethereum's anti-denial of service model. In order to prevent accidental or hostile infinite loops or other computational wastage in code, each transaction is required to set a limit to how many computational steps of code execution it can use. The fundamental unit of computation is "gas"; usually, a computational step costs 1 gas, but some operations cost higher amounts of gas because they are more computationally expensive, or increase the amount of data that must be stored as part of the state. There is also a fee of 5 gas for every byte in the transaction data. The intent of the fee system is to require an attacker to pay proportionately for every resource that they consume, including computation, bandwidth and storage; hence, any transaction that leads to the network consuming a greater amount of any of these resources must have a gas fee roughly proportional to the increment. - -### Messages - -Contracts have the ability to send "messages" to other contracts. Messages are virtual objects that are never serialized and exist only in the Ethereum execution environment. A message contains: - -* The sender of the message (implicit) -* The recipient of the message -* The amount of ether to transfer alongside the message -* An optional data field -* A `STARTGAS` value - -Essentially, a message is like a transaction, except it is produced by a contract and not an external actor. A message is produced when a contract currently executing code executes the `CALL` opcode, which produces and executes a message. Like a transaction, a message leads to the recipient account running its code. Thus, contracts can have relationships with other contracts in exactly the same way that external actors can. - -Note that the gas allowance assigned by a transaction or contract applies to the total gas consumed by that transaction and all sub-executions. For example, if an external actor A sends a transaction to B with 1000 gas, and B consumes 600 gas before sending a message to C, and the internal execution of C consumes 300 gas before returning, then B can spend another 100 gas before running out of gas. - -### Ethereum State Transition Function - -![ethertransition.png](https://raw.githubusercontent.com/vbuterin/diagrams/master/ethertransition.png) - -The Ethereum state transition function, `APPLY(S,TX) -> S'` can be defined as follows: - -1. Check if the transaction is well-formed (ie. has the right number of values), the signature is valid, and the nonce matches the nonce in the sender's account. If not, return an error. -2. Calculate the transaction fee as `STARTGAS * GASPRICE`, and determine the sending address from the signature. Subtract the fee from the sender's account balance and increment the sender's nonce. If there is not enough balance to spend, return an error. -3. Initialize `GAS = STARTGAS`, and take off a certain quantity of gas per byte to pay for the bytes in the transaction. -4. Transfer the transaction value from the sender's account to the receiving account. If the receiving account does not yet exist, create it. If the receiving account is a contract, run the contract's code either to completion or until the execution runs out of gas. -5. If the value transfer failed because the sender did not have enough money, or the code execution ran out of gas, revert all state changes except the payment of the fees, and add the fees to the miner's account. -6. Otherwise, refund the fees for all remaining gas to the sender, and send the fees paid for gas consumed to the miner. - -For example, suppose that the contract's code is: - - if !self.storage[calldataload(0)]: - self.storage[calldataload(0)] = calldataload(32) - -Note that in reality the contract code is written in the low-level EVM code; this example is written in Serpent, one of our high-level languages, for clarity, and can be compiled down to EVM code. Suppose that the contract's storage starts off empty, and a transaction is sent with 10 ether value, 2000 gas, 0.001 ether gasprice, and 64 bytes of data, with bytes 0-31 representing the number `2` and bytes 32-63 representing the string `CHARLIE`. The process for the state transition function in this case is as follows: - -1. Check that the transaction is valid and well formed. -2. Check that the transaction sender has at least 2000 * 0.001 = 2 ether. If it is, then subtract 2 ether from the sender's account. -3. Initialize gas = 2000; assuming the transaction is 170 bytes long and the byte-fee is 5, subtract 850 so that there is 1150 gas left. -3. Subtract 10 more ether from the sender's account, and add it to the contract's account. -4. Run the code. In this case, this is simple: it checks if the contract's storage at index `2` is used, notices that it is not, and so it sets the storage at index `2` to the value `CHARLIE`. Suppose this takes 187 gas, so the remaining amount of gas is 1150 - 187 = 963 -5. Add 963 * 0.001 = 0.963 ether back to the sender's account, and return the resulting state. - -If there was no contract at the receiving end of the transaction, then the total transaction fee would simply be equal to the provided `GASPRICE` multiplied by the length of the transaction in bytes, and the data sent alongside the transaction would be irrelevant. - -Note that messages work equivalently to transactions in terms of reverts: if a message execution runs out of gas, then that message's execution, and all other executions triggered by that execution, revert, but parent executions do not need to revert. This means that it is "safe" for a contract to call another contract, as if A calls B with G gas then A's execution is guaranteed to lose at most G gas. Finally, note that there is an opcode, `CREATE`, that creates a contract; its execution mechanics are generally similar to `CALL`, with the exception that the output of the execution determines the code of a newly created contract. - -### Code Execution - -The code in Ethereum contracts is written in a low-level, stack-based bytecode language, referred to as "Ethereum virtual machine code" or "EVM code". The code consists of a series of bytes, where each byte represents an operation. In general, code execution is an infinite loop that consists of repeatedly carrying out the operation at the current program counter (which begins at zero) and then incrementing the program counter by one, until the end of the code is reached or an error or `STOP` or `RETURN` instruction is detected. The operations have access to three types of space in which to store data: - -* The **stack**, a last-in-first-out container to which values can be pushed and popped -* **Memory**, an infinitely expandable byte array -* The contract's long-term **storage**, a key/value store. Unlike stack and memory, which reset after computation ends, storage persists for the long term. - -The code can also access the value, sender and data of the incoming message, as well as block header data, and the code can also return a byte array of data as an output. - -The formal execution model of EVM code is surprisingly simple. While the Ethereum virtual machine is running, its full computational state can be defined by the tuple `(block_state, transaction, message, code, memory, stack, pc, gas)`, where `block_state` is the global state containing all accounts and includes balances and storage. At the start of every round of execution, the current instruction is found by taking the `pc`th byte of `code` (or 0 if `pc >= len(code)`), and each instruction has its own definition in terms of how it affects the tuple. For example, `ADD` pops two items off the stack and pushes their sum, reduces `gas` by 1 and increments `pc` by 1, and `SSTORE` pushes the top two items off the stack and inserts the second item into the contract's storage at the index specified by the first item. Although there are many ways to optimize Ethereum virtual machine execution via just-in-time compilation, a basic implementation of Ethereum can be done in a few hundred lines of code. - -### Blockchain and Mining - -![apply_block_diagram.png](https://raw.githubusercontent.com/vbuterin/diagrams/master/apply_block_diagram.png) - -The Ethereum blockchain is in many ways similar to the Bitcoin blockchain, although it does have some differences. The main difference between Ethereum and Bitcoin with regard to the blockchain architecture is that, unlike Bitcoin, Ethereum blocks contain a copy of both the transaction list and the most recent state. Aside from that, two other values, the block number and the difficulty, are also stored in the block. The basic block validation algorithm in Ethereum is as follows: - -1. Check if the previous block referenced exists and is valid. -2. Check that the timestamp of the block is greater than that of the referenced previous block and less than 15 minutes into the future -3. Check that the block number, difficulty, transaction root, uncle root and gas limit (various low-level Ethereum-specific concepts) are valid. -4. Check that the proof of work on the block is valid. -5. Let `S[0]` be the state at the end of the previous block. -6. Let `TX` be the block's transaction list, with `n` transactions. For all `i` in `0...n-1`, set `S[i+1] = APPLY(S[i],TX[i])`. If any applications returns an error, or if the total gas consumed in the block up until this point exceeds the `GASLIMIT`, return an error. -7. Let `S_FINAL` be `S[n]`, but adding the block reward paid to the miner. -8. Check if the Merkle tree root of the state `S_FINAL` is equal to the final state root provided in the block header. If it is, the block is valid; otherwise, it is not valid. - -The approach may seem highly inefficient at first glance, because it needs to store the entire state with each block, but in reality efficiency should be comparable to that of Bitcoin. The reason is that the state is stored in the tree structure, and after every block only a small part of the tree needs to be changed. Thus, in general, between two adjacent blocks the vast majority of the tree should be the same, and therefore the data can be stored once and referenced twice using pointers (ie. hashes of subtrees). A special kind of tree known as a "Patricia tree" is used to accomplish this, including a modification to the Merkle tree concept that allows for nodes to be inserted and deleted, and not just changed, efficiently. Additionally, because all of the state information is part of the last block, there is no need to store the entire blockchain history - a strategy which, if it could be applied to Bitcoin, can be calculated to provide 5-20x savings in space. - -A commonly asked question is "where" contract code is executed, in terms of physical hardware. This has a simple answer: the process of executing contract code is part of the definition of the state transition function, which is part of the block validation algorithm, so if a transaction is added into block `B` the code execution spawned by that transaction will be executed by all nodes, now and in the future, that download and validate block `B`. - -## Applications - -In general, there are three types of applications on top of Ethereum. The first category is financial applications, providing users with more powerful ways of managing and entering into contracts using their money. This includes sub-currencies, financial derivatives, hedging contracts, savings wallets, wills, and ultimately even some classes of full-scale employment contracts. The second category is semi-financial applications, where money is involved but there is also a heavy non-monetary side to what is being done; a perfect example is self-enforcing bounties for solutions to computational problems. Finally, there are applications such as online voting and decentralized governance that are not financial at all. - -### Token Systems - -On-blockchain token systems have many applications ranging from sub-currencies representing assets such as USD or gold to company stocks, individual tokens representing smart property, secure unforgeable coupons, and even token systems with no ties to conventional value at all, used as point systems for incentivization. Token systems are surprisingly easy to implement in Ethereum. The key point to understand is that all a currency, or token system, fundamentally is a database with one operation: subtract X units from A and give X units to B, with the proviso that (i) A had at least X units before the transaction and (2) the transaction is approved by A. All that it takes to implement a token system is to implement this logic into a contract. - -The basic code for implementing a token system in Serpent looks as follows: - - def send(to, value): - if self.storage[msg.sender] >= value: - self.storage[msg.sender] = self.storage[msg.sender] - value - self.storage[to] = self.storage[to] + value - -This is essentially a literal implementation of the "banking system" state transition function described further above in this document. A few extra lines of code need to be added to provide for the initial step of distributing the currency units in the first place and a few other edge cases, and ideally a function would be added to let other contracts query for the balance of an address. But that's all there is to it. Theoretically, Ethereum-based token systems acting as sub-currencies can potentially include another important feature that on-chain Bitcoin-based meta-currencies lack: the ability to pay transaction fees directly in that currency. The way this would be implemented is that the contract would maintain an ether balance with which it would refund ether used to pay fees to the sender, and it would refill this balance by collecting the internal currency units that it takes in fees and reselling them in a constant running auction. Users would thus need to "activate" their accounts with ether, but once the ether is there it would be reusable because the contract would refund it each time. - -### Financial derivatives and Stable-Value Currencies - -Financial derivatives are the most common application of a "smart contract", and one of the simplest to implement in code. The main challenge in implementing financial contracts is that the majority of them require reference to an external price ticker; for example, a very desirable application is a smart contract that hedges against the volatility of ether (or another cryptocurrency) with respect to the US dollar, but doing this requires the contract to know what the value of ETH/USD is. The simplest way to do this is through a "data feed" contract maintained by a specific party (eg. NASDAQ) designed so that that party has the ability to update the contract as needed, and providing an interface that allows other contracts to send a message to that contract and get back a response that provides the price. - -Given that critical ingredient, the hedging contract would look as follows: - -1. Wait for party A to input 1000 ether. -2. Wait for party B to input 1000 ether. -3. Record the USD value of 1000 ether, calculated by querying the data feed contract, in storage, say this is $x. -4. After 30 days, allow A or B to "reactivate" the contract in order to send $x worth of ether (calculated by querying the data feed contract again to get the new price) to A and the rest to B. - -Such a contract would have significant potential in crypto-commerce. One of the main problems cited about cryptocurrency is the fact that it's volatile; although many users and merchants may want the security and convenience of dealing with cryptographic assets, they many not wish to face that prospect of losing 23% of the value of their funds in a single day. Up until now, the most commonly proposed solution has been issuer-backed assets; the idea is that an issuer creates a sub-currency in which they have the right to issue and revoke units, and provide one unit of the currency to anyone who provides them (offline) with one unit of a specified underlying asset (eg. gold, USD). The issuer then promises to provide one unit of the underlying asset to anyone who sends back one unit of the crypto-asset. This mechanism allows any non-cryptographic asset to be "uplifted" into a cryptographic asset, provided that the issuer can be trusted. - -In practice, however, issuers are not always trustworthy, and in some cases the banking infrastructure is too weak, or too hostile, for such services to exist. Financial derivatives provide an alternative. Here, instead of a single issuer providing the funds to back up an asset, a decentralized market of speculators, betting that the price of a cryptographic reference asset (eg. ETH) will go up, plays that role. Unlike issuers, speculators have no option to default on their side of the bargain because the hedging contract holds their funds in escrow. Note that this approach is not fully decentralized, because a trusted source is still needed to provide the price ticker, although arguably even still this is a massive improvement in terms of reducing infrastructure requirements (unlike being an issuer, issuing a price feed requires no licenses and can likely be categorized as free speech) and reducing the potential for fraud. - -### Identity and Reputation Systems - -The earliest alternative cryptocurrency of all, [Namecoin](http://namecoin.org/), attempted to use a Bitcoin-like blockchain to provide a name registration system, where users can register their names in a public database alongside other data. The major cited use case is for a [DNS](http://en.wikipedia.org/wiki/Domain_Name_System) system, mapping domain names like "bitcoin.org" (or, in Namecoin's case, "bitcoin.bit") to an IP address. Other use cases include email authentication and potentially more advanced reputation systems. Here is the basic contract to provide a Namecoin-like name registration system on Ethereum: - - def register(name, value): - if !self.storage[name]: - self.storage[name] = value - -The contract is very simple; all it is is a database inside the Ethereum network that can be added to, but not modified or removed from. Anyone can register a name with some value, and that registration then sticks forever. A more sophisticated name registration contract will also have a "function clause" allowing other contracts to query it, as well as a mechanism for the "owner" (ie. the first registerer) of a name to change the data or transfer ownership. One can even add reputation and web-of-trust functionality on top. - -### Decentralized File Storage - -Over the past few years, there have emerged a number of popular online file storage startups, the most prominent being Dropbox, seeking to allow users to upload a backup of their hard drive and have the service store the backup and allow the user to access it in exchange for a monthly fee. However, at this point the file storage market is at times relatively inefficient; a cursory look at various [existing solutions](http://online-storage-service-review.toptenreviews.com/) shows that, particularly at the "uncanny valley" 20-200 GB level at which neither free quotas nor enterprise-level discounts kick in, monthly prices for mainstream file storage costs are such that you are paying for more than the cost of the entire hard drive in a single month. Ethereum contracts can allow for the development of a decentralized file storage ecosystem, where individual users can earn small quantities of money by renting out their own hard drives and unused space can be used to further drive down the costs of file storage. - -The key underpinning piece of such a device would be what we have termed the "decentralized Dropbox contract". This contract works as follows. First, one splits the desired data up into blocks, encrypting each block for privacy, and builds a Merkle tree out of it. One then makes a contract with the rule that, every N blocks, the contract would pick a random index in the Merkle tree (using the previous block hash, accessible from contract code, as a source of randomness), and give X ether to the first entity to supply a transaction with a simplified payment verification-like proof of ownership of the block at that particular index in the tree. When a user wants to re-download their file, they can use a micropayment channel protocol (eg. pay 1 szabo per 32 kilobytes) to recover the file; the most fee-efficient approach is for the payer not to publish the transaction until the end, instead replacing the transaction with a slightly more lucrative one with the same nonce after every 32 kilobytes. - -An important feature of the protocol is that, although it may seem like one is trusting many random nodes not to decide to forget the file, one can reduce that risk down to near-zero by splitting the file into many pieces via secret sharing, and watching the contracts to see each piece is still in some node's possession. If a contract is still paying out money, that provides a cryptographic proof that someone out there is still storing the file. - -### Decentralized Autonomous Organizations - -The general concept of a "decentralized autonomous organization" is that of a virtual entity that has a certain set of members or shareholders which, perhaps with a 67% majority, have the right to spend the entity's funds and modify its code. The members would collectively decide on how the organization should allocate its funds. Methods for allocating a DAO's funds could range from bounties, salaries to even more exotic mechanisms such as an internal currency to reward work. This essentially replicates the legal trappings of a traditional company or nonprofit but using only cryptographic blockchain technology for enforcement. So far much of the talk around DAOs has been around the "capitalist" model of a "decentralized autonomous corporation" (DAC) with dividend-receiving shareholders and tradable shares; an alternative, perhaps described as a "decentralized autonomous community", would have all members have an equal share in the decision making and require 67% of existing members to agree to add or remove a member. The requirement that one person can only have one membership would then need to be enforced collectively by the group. - -A general outline for how to code a DAO is as follows. The simplest design is simply a piece of self-modifying code that changes if two thirds of members agree on a change. Although code is theoretically immutable, one can easily get around this and have de-facto mutability by having chunks of the code in separate contracts, and having the address of which contracts to call stored in the modifiable storage. In a simple implementation of such a DAO contract, there would be three transaction types, distinquished by the data provided in the transaction: - -* `[0,i,K,V]` to register a proposal with index `i` to change the address at storage index `K` to value `V` -* `[0,i]` to register a vote in favor of proposal `i` -* `[2,i]` to finalize proposal `i` if enough votes have been made - -The contract would then have clauses for each of these. It would maintain a record of all open storage changes, along with a list of who voted for them. It would also have a list of all members. When any storage change gets to two thirds of members voting for it, a finalizing transaction could execute the change. A more sophisticated skeleton would also have built-in voting ability for features like sending a transaction, adding members and removing members, and may even provide for [Liquid Democracy](http://en.wikipedia.org/wiki/Delegative_democracy)-style vote delegation (ie. anyone can assign someone to vote for them, and assignment is transitive so if A assigns B and B assigns C then C determines A's vote). This design would allow the DAO to grow organically as a decentralized community, allowing people to eventually delegate the task of filtering out who is a member to specialists, although unlike in the "current system" specialists can easily pop in and out of existence over time as individual community members change their alignments. - -An alternative model is for a decentralized corporation, where any account can have zero or more shares, and two thirds of the shares are required to make a decision. A complete skeleton would involve asset management functionality, the ability to make an offer to buy or sell shares, and the ability to accept offers (preferably with an order-matching mechanism inside the contract). Delegation would also exist Liquid Democracy-style, generalizing the concept of a "board of directors". - -### Further Applications - -**1. Savings wallets**. Suppose that Alice wants to keep her funds safe, but is worried that she will lose or someone will hack her private key. She puts ether into a contract with Bob, a bank, as follows: - -* Alice alone can withdraw a maximum of 1% of the funds per day. -* Bob alone can withdraw a maximum of 1% of the funds per day, but Alice has the ability to make a transaction with her key shutting off this ability. -* Alice and Bob together can withdraw anything. - -Normally, 1% per day is enough for Alice, and if Alice wants to withdraw more she can contact Bob for help. If Alice's key gets hacked, she runs to Bob to move the funds to a new contract. If she loses her key, Bob will get the funds out eventually. If Bob turns out to be malicious, then she can turn off his ability to withdraw. - -**2. Crop insurance**. One can easily make a financial derivatives contract but using a data feed of the weather instead of any price index. If a farmer in Iowa purchases a derivative that pays out inversely based on the precipitation in Iowa, then if there is a drought, the farmer will automatically receive money and if there is enough rain the farmer will be happy because their crops would do well. This can be expanded to natural disaster insurance generally. - -**3. A decentralized data feed**. For financial contracts for difference, it may actually be possible to decentralize the data feed via a protocol called "[SchellingCoin](http://blog.ethereum.org/2014/03/28/schellingcoin-a-minimal-trust-universal-data-feed/)". SchellingCoin basically works as follows: N parties all put into the system the value of a given datum (eg. the ETH/USD price), the values are sorted, and everyone between the 25th and 75th percentile gets one token as a reward. Everyone has the incentive to provide the answer that everyone else will provide, and the only value that a large number of players can realistically agree on is the obvious default: the truth. This creates a decentralized protocol that can theoretically provide any number of values, including the ETH/USD price, the temperature in Berlin or even the result of a particular hard computation. - -**4. Smart multisignature escrow**. Bitcoin allows multisignature transaction contracts where, for example, three out of a given five keys can spend the funds. Ethereum allows for more granularity; for example, four out of five can spend everything, three out of five can spend up to 10% per day, and two out of five can spend up to 0.5% per day. Additionally, Ethereum multisig is asynchronous - two parties can register their signatures on the blockchain at different times and the last signature will automatically send the transaction. - -**5. Cloud computing**. The EVM technology can also be used to create a verifiable computing environment, allowing users to ask others to carry out computations and then optionally ask for proofs that computations at certain randomly selected checkpoints were done correctly. This allows for the creation of a cloud computing market where any user can participate with their desktop, laptop or specialized server, and spot-checking together with security deposits can be used to ensure that the system is trustworthy (ie. nodes cannot profitably cheat). Although such a system may not be suitable for all tasks; tasks that require a high level of inter-process communication, for example, cannot easily be done on a large cloud of nodes. Other tasks, however, are much easier to parallelize; projects like SETI@home, folding@home and genetic algorithms can easily be implemented on top of such a platform. - -**6. Peer-to-peer gambling**. Any number of peer-to-peer gambling protocols, such as Frank Stajano and Richard Clayton's [Cyberdice](http://www.cl.cam.ac.uk/~fms27/papers/2008-StajanoCla-cyberdice.pdf), can be implemented on the Ethereum blockchain. The simplest gambling protocol is actually simply a contract for difference on the next block hash, and more advanced protocols can be built up from there, creating gambling services with near-zero fees that have no ability to cheat. - -**7. Prediction markets**. Provided an oracle or SchellingCoin, prediction markets are also easy to implement, and prediction markets together with SchellingCoin may prove to be the first mainstream application of [futarchy](http://hanson.gmu.edu/futarchy.html) as a governance protocol for decentralized organizations. - -**8. On-chain decentralized marketplaces**, using the identity and reputation system as a base. - -## Miscellanea And Concerns - -### Modified GHOST Implementation - -The "Greedy Heaviest Observed Subtree" (GHOST) protocol is an innovation first introduced by Yonatan Sompolinsky and Aviv Zohar in [December 2013](http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf). The motivation behind GHOST is that blockchains with fast confirmation times currently suffer from reduced security due to a high stale rate - because blocks take a certain time to propagate through the network, if miner A mines a block and then miner B happens to mine another block before miner A's block propagates to B, miner B's block will end up wasted and will not contribute to network security. Furthermore, there is a centralization issue: if miner A is a mining pool with 30% hashpower and B has 10% hashpower, A will have a risk of producing a stale block 70% of the time (since the other 30% of the time A produced the last block and so will get mining data immediately) whereas B will have a risk of producing a stale block 90% of the time. Thus, if the block interval is short enough for the stale rate to be high, A will be substantially more efficient simply by virtue of its size. With these two effects combined, blockchains which produce blocks quickly are very likely to lead to one mining pool having a large enough percentage of the network hashpower to have de facto control over the mining process. - -As described by Sompolinsky and Zohar, GHOST solves the first issue of network security loss by including stale blocks in the calculation of which chain is the "longest"; that is to say, not just the parent and further ancestors of a block, but also the stale descendants of the block's ancestor (in Ethereum jargon, "uncles") are added to the calculation of which block has the largest total proof of work backing it. To solve the second issue of centralization bias, we go beyond the protocol described by Sompolinsky and Zohar, and also provide block rewards to stales: a stale block receives 87.5% of its base reward, and the nephew that includes the stale block receives the remaining 12.5%. Transaction fees, however, are not awarded to uncles. - -Ethereum implements a simplified version of GHOST which only goes down seven levels. Specifically, it is defined as follows: - -* A block must specify a parent, and it must specify 0 or more uncles -* An uncle included in block `B` must have the following properties: - * It must be a direct child of the `k`-th generation ancestor of `B`, where `2 <= k <= 7`. - * It cannot be an ancestor of `B` - * An uncle must be a valid block header, but does not need to be a previously verified or even valid block - * An uncle must be different from all uncles included in previous blocks and all other uncles included in the same block (non-double-inclusion) -* For every uncle `U` in block `B`, the miner of `B` gets an additional 3.125% added to its coinbase reward and the miner of `U` gets 93.75% of a standard coinbase reward. - -This limited version of GHOST, with uncles includable only up to 7 generations, was used for two reasons. First, unlimited GHOST would include too many complications into the calculation of which uncles for a given block are valid. Second, unlimited GHOST with compensation as used in Ethereum removes the incentive for a miner to mine on the main chain and not the chain of a public attacker. - -### Fees - -Because every transaction published into the blockchain imposes on the network the cost of needing to download and verify it, there is a need for some regulatory mechanism, typically involving transaction fees, to prevent abuse. The default approach, used in Bitcoin, is to have purely voluntary fees, relying on miners to act as the gatekeepers and set dynamic minimums. This approach has been received very favorably in the Bitcoin community particularly because it is "market-based", allowing supply and demand between miners and transaction senders determine the price. The problem with this line of reasoning is, however, that transaction processing is not a market; although it is intuitively attractive to construe transaction processing as a service that the miner is offering to the sender, in reality every transaction that a miner includes will need to be processed by every node in the network, so the vast majority of the cost of transaction processing is borne by third parties and not the miner that is making the decision of whether or not to include it. Hence, tragedy-of-the-commons problems are very likely to occur. - -However, as it turns out this flaw in the market-based mechanism, when given a particular inaccurate simplifying assumption, magically cancels itself out. The argument is as follows. Suppose that: - -1. A transaction leads to `k` operations, offering the reward `kR` to any miner that includes it where `R` is set by the sender and `k` and `R` are (roughly) visible to the miner beforehand. -2. An operation has a processing cost of `C` to any node (ie. all nodes have equal efficiency) -3. There are `N` mining nodes, each with exactly equal processing power (ie. `1/N` of total) -4. No non-mining full nodes exist. - -A miner would be willing to process a transaction if the expected reward is greater than the cost. Thus, the expected reward is `kR/N` since the miner has a `1/N` chance of processing the next block, and the processing cost for the miner is simply `kC`. Hence, miners will include transactions where `kR/N > kC`, or `R > NC`. Note that `R` is the per-operation fee provided by the sender, and is thus a lower bound on the benefit that the sender derives from the transaction, and `NC` is the cost to the entire network together of processing an operation. Hence, miners have the incentive to include only those transactions for which the total utilitarian benefit exceeds the cost. - -However, there are several important deviations from those assumptions in reality: - -1. The miner does pay a higher cost to process the transaction than the other verifying nodes, since the extra verification time delays block propagation and thus increases the chance the block will become a stale. -2. There do exist nonmining full nodes. -3. The mining power distribution may end up radically inegalitarian in practice. -4. Speculators, political enemies and crazies whose utility function includes causing harm to the network do exist, and they can cleverly set up contracts where their cost is much lower than the cost paid by other verifying nodes. - -(1) provides a tendency for the miner to include fewer transactions, and (2) increases `NC`; hence, these two effects at least partially cancel each other out. (3) and (4) are the major issue; to solve them we simply institute a floating cap: no block can have more operations than `BLK_LIMIT_FACTOR` times the long-term exponential moving average. Specifically: - - blk.oplimit = floor((blk.parent.oplimit * (EMA_FACTOR - 1) + floor(parent.opcount * BLK_LIMIT_FACTOR)) / EMA_FACTOR) - -`BLK_LIMIT_FACTOR` and `EMA_FACTOR` are constants that will be set to 65536 and 1.5 for the time being, but will likely be changed after further analysis. - -There is another factor disincentivizing large block sizes in Bitcoin: blocks that are large will take longer to propagate, and thus have a higher probability of becoming stales. In Ethereum, highly gas-consuming blocks can also take longer to propagate both because they are physically larger and because they take longer to process the transaction state transitions to validate. This delay disincentive is a significant consideration in Bitcoin, but less so in Ethereum because of the GHOST protocol; hence, relying on regulated block limits provides a more stable baseline. - -### Computation And Turing-Completeness - -An important note is that the Ethereum virtual machine is Turing-complete; this means that EVM code can encode any computation that can be conceivably carried out, including infinite loops. EVM code allows looping in two ways. First, there is a `JUMP` instruction that allows the program to jump back to a previous spot in the code, and a `JUMPI` instruction to do conditional jumping, allowing for statements like `while x < 27: x = x * 2`. Second, contracts can call other contracts, potentially allowing for looping through recursion. This naturally leads to a problem: can malicious users essentially shut miners and full nodes down by forcing them to enter into an infinite loop? The issue arises because of a problem in computer science known as the halting problem: there is no way to tell, in the general case, whether or not a given program will ever halt. - -As described in the state transition section, our solution works by requiring a transaction to set a maximum number of computational steps that it is allowed to take, and if execution takes longer computation is reverted but fees are still paid. Messages work in the same way. To show the motivation behind our solution, consider the following examples: - -* An attacker creates a contract which runs an infinite loop, and then sends a transaction activating that loop to the miner. The miner will process the transaction, running the infinite loop, and wait for it to run out of gas. Even though the execution runs out of gas and stops halfway through, the transaction is still valid and the miner still claims the fee from the attacker for each computational step. -* An attacker creates a very long infinite loop with the intent of forcing the miner to keep computing for such a long time that by the time computation finishes a few more blocks will have come out and it will not be possible for the miner to include the transaction to claim the fee. However, the attacker will be required to submit a value for `STARTGAS` limiting the number of computational steps that execution can take, so the miner will know ahead of time that the computation will take an excessively large number of steps. -* An attacker sees a contract with code of some form like `send(A,contract.storage[A]); contract.storage[A] = 0`, and sends a transaction with just enough gas to run the first step but not the second (ie. making a withdrawal but not letting the balance go down). The contract author does not need to worry about protecting against such attacks, because if execution stops halfway through the changes get reverted. -* A financial contract works by taking the median of nine proprietary data feeds in order to minimize risk. An attacker takes over one of the data feeds, which is designed to be modifiable via the variable-address-call mechanism described in the section on DAOs, and converts it to run an infinite loop, thereby attempting to force any attempts to claim funds from the financial contract to run out of gas. However, the financial contract can set a gas limit on the message to prevent this problem. - -The alternative to Turing-completeness is Turing-incompleteness, where `JUMP` and `JUMPI` do not exist and only one copy of each contract is allowed to exist in the call stack at any given time. With this system, the fee system described and the uncertainties around the effectiveness of our solution might not be necessary, as the cost of executing a contract would be bounded above by its size. Additionally, Turing-incompleteness is not even that big a limitation; out of all the contract examples we have conceived internally, so far only one required a loop, and even that loop could be removed by making 26 repetitions of a one-line piece of code. Given the serious implications of Turing-completeness, and the limited benefit, why not simply have a Turing-incomplete language? In reality, however, Turing-incompleteness is far from a neat solution to the problem. To see why, consider the following contracts: - - C0: call(C1); call(C1); - C1: call(C2); call(C2); - C2: call(C3); call(C3); - ... - C49: call(C50); call(C50); - C50: (run one step of a program and record the change in storage) - -Now, send a transaction to A. Thus, in 51 transactions, we have a contract that takes up 250 computational steps. Miners could try to detect such logic bombs ahead of time by maintaining a value alongside each contract specifying the maximum number of computational steps that it can take, and calculating this for contracts calling other contracts recursively, but that would require miners to forbid contracts that create other contracts (since the creation and execution of all 26 contracts above could easily be rolled into a single contract). Another problematic point is that the address field of a message is a variable, so in general it may not even be possible to tell which other contracts a given contract will call ahead of time. Hence, all in all, we have a surprising conclusion: Turing-completeness is surprisingly easy to manage, and the lack of Turing-completeness is equally surprisingly difficult to manage unless the exact same controls are in place - but in that case why not just let the protocol be Turing-complete? - -### Currency And Issuance - -The Ethereum network includes its own built-in currency, ether, which serves the dual purpose of providing a primary liquidity layer to allow for efficient exchange between various types of digital assets and, more importantly, of providing a mechanism for paying transaction fees. For convenience and to avoid future argument (see the current mBTC/uBTC/satoshi debate in Bitcoin), the denominations will be pre-labelled: - -* 1: wei -* 1012: szabo -* 1015: finney -* 1018: ether - -This should be taken as an expanded version of the concept of "dollars" and "cents" or "BTC" and "satoshi". In the near future, we expect "ether" to be used for ordinary transactions, "finney" for microtransactions and "szabo" and "wei" for technical discussions around fees and protocol implementation; the remaining denominations may become useful later and should not be included in clients at this point. - -The issuance model will be as follows: - -* Ether will be released in a currency sale at the price of 1000-2000 ether per BTC, a mechanism intended to fund the Ethereum organization and pay for development that has been used with success by other platforms such as Mastercoin and NXT. Earlier buyers will benefit from larger discounts. The BTC received from the sale will be used entirely to pay salaries and bounties to developers and invested into various for-profit and non-profit projects in the Ethereum and cryptocurrency ecosystem. -* 0.099x the total amount sold (60102216 ETH) will be allocated to the organization to compensate early contributors and pay ETH-denominated expenses before the genesis block. -* 0.099x the total amount sold will be maintained as a long-term reserve. -* 0.26x the total amount sold will be allocated to miners per year forever after that point. - -| Group | At launch | After 1 year | After 5 years -| ------------- | ------------- |-------------| ----------- | -| Currency units | 1.198X | 1.458X | 2.498X | -| Purchasers | 83.5% | 68.6% | 40.0% | -| Reserve spent pre-sale | 8.26% | 6.79% | 3.96% | -| Reserve used post-sale | 8.26% | 6.79% | 3.96% | -| Miners | 0% | 17.8% | 52.0% | - -**Long-Term Supply Growth Rate (percent)** - -_Despite the linear currency issuance, just like with Bitcoin over time the supply growth rate nevertheless tends to zero_ - -The two main choices in the above model are (1) the existence and size of an endowment pool, and (2) the existence of a permanently growing linear supply, as opposed to a capped supply as in Bitcoin. The justification of the endowment pool is as follows. If the endowment pool did not exist, and the linear issuance reduced to 0.217x to provide the same inflation rate, then the total quantity of ether would be 16.5% less and so each unit would be 19.8% more valuable. Hence, in the equilibrium 19.8% more ether would be purchased in the sale, so each unit would once again be exactly as valuable as before. The organization would also then have 1.198x as much BTC, which can be considered to be split into two slices: the original BTC, and the additional 0.198x. Hence, this situation is _exactly equivalent_ to the endowment, but with one important difference: the organization holds purely BTC, and so is not incentivized to support the value of the ether unit. - -The permanent linear supply growth model reduces the risk of what some see as excessive wealth concentration in Bitcoin, and gives individuals living in present and future eras a fair chance to acquire currency units, while at the same time retaining a strong incentive to obtain and hold ether because the "supply growth rate" as a percentage still tends to zero over time. We also theorize that because coins are always lost over time due to carelessness, death, etc, and coin loss can be modeled as a percentage of the total supply per year, that the total currency supply in circulation will in fact eventually stabilize at a value equal to the annual issuance divided by the loss rate (eg. at a loss rate of 1%, once the supply reaches 26X then 0.26X will be mined and 0.26X lost every year, creating an equilibrium). - -Note that in the future, it is likely that Ethereum will switch to a proof-of-stake model for security, reducing the issuance requirement to somewhere between zero and 0.05X per year. In the event that the Ethereum organization loses funding or for any other reason disappears, we leave open a "social contract": anyone has the right to create a future candidate version of Ethereum, with the only condition being that the quantity of ether must be at most equal to `60102216 * (1.198 + 0.26 * n)` where `n` is the number of years after the genesis block. Creators are free to crowd-sell or otherwise assign some or all of the difference between the PoS-driven supply expansion and the maximum allowable supply expansion to pay for development. Candidate upgrades that do not comply with the social contract may justifiably be forked into compliant versions. - -### Mining Centralization - -The Bitcoin mining algorithm works by having miners compute SHA256 on slightly modified versions of the block header millions of times over and over again, until eventually one node comes up with a version whose hash is less than the target (currently around 2192). However, this mining algorithm is vulnerable to two forms of centralization. First, the mining ecosystem has come to be dominated by ASICs (application-specific integrated circuits), computer chips designed for, and therefore thousands of times more efficient at, the specific task of Bitcoin mining. This means that Bitcoin mining is no longer a highly decentralized and egalitarian pursuit, requiring millions of dollars of capital to effectively participate in. Second, most Bitcoin miners do not actually perform block validation locally; instead, they rely on a centralized mining pool to provide the block headers. This problem is arguably worse: as of the time of this writing, the top three mining pools indirectly control roughly 50% of processing power in the Bitcoin network, although this is mitigated by the fact that miners can switch to other mining pools if a pool or coalition attempts a 51% attack. - -The current intent at Ethereum is to use a mining algorithm where miners are required to fetch random data from the state, compute some randomly selected transactions from the last N blocks in the blockchain, and return the hash of the result. This has two important benefits. First, Ethereum contracts can include any kind of computation, so an Ethereum ASIC would essentially be an ASIC for general computation - ie. a better CPU. Second, mining requires access to the entire blockchain, forcing miners to store the entire blockchain and at least be capable of verifying every transaction. This removes the need for centralized mining pools; although mining pools can still serve the legitimate role of evening out the randomness of reward distribution, this function can be served equally well by peer-to-peer pools with no central control. - -This model is untested, and there may be difficulties along the way in avoiding certain clever optimizations when using contract execution as a mining algorithm. However, one notably interesting feature of this algorithm is that it allows anyone to "poison the well", by introducing a large number of contracts into the blockchain specifically designed to stymie certain ASICs. The economic incentives exist for ASIC manufacturers to use such a trick to attack each other. Thus, the solution that we are developing is ultimately an adaptive economic human solution rather than purely a technical one. - -### Scalability - -One common concern about Ethereum is the issue of scalability. Like Bitcoin, Ethereum suffers from the flaw that every transaction needs to be processed by every node in the network. With Bitcoin, the size of the current blockchain rests at about 15 GB, growing by about 1 MB per hour. If the Bitcoin network were to process Visa's 2000 transactions per second, it would grow by 1 MB per three seconds (1 GB per hour, 8 TB per year). Ethereum is likely to suffer a similar growth pattern, worsened by the fact that there will be many applications on top of the Ethereum blockchain instead of just a currency as is the case with Bitcoin, but ameliorated by the fact that Ethereum full nodes need to store just the state instead of the entire blockchain history. - -The problem with such a large blockchain size is centralization risk. If the blockchain size increases to, say, 100 TB, then the likely scenario would be that only a very small number of large businesses would run full nodes, with all regular users using light SPV nodes. In such a situation, there arises the potential concern that the full nodes could band together and all agree to cheat in some profitable fashion (eg. change the block reward, give themselves BTC). Light nodes would have no way of detecting this immediately. Of course, at least one honest full node would likely exist, and after a few hours information about the fraud would trickle out through channels like Reddit, but at that point it would be too late: it would be up to the ordinary users to organize an effort to blacklist the given blocks, a massive and likely infeasible coordination problem on a similar scale as that of pulling off a successful 51% attack. In the case of Bitcoin, this is currently a problem, but there exists a blockchain modification [suggested by Peter Todd](https://web.archive.org/web/20140623061815/http://sourceforge.net/p/bitcoin/mailman/message/31709140/) which will alleviate this issue. - -In the near term, Ethereum will use two additional strategies to cope with this problem. First, because of the blockchain-based mining algorithms, at least every miner will be forced to be a full node, creating a lower bound on the number of full nodes. Second and more importantly, however, we will include an intermediate state tree root in the blockchain after processing each transaction. Even if block validation is centralized, as long as one honest verifying node exists, the centralization problem can be circumvented via a verification protocol. If a miner publishes an invalid block, that block must either be badly formatted, or the state `S[n]` is incorrect. Since `S[0]` is known to be correct, there must be some first state `S[i]` that is incorrect where `S[i-1]` is correct. The verifying node would provide the index `i`, along with a "proof of invalidity" consisting of the subset of Patricia tree nodes needing to process `APPLY(S[i-1],TX[i]) -> S[i]`. Nodes would be able to use those nodes to run that part of the computation, and see that the `S[i]` generated does not match the `S[i]` provided. - -Another, more sophisticated, attack would involve the malicious miners publishing incomplete blocks, so the full information does not even exist to determine whether or not blocks are valid. The solution to this is a challenge-response protocol: verification nodes issue "challenges" in the form of target transaction indices, and upon receiving a node a light node treats the block as untrusted until another node, whether the miner or another verifier, provides a subset of Patricia nodes as a proof of validity. - -## Conclusion - -The Ethereum protocol was originally conceived as an upgraded version of a cryptocurrency, providing advanced features such as on-blockchain escrow, withdrawal limits, financial contracts, gambling markets and the like via a highly generalized programming language. The Ethereum protocol would not "support" any of the applications directly, but the existence of a Turing-complete programming language means that arbitrary contracts can theoretically be created for any transaction type or application. What is more interesting about Ethereum, however, is that the Ethereum protocol moves far beyond just currency. Protocols around decentralized file storage, decentralized computation and decentralized prediction markets, among dozens of other such concepts, have the potential to substantially increase the efficiency of the computational industry, and provide a massive boost to other peer-to-peer protocols by adding for the first time an economic layer. Finally, there is also a substantial array of applications that have nothing to do with money at all. - -The concept of an arbitrary state transition function as implemented by the Ethereum protocol provides for a platform with unique potential; rather than being a closed-ended, single-purpose protocol intended for a specific array of applications in data storage, gambling or finance, Ethereum is open-ended by design, and we believe that it is extremely well-suited to serving as a foundational layer for a very large number of both financial and non-financial protocols in the years to come. - -## Notes and Further Reading - -#### Notes - -1. A sophisticated reader may notice that in fact a Bitcoin address is the hash of the elliptic curve public key, and not the public key itself. However, it is in fact perfectly legitimate cryptographic terminology to refer to the pubkey hash as a public key itself. This is because Bitcoin's cryptography can be considered to be a custom digital signature algorithm, where the public key consists of the hash of the ECC pubkey, the signature consists of the ECC pubkey concatenated with the ECC signature, and the verification algorithm involves checking the ECC pubkey in the signature against the ECC pubkey hash provided as a public key and then verifying the ECC signature against the ECC pubkey. -2. Technically, the median of the 11 previous blocks. -3. Internally, 2 and "CHARLIE" are both numbers, with the latter being in big-endian base 256 representation. Numbers can be at least 0 and at most 2256-1. - -#### Further Reading - -1. Intrinsic value: http://bitcoinmagazine.com/8640/an-exploration-of-intrinsic-value-what-it-is-why-bitcoin-doesnt-have-it-and-why-bitcoin-does-have-it/ -2. Smart property: https://en.bitcoin.it/wiki/Smart_Property -3. Smart contracts: https://en.bitcoin.it/wiki/Contracts -4. B-money: http://www.weidai.com/bmoney.txt -5. Reusable proofs of work: http://www.finney.org/~hal/rpow/ -6. Secure property titles with owner authority: http://szabo.best.vwh.net/securetitle.html -7. Bitcoin whitepaper: http://bitcoin.org/bitcoin.pdf -8. Namecoin: https://namecoin.org/ -9. Zooko's triangle: http://en.wikipedia.org/wiki/Zooko's_triangle -10. Colored coins whitepaper: https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit -11. Mastercoin whitepaper: https://github.com/mastercoin-MSC/spec -12. Decentralized autonomous corporations, Bitcoin Magazine: http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/ -13. Simplified payment verification: https://en.bitcoin.it/wiki/Scalability#Simplifiedpaymentverification -14. Merkle trees: http://en.wikipedia.org/wiki/Merkle_tree -15. Patricia trees: http://en.wikipedia.org/wiki/Patricia_tree -16. GHOST: http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf -17. StorJ and Autonomous Agents, Jeff Garzik: http://garzikrants.blogspot.ca/2013/01/storj-and-bitcoin-autonomous-agents.html -18. Mike Hearn on Smart Property at Turing Festival: http://www.youtube.com/watch?v=Pu4PAMFPo5Y -19. Ethereum RLP: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP -20. Ethereum Merkle Patricia trees: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree -21. Peter Todd on Merkle sum trees: http://sourceforge.net/p/bitcoin/mailman/message/31709140/ diff --git a/pages/white-paper/[german]-white-paper.md b/pages/white-paper/[german]-white-paper.md deleted file mode 100644 index 6c12efa95..000000000 --- a/pages/white-paper/[german]-white-paper.md +++ /dev/null @@ -1,630 +0,0 @@ ---- -name: White Paper -category: ---- - -### Ethereum: Die nächste Generation elektronischer Verträge und die Plattform für dezentrale Anwendungen - -Als Satoshi Nakamoto Anfang 2009 zum ersten Mal die Bitcoin-Blockchain in Gang setzte stellte er mit dieser Veröffentlichung zwei fundamentale und bislang ungetestete Konzepte vor. Das erste Konzept ist „Bitcoin“, eine dezentrale Peer-to-Peer Onlinewährung, die ihren Wert behält, obwohl sie durch nichts hinterlegt ist, keinen intrinsischen Wert besitzt und von keiner zentralen Instanz herausgegeben wird. Bis jetzt hat Bitcoin als Währung den Großteil der öffentlichen Aufmerksamkeit auf sich gezogen. Vor allem die politischen Aspekte einer Währung ohne herausgebende Zentralbank als auch die extreme Volatilität der Bitcoins sorgten für medialen Aufruhr. Satoshis großartiges Experiment beinhaltet jedoch ein zweites, ebenso wichtiges Konzept: Die Idee einer auf Proof-of-Work basierenden Blockchain, die es erlaubt, allgemeine Übereinstimmung über die Reihenfolge von Transaktionen zu finden. Anwendungstechnisch kann Bitcoin als First-to-File System beschrieben werden. Wenn beispielsweise Instanz A 50 BTC besitzt und diese gleichzeitig an Instanz B und C versendet wird nur diejenige Transaktion verarbeitet, die zuerst bestätigt wird. Die Problemstellung, dass es keinen inhärenten Weg gibt um festzustellen, welche Transaktion zuerst ausgeführt wurde, behinderte jahrzzehntelang die Entwicklung eines dezentralen digitalen Zahlungsmittels. Satoshis Blockchain ist die erste ernstzunehmende dezentrale Lösung. Nun ist der Zeitpunkt erreicht, an dem sich das öffentliche Interesse immer mehr diesem zweiten Teil der Bitcoin-Technologie zuwendet. Die zentrale Frage lautet, wie das Konzept der Blockchain für Anwendungen abseits einer reinen Währung verwendet werden kann. - -In den letzten Monaten war ein großes Interesse an der Verwendung von Blockketten (wie beim Bitcoin) zu verzeichnen, die einen Mechanismus darstellen, der es der ganzen Welt erlaubt, sich über den Status von Dingen in einer öffentlichen Eigentumsdatenbank einig zu sein - und das für mehr Dinge als nur für Geld. -Die am häufigsten genannten Anwendungen bei der Nutzung von Online-Blockketten sind - -* digitale Wertanlagen, wie benutzerdefinierte Währungen oder Finanzinstrumente ("Farbige Münzen / Colored Coins"), -* "Elektronische Besitzstände / smart property" Dinge wie Autos, die einen "Colored Coin" in der Blockkette verfolgen, um den gegenwärtigen legitimen Besitzer festzustellen, -* erweiterte Anwendungen wie dezentrale Tauschbörsen, Finanzderivate, Peer-to-Peer-Glücksspiele, -* Online-Blockketten basierte Identitätsnachweise und Reputationssysteme. - -Die möglicherweise ambitionierteste aller Anwendungen ist das Konzept der autonomen Vermittlung oder die [Dezentrale Autonome Organisation] (http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/) (DAO) - autonome Instanzen, die auf Basis der Blockchain ohne jegliche zentrale Kontrolle und unter Verzicht auf alle Abhängigkeit von Rechtsverträgen und Organisationssatzungen operieren. *?Und dies zu Gunsten / zu Lasten von Ressourcen und Mitteln?*...autonom verwaltet durch Selbstregulierung der "Smart-Contracts" auf Basis einer kryptografischen Blockkette. - -Wie auch immer, die meisten derartiger Anwendungen sind heute schwierig zu implementieren, einfach wegen der Programmsprache des Bitcoin. Gerade die Protokolle der Kryptowährungen der nächsten Generation wie das Bitcoin-basierte Protokoll der "Colored Coins", auch "Metacoins" genannt, sind viel zu eingeschränkt, um diese Art von beliebig komplexen Berechnungen, wie sie für DAOs nötig sind, zu erlauben. - -Was dieses Projekt zu tun beabsichtigt, ist sich der Innovationen zu bedienen, die solche Protokolle mit sich bringen, sie zu vereinheitlichen, -einen vollwertigen *?TURING -vervollständigt?* (aber stark gebührenregulierten) kryptographischen Registers zu erstellen, welches es den Beteiligten erlaubt, beliebig komplexe Verträge, autonome Vermittlungen und Beziehungen zu kodieren, die vollständig über der Blockkette ausgehandelt werden. -Anstatt sich auf einen bestimmten Satz von Transaktionstypen zu beschränken, werden die Nutzer in der Lage sein, Ethereum wie eine Art "Lego für Krypto-Finanzsysteme" zu verwenden. Das heißt man wird in die Lage versetzt, jedes Leistungsmerkmal einfach durch Codierung mit der internen Skriptsprache des Protokolls zu implementieren. -Kundenspezifische Währungen, Finanzderivate, Identitätssysteme und dezentralisierte Organisationen werden einfach machbar sein, aber wichtiger, im Gegensatz zu früheren Systemen wird es ebenfalls möglich sein Transaktionstypen zu konstruieren, die sich die Entwickler von Ethereum heute noch nicht vorstellen können. -Alles in allem glauben wir, dass dieses Design ein großer Schritt in Richtung der Realisierung von "Cryptocurrency 2.0" ist und wir hoffen, dass Astraleums ein signifikanter Beitrag zum Cryptocurrency Ökosystem wird, wie es das Aufkommen von Web 2.0 wa, in Kontrast zum statischen-content-Internet von 1999. - - -### Inhaltsverzeichnis - -* [Warum eine neue Plattform?] (#warum-eine-neue-plattform?) - * [Colored Coins] (#colored-coins) - * [Metacoins] (#metacoins) -* [Philosophie](#philosophy) -* [Grundbeusteine](#basic-building-blocks) - * [Modifizierte GHOST Implementierung](#modified-ghost-implementation) - * [Ethereum Client P2P Protokoll](#ethereum-client-p2p-protocol) - * [Währunge und Währungsausgabe](#currency-and-issuance) - * [Datenformat](#data-format) - * [Mining Algorithmus](#mining-algorithm) - * [Transaktionen](#transactions) - * [Justierung des Schwierigkeitsgrades (Difficulty)](#difficulty-adjustment) - * [Belohung (Block Rewards)](#block-rewards) -* [Verträge](#contracts) - * [Anwendungen](#applications) - * [Unterwährungen](#sub-currencies) - * [Finanzderivate](#financial-derivatives) - * [Identifizierugs- und Reputationsysteme](#identity-and-reputation-systems) - * [Dezentrale Autonome Organisation](#decentralized-autonomous-organizations) - * [Spätere Anwendungen](#further-applications) - * [Wie funktioneren die Verträge?](#how-do-contracts-work) - * [Spezifikation der Prommiersprache](#language-specification) -* [Gebühren](#fees) -* [Fazit](#conclusion) -* [Refernzen und weiterführende Literatur](#references-and-further-reading) - -## Warum eine neue Plattform? -Wenn man eine neue Anwendung erstellt, vor allem in so heiklen Bereichen wie Kryptographie oder Kryptowährungen, ist die naheliegenste Intention, bestehende Protokolle möglichst umfänglich zu nutzen. -Es gibt keine Veranlassung eine neue Währung oder ein neues Protkoll zu erschaffen, wenn Probleme mit der vorhandenen Technologie gelöst werden können. -In der Tat kommt es einem Puzzle gleich, zu versuchen Probleme zu lösen, die mit elektronischen Besitztum, elektronischen Verträgen und Dezentrale Autonome Gesellschftsformen einhergehen, wenn man dies auf Basis des Bitcoins tun möchte. Dies war unser ursprünglicher Antrieb an einem Protokoll der nächsten Generation zu arbeiten. -Während das Bitcoin-Protokoll für das Handling einer Währung mehr als ausreichend ist, wurde im Laufe unserer Forschung aber auch deutlich, dass es schon für einfache elektronische Verträge oder Treuhandfunktionen mit Mehrfachunterschriften grundlegende Einschränkungen gibt, die eine weitergehende Nutzung nur in sehr begrenzten Umfang möglich machen würden. - -### Colored Coins - -Der erste Versuch zur Implementierung eines Systems zur Verarbeitung von elektronischen Besitzständen, kundenspezifischen Währungen und Vermögenswerten auf Basis der Blockkette wurde realisiert als ein "Overlay-Protokoll" auf dem Bitcoin. Um einen Vergleich anzustellen: Etwa so, wie [HTTP] (http://de.wikipedia.org/wiki/Http) als eine obere Schicht des [TCP-Protokolls] (http://de.wikipedia.org/wiki/Transmission_Control_Protocol), so wie im [Interent-Protkoll-Stack](http://de.wikipedia.org/wiki/Internet_Protocol) definiert. - -Das [Colored Coins - Protokoll] (https://docs.google.com/a/ursium.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit) lässt sich annähernd wie folgt beschreiben: - -1. Der Herausgeber eines Clored Coins legt fest, dass eine bestimmte Transaktionsausgabe H:i einen bestimmten Vermögenswert repräsentiert. (H sei dabei der Transaktions-Hash und i der *?Ausgabeindex?*). Er veröffentlicht eine Colored-Coin-Definition, die besagt, welchen Vermögenswert die *?Transaktionsausgabe?* entspricht (z.B. 1 Satoshi von H:i = eine Unze Gold, einzulösen bei der "Stephan Gold Company"). -2. Die anderen "installieren" die Colored-Coin-Definitions-Datei in ihrem Clored-Coin- Clientprogramm. -3. *?Ist die Color-Coin-Definition freigegen, die Ausgabe H:i ist die einzige Transaktionsausgabe, die diese Farbe hat.?* -4. Wenn eine Transaktion Eingänge mit der Farbe X enthält, dann haben die Ausgaben auch die Farbe X. D.h. wenn der Eigentümer von H:i sofort eine Transaktion vornimmt, um die Ausgaben auf 5 Empfänger zu splitten, dann werden die Ausgaben auch die Farbe X haben. -*?Hat?* ein Transaktion Eingänge unterschiedlicher Farben, dann wird eine "Color-Transfer-Richtlinie" oder ein "Color-Kernel" bestimmen, welche Farben welche Ausgaben sind (z.B. würde eine einfache Implementierung bedeutet, dass die Ausgabe 0 die selbe Farbe hat, wie die Eingabe 0, oder die Ausgabe 1 die selbe Farbe wie wie die Eingabe 1, usw.). -5. Wenn eine Colored-Coin-Client-Software feststellt, das eine neue Transaktions-Ausgabe empfangen wurde, verwendet es einen Rückwerts-Such-Algorithmus, basierend auf dem "Color-Kernel", um die Farbe der Ausgabe festzustellen. Die die Regeln deterministisch sind, werden alle Colored-Coin-Client-Programme damit einverstanden sein, welche Farbe die jeweiligen Ausgaben haben. - -Wie auch immer, das Protokoll hat einige fundamentale Schwachstellen: - -**Vereinfachte Zahlungsbestätigung beim Bitcoin ** - -![SPV in bitcoin](https://www.ethereum.org/gh_wiki/spv_bitcoin.png) - -_Links: Es genügt nur eine kleine Anzahl von Knoten im Merkle-Baum um einen Beweis für die Gültigkeit eines Zweigungs zu bekommen._ -_Rechts: Jeder Versuch, einen Teil des Merkle-Baums zu ändern, wird schließlich zu einer Inkonsistenz irgendwo in der Kette führen._ - -1. **Die Schwierigkeit einer vereinfachten Zahlungsüberprüfung** - Die Bitcoin ist [Merkle-Baum-Konstruktion] (http://de.wikipedia.org/wiki/Merkle-Signatur) ermöglicht dem Protokoll eine ["vereinfachte Zahlungsüberprüfung"] (https://en.bitcoin.it/wiki/Scalability#Simplified_payment_verification), in dem ein Client, der nicht die volle Blockkette geladen hat, schnell die Gültigkeit einer Transaktion-Ausgabe zu bestimmen, indem er bei einem anderen Knoten nach einem kryptografischen Beweis für die Gültigkeit eines einzigen Zweigs des Baumes anfragt. -Um sicher zu sein, muss die Client-Software nur den Block-Header herunter laden. Die Menge an Daten, die Bandbreite und die Prüfzeit reduziert sich um etwa den Faktor eintausend. -Mit Colored Coins ist dies viel schwieriger. Der Grund ist, dass man die Farbe einer Transaktionsausgabe nicht einfach durch Nachschlagen im Merkle-Baum bestimmen kann, sondern der Rückwärts-Such-Algorithmus verwendet werden muss. D.h. es müssen potentiell Tausende von Transaktionen geladen werden und es muss ein Merkle-Baum-Gültigkeitsnachweis für jede Transaktion eingeholt werden, bevor eine Client sicher sein kann, dass eine Transaktion eine bestimmte Farbe hat. -Nach über einem Jahr der Untersuchung, einschließlich der Hilfe von uns selbst, wurde keine Lösung für dieses Problem gefunden. - -2. **Inkompatibilität mit Scripting** - wie oben erwähnt, hat Bitcoin ein mäßig flexibles Scripting-System, die es dem Benutzer beispielsweise erlaubt, eine Transaktion in der Form zu unterzeichnen: "Ich gebe die Transaktion-Ausgabe frei für denjenigen, der bereit ist mir einen BTC zu zahlen". -Weitere Beispiele sind [Versicherungsverträge](http://en.wikipedia.org/wiki/Assurance_contract), [effiziente Microzahlungen](https://en.bitcoin.it/wiki/Contracts#Example_7:_Rapidly-adjusted_.28micro.29payments_to_a_pre-determined_party) und blockkettenbasierte Auktionen. -Allerdings ist dieses System von Natur aus nicht "farbbewusst", das heißt, man kann eine Transaktion nicht in der Form machen: "Ich stelle diese Transaktion-Ausgabe für jeden bereit, der mir eine Goldmünze - definiert mit der Entstehung von H:i - zahlt, denn die Skriptsprache hat keine Ahnung davon, dass das "Farben"-Konzept überhaupt existiert. -Während zwar der Austausch von zwei verschiedenfarbige Münzen ohne Vertrauensvorschuss möglich ist, gilt dies nicht für einen vollständigen dezentralen Austausch, da es keine Möglichkeit gibt, durchsetzbare Kauf-oder Verkaufaufträge zu platzieren. - -3. **Die gleichen Einschränkungen wie beim Bitcoin** - im Idealfall sollten Blockchain-Protokolle in der Lage sein, erweiterte Derivate, Wetten und viele andere Formen von bedingten Transfers zu unterstützen. Leider erben die Colored Coins die Grenzen des Bitcoin in Bezug auf die Unmöglichkeit, solche Vereinbarungen zu treffen. - -### Metacoins - -Ein anderes Konzept, wieder in dem Sinne des Aufsetzens auf das Bitcoinprotokoll (wie HTTP auf TCP) ist das des Metacoins. Es ist sehr einfach: -Das Metacoin-Protokoll bietet eine Möglichkeit Metacoin-Transaktionsdaten in die Ausgabe von Bitcoin-Transaktionen heineinzukodieren. Ein Metacoin-Knoten funktioniert durch die Bearbeitung aller Bitcoin-Transaktionen und der Überprüfung der Bitcoin-Transaktionen die gültigen Metacoin-Transaktionen entsprechen, um zu jedem Zeitpunkt die Coinmenge eines Accounts bestimmen zu können. -Zum Beispiel, ein einfaches Metacoin-Protokoll möge eine Transaktion verwenden, um 4 Ausgaben zu generieren: MARKER, FROM, TO und VALUE. -MARKER könnte eine bestimmter Marker-Adresse sein, um die Transaktion als eine Metacoin-Transaktion zu deklarieren. -FROM könnte die Adresse des Absenders sein. -TO könnte die Empfängeradresse der Coins sein und VALUE die Menge der Coins. -Da das Bitcoin-Protokoll keine Metacoins kennt und so auch nicht in der Lage ist, ungültige Metacoin-Transaktionen abzulehnen, muss das Metacoin-Protokoll *?alle Transaktionen zurück bis zu der ersten Ausgabe MARKER?* bearbeiten, um entsprechend reagieren zu können. -Der Teil der Transaktionsverabeitung des oben beschriebenen Metacoin-Protokolls könnte z.B. folgendermaßen aussehen: - - if tx.output[0] != MARKER: - break - else if balance[tx.output[1]] < decode_value(tx.output[3]): - break - else if not tx.hasSignature(tx.output[1]): - break - else: - balance[tx.output[1]] -= decode_value(tx.output[3]); - balance[tx.output[2]] += decode_value(tx.output[3]); - - -Der Vorteil eines Metacoin-Protokolls ist, dass es die Implementierung von erweiterten Transaktionstypen erlaubt (benutzerspezifische Währungen, dezentrale Austausch, Derivate, etc.), die mit dem in der unteren Schicht liegenden Bitcoin-Protokoll nicht möglich wären. -Metacoins, die auf das Bitcoinprotkoll aufgesetzt sind, haben jedoch eine erhebliche Schwachstelle. Eine vereinfachte Zahlungsbestätigung, schon schwierig mit Clored Coins, ist mit Metacoins komplett unmöglich. -Der Grund dafür ist, dass, während man *?SPV?* verwenden kann, um festzustellen, dass eine Transaktion 30 metacoins *?zur?* Adresse X gesendet hat, bedeutet die allein jedoch noch nicht, dass die Adresse X auch 30 metacoins hat. - Was ist, wenn der Absender der Transaktion nicht über 30 metacoins verfügt und so die Transaktion ungültig ist? Um irgend einen aktuellen Zusammenhang mit dem Metacoin herauszufinden, wie die Frage ob eine Transaktion gültig ist oder nicht, ist es letztendlich immer nötig, alle Transaktionen seit dem Launch des Metacoins zu scannen. - -In beiden Fällen ergibt sich folgende Schlussfolgerung. Der Versuch, erweiterte Protokolle aufgesetzt auf dem Bitcoin (wie HTTP auf TCP) zu bauen, ist bewundernswert. Und es ist in der Tat der richtige Weg bei der Umsetzung erweiterter dezentraler Anwendungen. Allerdings ist der Versuch Colored Coins auf Basis des Bitcoinprotokolls zu bauen, aufwändiger als der Bau von *?HTTP über SMTP?*. Die Absicht von SMTP war es, E-Mail-Nachrichten zu übertragen und nicht als Rückrad für die generische Internet-Kommunikation zu dienen. Man hätte viele ineffiziente und architektonisch hässlichen Praktiken umsetzen müssen, um dieses Ziel effektiv zu erreichen. - -Während der Bitcoin ein großartiges Protokoll für einfache Transaktionen und die Aufbewahrung von Werten ist, ist es weder dafür konzipiert noch in der Lage, als Basisschicht für Finanz-Peer-to-Peer-Protokolle im Allgemeinen zu dienen. Etherium löst die Fragen der Skalierbarkeit, indem es seine eigene Blockkette hostet und einen individuellen "Statusbaum" zusammen mit der Transaktionslite in jedem Block hinterlegt. Jeder "Statusbaum" stellt den aktuellen Status des gesamten Systems dar, einschließlich der Adressen, Guthaben und Vertrags-Stati. -Den Ethereu-Verträgen ist es erlaubt, Daten in dauerhaften Speichern abzulegen. Diese Speicher, kombiniert mit der *?Tuning complete?* Skript-Sprache ermöglicht es uns, eine ganze Währung innerhalb eines einzigen Vertrags zu kodieren, neben unzähligen anderen Varienten kryptographischer Vermögenswerte. -Somit hat Ethereum nicht die Absicht, die oben beschriebenen Colored Coin- und Metcoin- Protokolle zu ersetzen, sondern eine überlegene Basis-Schicht mit einem einzigartig leistungsfähigen Scripting-System zu schaffen, auf der beliebig erweiterbare Verträge, Währungen und andere dezentralen Anwendungen aufgesetzt werden können. -Wenn bestehende Colored Coin- und Metacoin-Projekte auf die Ethereum-Baisi wechseln, können sie die Vorteile der vereinfachten Zahlungsüberprüfung nutzen, hätten die Möglichkeit mit den auf Ethereum basierten Finanzderivaten und dezentralen Tauschbörsen kompatibel zu sein, und die Fähigkeit, auf einem einzigen Netzwerk zu zusammen zu arbeiten. -Jemand mit einer Idee für einen neuen Vertrag oder eine Art von Transaktionen, die die Dinge, die mit Kryptowährungen getan werden können, drastisch verbessern, muss nicht seinen eigenen Kryptocoin starten. Dies kann einfach durch die Implementierung auf Basis des Ethereum Script-Codes erfolgen. Kurz gesagt, Ethereu ist ein Fundament für Innovationen. - -## Philosophie - -The design behind Ethereum is intended to follow the following principles: - -1. **Simplicity** - the Ethereum protocol should be as simple as possible, even at the cost of some data storage or time inefficiency. An average programmer should ideally be able to follow and implement the entire specification, so as to fully realize the unprecedented democratizing potential that cryptocurrency brings and further the vision of Ethereum as a protocol that is open to all. Any optimization which adds complexity should not be included unless that optimization provides very substantial benefit. -2. **Universality** - a fundamental part of Ethereum's design philosophy is that Ethereum does not have "features". Instead, Ethereum provides an internal Turing-complete scripting language, which a programmer can use to construct any smart contract or transaction type that can be mathematically defined. Want to invent your own financial derivative? With Ethereum, you can. Want to make your own currency? Set it up as an Ethereum contract. Want to set up a full-scale Daemon or Skynet? You may need to have a few thousand interlocking contracts, and be sure to feed them generously, to do that, but nothing is stopping you with Ethereum at your fingertips. -3. **Modularity** - the parts of the Ethereum protocol should be designed to be as modular and separable as possible. Over the course of development, our goal is to create a program where if one was to make a small protocol modification in one place, the application stack would continue to function without any further modification. Innovations such as [Dagger](https://github.com/ethereum/wiki/wiki/Dagger), [Patricia trees](https://github.com/ethereum/wiki/wiki/Patricia-Tree) and [RLP](https://github.com/ethereum/wiki/wiki/RLP) should be implemented as separate libraries and made to be feature-complete even if Ethereum does not require certain features so as to make them usable in other protocols as well. Ethereum development should be maximally done so as to benefit the entire cryptocurrency ecosystem, not just itself. -4. **Agility** - details of the Ethereum protocol are not set in stone. Although we will be extremely judicious about making modifications to high-level constructs such as the C-like language and the address system, computational tests later on in the development process may lead us to discover that certain modifications to the algorithm or scripting language will substantially improve scalability or security. If any such opportunities are found, we will exploit them. -5. **Non-discrimination** - the protocol should not attempt to actively restrict or prevent specific categories of usage. All regulatory mechanisms in the protocol should be designed to directly regulate the harm and not attempt to oppose specific undesirable applications. A programmer can even run an infinite loop script on top of Ethereum for as long as they are willing to keep paying the per-computational-step transaction fee. - - -## Basic Building Blocks - -At its core, Ethereum starts off as a fairly regular memory-hard proof-of-work mined cryptocurrency without many extra complications. In fact, Ethereum is in some ways simpler than the Bitcoin-based cryptocurrencies that we use today. The concept of a transaction having multiple inputs and outputs, for example, is gone, replaced by a more intuitive balance-based model (to prevent transaction replay attacks, as part of each account balance we also store an incrementing nonce). Sequence numbers and lock times are also removed, and all transaction and block data is encoded in a single format. Instead of addresses being the RIPEMD160 hash of the SHA256 hash of the public key prefixed with 04, addresses are simply the last 20 bytes of the SHA3 hash of the public key. Unlike other cryptocurrencies, which aim to offer a large number of "features", Ethereum intends to take features away, and instead provide its users with near-infinite power through an all-encompassing mechanism known as "contracts". - -### Modified GHOST Implementation - -The "Greedy Heavist Observed Subtree" (GHOST) protocol is an innovation first introduced by Yonatan Sompolinsky and Aviv Zohar in [December 2013](http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf). The motivation behind GHOST is that blockchains with fast confirmation times currently suffer from reduced security due to a high stale rate - because blocks take a certain time to propagate through the network, if miner A mines a block and then miner B happens to mine another block before miner A's block propagates to B, miner B's block will end up wasted and will not contribute to network security. Furthermore, there is a centralization issue: if miner A is a mining pool with 30% hashpower and B has 10% hashpower, A will have a risk of producing stale blocks 70% of the time whereas B will have a risk of producing stale blocks 90% of the time. Thus, if the stale rate is high, A will be substantially more efficient simply by virtue of its size. With these two effects combined, blockchains which produce blocks quickly are very likely to lead to one mining pool having a large enough percentage of the network hashpower to have de facto control over the mining process. - -As descrived by Sompolinsky and Zohar, GHOST solves the first issue of network security loss by including stale blocks in the calculation of which chain is the "longest"; that is to say, not just the parent and further ancestors of a block, but also the stale descendants of the block's ancestor (in Ethereum jargon, "uncles") are added to the calculation of which block has the largest total proof of work backing it. To solve the second issue of centralization bias, we go beyond the protocol described by Sompolinsky and Zohar, and also provide block rewards to stales: a stale block receives 87.5% of its base reward, and the nephew that includes the stale block receives the remaining 12.5%. Transaction fees, however, are not awarded to uncles. - -Ethereum implements a simplified version of GHOST which only goes down one level. Specifically, a stale block can only be included as an uncle by the direct child of one of its direct siblings, and not any block with a more distant relation. This was done for several reasons. First, unlimited GHOST would include too many complications into the calculation of which uncles for a given block are valid. Second, unlimited GHOST with compensation as used in Ethereum removes the incentive for a miner to mine on the main chain and not the chain of a public attacker. Finally, calculations show that single-level GHOST has over 80% of the benefit of unlimited GHOST, and provides a stale rate comparable to the 2.5 minute Litecoin even with a 40-second block time. However, we will be conservative and still retain a Primecoin-like 60-second block time because individual blocks may take a longer time to verify. - - -### Ethereum Client P2P Protocol - -**P2P Protocol** -![SPV in bitcoin](https://www.ethereum.org/gh_wiki/minerchart.png) - -The Ethereum client P2P protocol is a fairly standard cryptocurrency protocol, and can just as easily be used for any other cryptocurrency; the only modification is the introduction of the GHOST protocol described above. The Ethereum client will be mostly reactive; if not provoked, the only thing the client will do by itself is have the networking daemon maintain connections and periodically send a message asking for blocks whose parent is the current block. However, the client will also be more powerful. Unlike bitcoind, which only stores a limited amount of data about the blockchain, the Ethereum client will also act as a fully functional backend for a block explorer. - -When the client reads a message, it will perform the following steps: - -1. Hash the data, and check if the data with that hash has already been received. If so, exit. -2. Determine the data type. If the data is a transaction, if the transaction is valid add it to the local transaction list, process it onto the current block and publish it to the network. If the data item is a message, respond to it. If the data item is a block, go to step 3. -3. Check if the parent of the block is already stored in the database. If it is not, exit. -4. Check if the proof of work on the block header and all block headers in the "uncle list" is valid. If any are not, exit. -5. Check if every block header in the "uncle list" in the block has the block's parent's parent as its own parent. If any is not, exit. Note that uncle block headers do not need to be in the database; they just need to have the correct parent and a valid proof of work. Also, make sure that uncles are unique and distinct from the parent. -6. Check if the timestamp of the block is at most 15 minutes into the future and ahead of the timestamp of the parent. Check if the difficulty of the block and the block number are correct. If either of these checks fails, exit. -7. Start with the state of the parent of the block, and sequentially apply every transaction in the block to it. At the end, add the miner rewards. If the root hash of the resulting state tree does not match the state root in the block header, exit. If it does, add the block to the database and advance to the next step. -8. Determine TD(block) ("total difficulty") for the new block. TD is defined recursively by TD(genesis_block) = 0 and TD(B) = TD(B.parent) + sum([u.difficulty for u in B.uncles]) + B.difficulty. If the new block has higher TD than the current block, set the current block to the new block and continue to the next step. Otherwise, exit. -9. If the new block was changed, apply all transactions in the transaction list to it, discarding from the transaction list any that turn out to be invalid, and rebroadcast the block and those transactions to the network. - -The "current block" is a pointer maintained by each node that refers to the block that the node deems as representing the current official state of the network. All messages asking for balances, contract states, etc, have their responses computed by looking at the current block. If a node is mining, the process is only slightly changed: while doing all of the above, the node also continuously mines on the current block, using its transaction list as the transaction list of the block. - - -### Currency and Issuance - -The Ethereum network includes its own built-in currency, ether. The main reason for including a currency in the network is twofold. First, like Bitcoin, ether is rewarded to miners so as to incentivize network security. Second, it serves as a mechanism for paying transaction fees for anti-spam purposes. Of the two main alternatives to fees, per-transaction proof of work similar to [Hashcash](http://en.wikipedia.org/wiki/Hashcash) and zero-fee laissez-faire, the former is wasteful of resources and unfairly punitive against weak computers and smartphones and the latter would lead to the network being almost immediately overwhelmed by an infinitely looping "logic bomb" contract. For convenience and to avoid future argument (see the current mBTC/uBTC/satoshi debate), the denominations will be pre-labelled: - -* 1: wei -* 10^3: (unspecified) -* 10^6: (unspecified) -* 10^9: (unspecified) -* 10^12: szabo -* 10^15: finney -* 10^18: ether - -This should be taken as an expanded version of the concept of "dollars" and "cents" or "BTC" and "satoshi" that is intended to be future proof. Szabo, finney and ether will likely be used in the foreseeable future, and the other units will be more . "ether" is intended to be the primary unit in the system, much like the dollar or bitcoin. The right to name the 103, 106 and 109 units will be left as a high-level secondary reward for the fundraiser subject to pre-approval from ourselves. - -The issuance model will be as follows: - -* Ether will be released in a fundraiser at the price of 1000-2000 ether per BTC, with earlier funders getting a better price to compensate for the increased uncertainty of participating at an earlier stage. The minimum funding amount will be 0.01 BTC. Suppose that X ether gets released in this way -* 0.225X ether will be allocated to the fiduciary members and early contributors who substantially participated in the project before the start of the fundraiser. This share will be stored in a time-lock contract; about 40% of it will be spendable after one year, 70% after two years and 100% after 3 years. -* 0.05X ether will be allocated to a fund to use to pay expenses and rewards in ether between the start of the fundraiser and the launch of the currency -* 0.225X ether will be allocated as a long-term reserve pool to pay expenses, salaries and rewards in ether after the launch of the currency -* 0.4X ether will be mined per year forever after that point - - -| Group | After 1 year | After 5 years -| ------------- | ------------- |-------------| -| Currency units | 1.9X | 3.5X | -| Fundraiser participants | 52.6% | 28.6% | -| Fiduciary members and early contributors | 11.8% | 6.42% | -| Additional pre-launch allocations | 2.63% | 1.42% | -| Reserve | 11.8% | 6.42% | -| Miners | 21.1% | 57.1% | - - -**Long-Term Inflation Rate (percent)** - -![SPV in bitcoin](https://www.ethereum.org/gh_wiki/inflation.svg) - -_Despite the linear currency issuance, just like with Bitcoin over time the inflation rate nevertheless tends to zero_ - - -For example, after five years and assuming no transactions, 28.6% of the ether will be in the hands of the fundraiser participants, 6.42% in the fiduciary member and early contributor pool, 6.42% paid to the reserve pool, and 57.1% will belong to miners. The permanent linear inflation model reduces the risk of what some see as excessive wealth concentration in Bitcoin, and gives individuals living in present and future eras a fair chance to acquire currency units, while at the same time retaining a strong incentive to obtain and hold ether because the inflation "rate" still tends to zero over time (eg. during year 1000001 the money supply would increase from 500001.5 * X to 500002 * X, an inflation rate of 0.0001%). Furthermore, much of the interest in Ethereum will be medium-term; we predict that if Ethereum succeeds it will see the bulk of its growth on a 1-10 year timescale, and supply during that period will be very much limited. - -We also theorize that because coins are always lost over time due to carelessness, death, etc, and coin loss can be modeled as a percentage of the total supply per year, that the total currency supply in circulation will in fact eventually stabilize at a value equal to the annual issuance divided by the loss rate (eg. at a loss rate of 1%, once the supply reaches 40X then 0.4X will be mined and 0.4X lost every year, creating an equilibrium). - - -### Data Format - -All data in Ethereum will be stored in [recursive length prefix encoding](https://github.com/ethereum/wiki/wiki/RLP), which serializes arrays of strings of arbitrary length and dimension into strings. For example, ['dog', 'cat'] is serialized (in byte array format) as [ 130, 67, 100, 111, 103, 67, 99, 97, 116]; the general idea is to encode the data type and length in a single byte followed by the actual data (eg. converted into a byte array, 'dog' becomes [ 100, 111, 103 ], so its serialization is [ 67, 100, 111, 103 ]. Note that RLP encoding is, as suggested by the name, recursive; when RLP encoding an array, one is really encoding a string which is the concatenation of the RLP encodings of each of the elements. Additionally, note that block number, timestamp, difficulty, memory deposits, account balances and all values in contract storage are integers, and Patricia tree hashes, root hashes, addresses, transaction list hashes and all keys in contract storage are strings. The main difference between the two is that strings are stored as fixed-length data (20 bytes for addresses, 32 bytes for everything else), and integers take up only as much space as they need. Integers are stored in big-endian base 256 format (eg. 32767 in byte array format as [ 127, 255 ]). - -A full block is stored as: - - [ - block_header, - transaction_list, - uncle_list - ] - -Where: - - transaction_list = [ - transaction 1, - transaction 2, - ... - ] - - uncle list = [ - uncle_block_header_1, - uncle_block_header_2, - ... - ] - - block_header = [ - parent hash, - sha3(rlp_encode(uncle_list)), - coinbase address, - state_root, - sha3(rlp_encode(transaction_list)), - difficulty, - timestamp, - extra_data, - nonce - ] - -Each transaction and uncle block header is itself a list. The data for the proof of work is the RLP encoding of the block WITHOUT the nonce. uncle_list and transaction_list are the lists of the uncle block headers and transactions in the block, respectively. nonce and extra_data are both limited to a maximum of 32 bytes, except the genesis block where the extra_data parameter will be much larger. - -The state_root is the root of a [Merkle Patricia tree](https://github.com/ethereum/wiki/wiki/Patricia-Tree) containing (key, value) pairs for all accounts where each address is represented as a 20-byte binary string. At the address of each account, the value stored in the Merkle Patricia tree is a string which is the RLP-serialized form of an object of the form: - - [ balance, nonce, contract_root, storage_deposit ] - -The nonce is the number of transactions made from the account, and is incremented every time a transaction is made. The purpose of this is to (1) make each transaction valid only once to prevent replay attacks, and (2) to make it impossible (more precisely, cryptographically infeasible) to construct a contract with the same hash as a pre-existing contract. balance refers to the account's balance, denominated in wei. contract_root is the root of yet another Patricia tree, containing the contract's memory, if that account is controlled by a contract. If an account is not controlled by a contract, the contract root will simply be the empty string. storage_deposit is a counter that stores paid storage fees; its function will be discussed in more detail further in this paper. - - -### Mining algorithm - -One highly desirable property in mining algorithms is resistance to optimization through specialized hardware. Originally, Bitcoin was conceived as a highly democratic currency, allowing anyone to participate in the mining process with a CPU. In 2010, however, much faster miners exploiting the rapid parallelization offered by graphics processing units (GPUs) rapidly took over, increasing network hashpower by a factor of 100 and leaving CPUs essentially in the dust. In 2013, a further category of specialized hardware, application-specific integrated circuits (ASICs) outcompeted the GPUs in turn, achieving another 100x speedup by using chips fabricated for the sole purpose of computing SHA256 hashes. Today, it is virtually impossible to mine without first purchasing a mining device from one of these companies, and some people are concerned that in 5-10 years' time mining will be entirely dominated by large centralized corporations such as AMD and Intel. - -To date, the main way of achieving this goal has been "memory-hardness", constructing proof of work algorithms that require not only a large number of computations, but also a large amount of memory, to validate, thereby making highly parallelized specialized hardware implementations less effective. There have been several implementations of memory-hard proof of work, all of which have their flaws: - -* **Scrypt** - Scrypt is a function which is designed to take 128 KB of memory [to compute](https://litecoin.info/User:Iddo/Comparison_between_Litecoin_and_Bitcoin#SHA256_mining_vs_scrypt_mining). The algorithm essentially works by filling a memory array with hashes, and then computing intermediate values and finally a result based on the values in the memory array. However, the 128 KB parameter is a very weak threshold, and ASICs for Litecoin are [already under development](https://axablends.com/merchants-accepting-bitcoin/litecoin-discussion/litecoin-scrypt-asic-miners/). Furthermore, there is a natural limit to how much memory hardness with Scrypt can be tweaked up to achieve, as the verification process takes just as much memory, and just as much computation, as one round of the mining process. -* **Birthday attacks** - the idea behind birthday-based proofs of work is simple: find values xn,i,j such that i < k, j < k and |H(data+xn+i) - H(data+xn+j)| < 2^256 / d^2. The d parameter sets the computational difficulty of finding a block, and the k parameter sets the memory hardness. Any birthday algorithm must somehow store all computations of H(data+xn+i) in memory so that future computations can be compared against them. Here, computation is memory-hard, but verification is memory-easy, allowing for extreme memory hardness without compromising the ease of verification. However, the algorithm is problematic for two reasons. First, there is a time-memory tradeoff attack where users 2x less memory can compensate with 2x more computational power, so its memory hardness is not absolute. Second, it may be easy to build specialized hardware devices for the problem, especially once one moves beyond traditional chip and processor architecture and into various classes of hardware-based hash tables or probabilistic analog computing. -* **Dagger** - the idea behind Dagger, an in-house algorithm developed by the Ethereum team, is to have an algorithm that is similar to Scrypt, but which is specially designed so that each individual nonce only depends on a small portion of the data tree that gets built up for each group of ~10 million nonces. Computing nonces with any reasonable level of efficiency requires building up the entire tree, taking up over 100 MB of memory, whereas verifying a nonce only takes about 100 KB. However, Dagger-style algorithms are vulnerable to devices that have multiple computational circuits sharing the same memory, and although this threat can be mitigated it is arguably impossible to fully remove. - - -As a default, we are currently considering a Dagger-like algorithm with tweaked parameters to minimize specialized hardware attacks, perhaps together with a proof of stake algorithm such as our own Slasher for added security if deemed necessary. However, in order to come up with a proof-of-work algorithm that is better than all existing competitors, our intention is to use some of the funds raised in the fundraiser to host a contest, similar to those used to determine the algorithm for the Advanced Encryption Standard (AES) in 2005 and the SHA3 hash algorithm in 2013, where research groups from around the world compete to develop ASIC-resistant mining algorithms, and have a selection process with multiple rounds of judging determine the winners. The contest will have prizes, and will be open-ended; we encourage research into memory-hard proofs of work, self-modifying proofs of work, proofs of work based on x86 instructions, multiple proofs of work with a human-driven incentive-compatible economic protocol for swapping one out in the future, and any other design that accomplishes the task. There will be opportunities to explore alternatives such as proof of stake, proof of burn and proof of excellence as well. - - -### Transactions - -A transaction is stored as: - - [ nonce, receiving_address, value, [ data item 0, data item 1 ... data item n ], v, r, s ] - -nonce is the number of transactions already sent by that account, encoded in binary form (eg. 0 -> '', 7 -> '\x07', 1000 -> '\x03\xd8'). (v,r,s) is the raw Electrum-style signature of the transaction without the signature made with the private key corresponding to the sending account, with 0 <= v <= 3. From an Electrum-style signature (65 bytes) it is possible to extract the public key, and thereby the address, directly. A valid transaction is one where (i) the signature is well-formed (ie. 0 <= v <= 3, 0 <= r < P, 0 <= s < N, 0 <= r < P - N if v >= 2), and (ii) the sending account has enough funds to pay the fee and the value. A valid block cannot contain an invalid transaction; however, if a contract generates an invalid transaction that transaction will simply have no effect. Transaction fees will be included automatically. If one wishes to voluntarily pay a higher fee, one is always free to do so by constructing a contract which forwards transactions but automatically sends a certain amount or percentage to the miner of the current block. - -Transactions sent to the empty string as an address are a special type of transaction, creating a "contract". - - -### Difficulty adjustment - -Difficulty is adjusted by the formula: - - D(genesis_block) = 2^36 - D(block) = - if anc(block,1).timestamp >= anc(block,501).timestamp + 60 * 500: D(block.parent) - floor(D(block.parent) / 1000) - else: D(block.parent) + floor(D(block.parent) / 1000) - -anc(block,n) is the nth generation ancestor of the block; all blocks before the genesis block are assumed to have the same timestamp as the genesis block. This stabilizes around a block time of 60 seconds automatically. The choice of 500 was made in order to balance the concern that for smaller values miners with sufficient hashpower to often produce two blocks in a row would have the incentive to provide an incorrect timestamp to maximize their own reward and the fact that with higher values the difficulty oscillates too much; with the constant of 500, simulations show that a constant hashpower produces a variance of about +/-20%. - - -### Block Rewards - -A miner receives three kinds of rewards: a static block reward for producing a block, fees from transactions, and nephew/uncle rewards as described in the GHOST section above. The miner will receive 100% of the block reward for themselves, but transaction fee rewards will be split, so that 50% goes to the miner and the remaining 50% is evenly split among the last 64 miners. The reason for this is to prevent a miner from being able to create an Ethereum block with an unlimited number of operations, paying all transaction fees to themselves, while still maintaining an incentive for miners to include transactions. As described in the GHOST section, uncles only receive 87.5% of their block reward, with the remaining 12.5% going to the including nephew; the transaction fees from the stale block do not go to anyone. - - -## Contracts - -In Ethereum, there are two types of entities that can generate and receive transactions: actual people (or bots, as cryptographic protocols cannot distinguish between the two) and contracts. A contract is essentially an automated agent that lives on the Ethereum network, has an Ethereum address and balance, and can send and receive transactions. A contract is "activated" every time someone sends a transaction to it, at which point it runs its code, perhaps modifying its internal state or even sending some transactions, and then shuts down. The "code" for a contract is written in a special-purpose low-level language consisting of a stack, which is not persistent, 2256 memory entries, which are also not persistent, and 2256 storage entries which constitute the contract's permanent state. Note that Ethereum users will not need to code in this low-level stack language; we will provide a simple [C-Like language](https://github.com/ethereum/wiki/wiki/CLL) with variables, expressions, conditionals, arrays and while loops, and provide a compiler down to Ethereum script code. - - -### Applications - -Here are some examples of what can be done with Ethereum contracts, with all code examples written in our C-like language. The variables tx.sender, tx.value, tx.fee, tx.data and tx.datan are properties of the incoming transaction, contract.storage, and contract.address of the contract itself, and block.contract_storage, block.account_balance, block.number, block.difficulty, block.parenthash, block.basefee and block.timestamp properties of the block. block.basefee is the "base fee" which all transaction fees in Ethereum are calculated as a multiple of; for more info see the "fees" section below. All variables expressed as capital letters (eg. A) are constants, to be replaced by actual values by the contract creator when actually releasing the contract. - - -### Sub-currencies - -Sub-currencies have many applications ranging from currencies representing assets such as USD or gold to company stocks and even currencies with only one unit issued to represent collectibles or smart property. Advanced special-purpose financial protocols sitting on top of Ethereum may also wish to organize themselves with an internal currency. Sub-currencies are surprisingly easy to implement in Ethereum; this section describes a fairly simple contract for doing so. - -The idea is that if someone wants to send X currency units to account A in currency contract C, they will need to make a transaction of the form (C, 100 * block.basefee, [A, X]), and the contract parses the transaction and adjusts balances accordingly. For a transaction to be valid, it must send 100 times the base fee worth of ether to the contract in order to "feed" the contract (as each computational step after the first 16 for any contract costs the contract a small fee and the contract will stop working if its balance drains to zero). - - if tx.value < 100 * block.basefee: - stop - elif contract.storage[1000]: - from = tx.sender - to = tx.data[0] - value = tx.data[1] - if to <= 1000: - stop - if contract.storage[from] < value: - stop - contract.storage[from] = contract.storage[from] - value - contract.storage[to] = contract.storage[to] + value - else: - contract.storage[MYCREATOR] = 10^18 - contract.storage[1000] = 1 - - -Ethereum sub-currency developers may also wish to add some other more advanced features: - -* Include a mechanism by which people can buy currency units in exchange for ether, perhaps auctioning off a set number of units every day. -* Allow transaction fees to be paid in the internal currency, and then refund the ether transaction fee to the sender. This solves one major problem that all other "sub-currency" protocols have had to date: the fact that sub-currency users need to maintain a balance of sub-currency units to use and units in the main currency to pay transaction fees in. Here, a new account would need to be "activated" once with ether, but from that point on it would not need to be recharged. -* Allow for a trust-free decentralized exchange between the currency and ether. Note that trust-free decentralized exchange between any two contracts is theoretically possible in Ethereum even without special support, but special support will allow the process to be done about ten times more cheaply. - - -### Financial derivatives - -The underlying key ingredient of a financial derivative is a data feed to provide the price of a particular asset as expressed in another asset (in Ethereum's case, the second asset will usually be ether). There are many ways to implement a data feed; one method, pioneered by the developers of [Mastercoin](http://mastercoin.org/), is to include the data feed in the blockchain. Here is the code: - - if tx.sender != FEEDOWNER: - stop - contract.storage[data[0]] = data[1] - -Any other contract will then be able to query index I of data store D by using block.contract_storage(D)[I]. A more advanced way to implement a data feed may be to do it off-chain - have the data feed provider sign all values and require anyone attempting to trigger the contract to include the latest signed data, and then use Ethereum's internal scripting functionality to verify the signature. Pretty much any derivative can be made from this, including leveraged trading, options, and even more advanced constructions like collateralized debt obligations (no bailouts here though, so be mindful of black swan risks). - -To show an example, let's make a hedging contract. The basic idea is that the contract is created by party A, who puts up 4000 ether as a deposit. The contract then lies open for any party to accept it by putting in 1000 ether. Say that 1000 ether is worth $25 at the time the contract is made, according to index I of data store D. If party B accepts it, then after 30 days anyone can send a transaction to make the contract process, sending the same dollar value worth of ether (in our example, $25) back to B and the rest to A. B gains the benefit of being completely insulated against currency volatility risk without having to rely on any issuers. The only risk to B is if the value of ether falls by over 80% in 30 days - and even then, if B is online B can simply quickly hop onto another hedging contract. The benefit to A is the implicit 0.2% fee in the contract, and A can hedge against losses by separately holding USD in another location (or, alternatively, A can be an individual who is optimistic about the future of Ethereum and wants to hold ether at 1.25x leverage, in which case the fee may even be in B's favor). - - if tx.value < 200 * block.basefee: - stop - if contract.storage[1000] == 0: - if tx.value < 1000 * 10^18: - stop - contract.storage[1000] = 1 - contract.storage[1001] = 998 * block.contract_storage(D)[I] - contract.storage[1002] = block.timestamp + 30 * 86400 - contract.storage[1003] = tx.sender - else: - ethervalue = contract.storage[1001] / block.contract_storage(D)[I] - if ethervalue >= 5000: - mktx(contract.storage[1003],5000 * 10^18,0,0) - else if block.timestamp > contract.storage[1002]: - mktx(contract.storage[1003],ethervalue * 10^18,0,0) - mktx(A,(5000 - ethervalue) * 10^18,0,0) - -More advanced financial contracts are also possible; complex multi-clause options (eg. "Anyone, hereinafter referred to as X, can claim this contract by putting in 2 USD before Dec 1. X will have a choice on Dec 4 between receiving 1.95 USD on Dec 29 and the right to choose on Dec 11 between 2.20 EUR on Dec 28 and the right to choose on Dec 18 between 1.20 GBP on Dec 30 and paying 1 EUR and getting 3.20 EUR on Dec 29") can be defined simply by storing a state variable just like the contract above but having more clauses in the code, one clause for each possible state. Note that financial contracts of any form do need to be fully collateralized; the Ethereum network controls no enforcement agency and cannot collect debt. - - -### Identity and Reputation Systems - -The earliest alternative cryptocurrency of all, [Namecoin](http://namecoin.org/), attempted to use a Bitcoin-like blockchain to provide a name registration system, where users can register their names in a public database alongside other data. The major cited use case is for a [DNS](http://en.wikipedia.org/wiki/Domain_Name_System) system, mapping domain names like "bitcoin.org" (or, in Namecoin's case, "bitcoin.bit") to an IP address. Other use cases include email authentication and potentially more advanced reputation systems. Here is a simple contract to provide a Namecoin-like name registration system on Ethereum: - - if tx.value < block.basefee * 200: - stop - if contract.storage[tx.data[0]] or tx.data[0] < 100: - stop - contract.storage[tx.data[0]] = tx.data[1] - -One can easily add more complexity to allow users to change mappings, automatically send transactions to the contract and have them forwarded, and even add reputation and web-of-trust mechanics. - - -### Decentralized Autonomous Organizations - -The general concept of a "decentralized autonomous organization" is that of a virtual entity that has a certain set of members or shareholders which, perhaps with a 67% majority, have the right to spend the entity's funds and modify its code. The members would collectively decide on how the organization should allocate its funds. Methods for allocating a DAO's funds could range from bounties, salaries to even more exotic mechanisms such as an internal currency to reward work. This essentially replicates the legal trappings of a traditional company or nonprofit but using only cryptographic blockchain technology for enforcement. So far much of the talk around DAOs has been around the "capitalist" model of a "decentralized autonomous corporation" (DAC) with dividend-receiving shareholders and tradable shared; an alternative, perhaps described as a "decentralized autonomous community", would have all members have an equal share in the decision making and require 67% of existing members to agree to add or remove a member. The requirement that one person can only have one membership would then need to be enforced collectively by the group. - -Some "skeleton code" for a DAO might look as follows. - -There are three transaction types: - -* [0,k] to register a vote in favor of a code change -* [1,k,L,v0,v1...vn] to register a code change at code k in favor of setting memory starting from location L to v0, v1 ... vn -* [2,k] to finalize a given code change - -Note that the design relies on the randomness of addresses and hashes for data integrity; the contract will likely get corrupted in some fashion after about 2^128 uses, but that is acceptable since nothing close to that volume of usage will exist in the foreseeable future. 2^255 is used as a magic number to store the total number of members, and a membership is stored with a 1 at the member's address. The last three lines of the contract are there to add C as the first member; from there, it will be C's responsibility to use the democratic code change protocol to add a few other members and code to bootstrap the organization. - - if tx.value < tx.basefee * 200: - stop - if contract.storage[tx.sender] == 0: - stop - k = sha3(32,tx.data[1]) - if tx.data[0] == 0: - if contract.storage[k + tx.sender] == 0: - contract.storage[k + tx.sender] = 1 - contract.storage[k] += 1 - else if tx.data[0] == 1: - if tx.value <= tx.datan * block.basefee * 200 or contract.storage[k]: - stop - i = 2 - while i < tx.datan: - contract.storage[k + i] = tx.data[i] - i = i + 1 - contract.storage[k] = 1 - contract.storage[k+1] = tx.datan - else if tx.data[0] == 2: - if contract.storage[k] >= contract.storage[2 ^ 255] * 2 / 3: - if tx.value <= tx.datan * block.basefee * 200: - stop - i = 3 - L = contract.storage[k+1] - loc = contract.storage[k+2] - while i < L: - contract.storage[loc+i-3] = tx.data[i] - i = i + 1 - if contract.storage[2 ^ 255 + 1] == 0: - contract.storage[2 ^ 255 + 1] = 1 - contract.storage[C] = 1 - -This implements the "egalitarian" DAO model where members have equal shares. One can easily extend it to a shareholder model by also storing how many shares each owner holds and providing a simple way to transfer shares. - -DAOs and DACs have already been the topic of a large amount of interest among cryptocurrency users as a future form of economic organization, and we are very excited about the potential that DAOs can offer. In the long term, the Ethereum fund itself intends to transition into being a fully self-sustaining DAO. - - -### Further Applications - -1. **Savings wallets**. Suppose that Alice wants to keep her funds safe, but is worried that she will lose or someone will hack her private key. She puts ether into a contract with Bob, a bank, as follows: Alice alone can withdraw a maximum of 1% of the funds per day, Alice and Bob together can withdraw everything, and Bob alone can withdraw a maximum of 0.05% of the funds. Normally, 1% per day is enough for Alice, and if Alice wants to withdraw more she can contact Bob for help. If Alice's key gets hacked, she runs to Bob to move the funds to a new contract. If she loses her key, Bob will get the funds out eventually. If Bob turns out to be malicious, she can still withdraw 20 times faster than he can. - -2. **Crop insurance**. One can easily make a financial derivatives contract but using a data feed of the weather instead of any price index. If a farmer in Iowa purchases a derivative that pays out inversely based on the precipitation in Iowa, then if there is a drought, the farmer will automatically receive money and if there is enough rain the farmer will be happy because their crops would do well. - -3. **A decentrally managed data feed**, using proof-of-stake voting to give an average (or more likely, median) of everyone's opinion on the price of a commodity, the weather or any other relevant data. - -4. **Smart multisignature escrow**. Bitcoin allows multisignature transaction contracts where, for example, three out of a given five keys can spend the funds. Ethereum allows for more granularity; for example, four out of five can spend everything, three out of five can spend up to 10% per day, and two out of five can spend up to 0.5% per day. Additionally, Ethereum multisig is asynchronous - two parties can register their signatures on the blockchain at different times and the last signature will automatically send the transaction. - -5. **Peer-to-peer gambling**. Any number of peer-to-peer gambling protocols, such as Frank Stajano and Richard Clayton's [Cyberdice](http://www.cl.cam.ac.uk/~fms27/papers/2008-StajanoCla-cyberdice.pdf), can be implemented on the Ethereum blockchain. The simplest gambling protocol is actually simply a contract for difference on the next block hash. From there, entire gambling services such as SatoshiDice can be replicated on the blockchain either by creating a unique contract per bet or by using a quasi-centralized contract. - -6. A full-scale **on-chain stock market**. Prediction markets are also easy to implement as a trivial consequence. - -7. An **on-chain decentralized marketplace**, using the identity and reputation system as a base. - -8. **Decentralized Dropbox**. One setup is to encrypt a file, build a Merkle tree out of it, put the Merkle root into a contract alongside a certain quantity of ether, and distribute the file across some secondary network. Every day, the contract would randomly select a branch of the Merkle tree depending on the block hash, and give X ether to the first node to provide that branch to the contract, thereby encouraging nodes to store the data for the long term in an attempt to earn the prize. If one wants to download any portion of the file, one can use a [micropayment-channel](https://bitcointalk.org/index.php?topic=244656.0)-style contract to download the file from a few nodes a block at a time. - - -### How do contracts work? - -A contract making transaction is encoded as follows: - - [ - nonce, - '', - value, - [ - data item 0, - data item 1, - ... - ], - v, - r, - s - ] - - -The data items will, in most cases, be script codes (more on this below). Contract creation transaction validation happens as follows: - -Deserialize the transaction, and extract its sending address from its signature. -Calculate the transaction's fee as NEWCONTRACTFEE plus storage fees for the code. Check that the balance of the creator is at least the transaction value plus the fee. If not, exit. -Take the last 20 bytes of the sha3 hash of the RLP encoding of the transaction making the contract. If an account with that address already exists, exit. Otherwise, create the contract at that address -Copy data item i to storage slot i in the contract for all i in [0 ... n-1] where n is the number of data items in the transaction, and initialize the contract with the transaction's value as its value. Subtract the value and fee from the creator's balance. - - -### Language Specification - -The contract scripting language is a hybrid of assembly language and Bitcoin's stack-based language, maintaining an index pointer that usually increments by one after every operation and continuously processing the operation found at the current index pointer. All opcodes are numbers in the range [0 ... 63]; labels further in this description such as STOP, EXTRO and BALANCE refer to specific values are defined further below. The scripting language has access to three kinds of memory: - -* **Stack** - a form of temporary storage that is reset to an empty list every time a contract is executed. Operations typically add and remove values to and from the top of the stack, so the total length of the stack will shrink and grow over the course of the program's execution. -* **Memory** - a temporary key/value store that is reset to containing all zeroes every time a contract is executed. Keys and values in memory are integers in the range [0 ... 2^256-1] -* **Storage** - a persistent key/value store that is initially set to contain all zeroes, except for some script code inserted at the beginning when the contract is created as described above. Keys and values in storage are integers in the range [0 ... 2^256-1] - -Whenever a transaction is sent to a contract, the contract executes its scripting code. The precise steps that happen when a contract receives a transaction are as follows: - -**Contract Script Interpretation ** - -![SPV in bitcoin](https://www.ethereum.org/gh_wiki/flowchart.png) - -1. The contract's ether balance increases by the amount sent -2. The index pointer is set to zero, and STEPCOUNT = 0 -3. Repeat forever: - -* if the command at the index pointer is STOP, invalid or greater than 63, exit from the loop -* set MINERFEE = 0, VOIDFEE = 0 -* set STEPCOUNT <- STEPCOUNT + 1 -* if STEPCOUNT > 16, set MINERFEE <- MINERFEE + STEPFEE -* see if the command is LOAD or STORE. If so, set MINERFEE <- MINERFEE + DATAFEE -* see if the command will modify a storage field, say modifying KEY from OLDVALUE to NEWVALUE. Let F(K,V) be 0 if V == 0 else (len(K) + len(V)) * STORAGEFEE in bytes. Set VOIDFEE <- VOIDFEE - F(KEY,OLDVALUE) + F(KEY,NEWVALUE). Computing len(K) ignores leading zero bytes. -* see if the command is EXTRO or BALANCE. If so, set MINERFEE <- MINERFEE + EXTROFEE -* see if the command is a crypto operation. If so, set MINERFEE <- MINERFEE + CRYPTOFEE -* if MINERFEE + VOIDFEE > CONTRACT.BALANCE, HALT and exit from the loop -* subtract MINERFEE from the contract's balance and add MINERFEE to a running counter that will be added to the miner's balance once all transactions are parsed. -* set DELTA = max(-CONTRACT.STORAGE_DEPOSIT,VOIDFEE) and CONTRACT.BALANCE <- CONTRACT.BALANCE - DELTA and CONTRACT.STORAGE_DEPOSIT <- CONTRACT.STORAGE_DEPOSIT + DELTA. Note that DELTA can be positive or negative; the only restriction is that the contract's deposit cannot go below zero. -* run the command -* if the command did not exit with an error, update the index pointer and return to the start of the loop. If the contract did exit with an error, break out of the loop. Note that a contract exiting with an error does not make the transaction or the block invalid; it simply means that the contract execution halts midway through. - -In the following descriptions, S[-1], S[-2], etc represent the topmost, second topmost, etc items on the stack. The individual opcodes are defined as follows: - -* (0) STOP - halts execution -* (1) ADD - pops two items and pushes S[-2] + S[-1] mod 2^256 -* (2) MUL - pops two items and pushes S[-2] * S[-1] mod 2^256 -* (3) SUB - pops two items and pushes S[-2] - S[-1] mod 2^256 -* (4) DIV - pops two items and pushes floor(S[-2] / S[-1]). If S[-1] = 0, halts execution. -* (5) SDIV - pops two items and pushes floor(S[-2] / S[-1]), but treating values above 2^255 - 1 as negative (ie. x -> 2^256 - x). If S[-1] = 0, halts execution. -* (6) MOD - pops two items and pushes S[-2] mod S[-1]. If S[-1] = 0, halts execution. -* (7) SMOD - pops two items and pushes S[-2] mod S[-1], but treating values above 2^255 - 1 as negative (ie. x -> 2^256 - x). If S[-1] = 0, halts execution. -* (8) EXP - pops two items and pushes S[-2] ^ S[-1] mod 2^256 -* (9) NEG - pops one item and pushes 2^256 - S[-1] -* (10) LT - pops two items and pushes 1 if S[-2] < S[-1] else 0 -* (11) LE - pops two items and pushes 1 if S[-2] <= S[-1] else 0 -* (12) GT - pops two items and pushes 1 if S[-2] > S[-1] else 0 -* (13) GE - pops two items and pushes 1 if S[-2] >= S[-1] else 0 -* (14) EQ - pops two items and pushes 1 if S[-2] == S[-1] else 0 -* (15) NOT - pops one item and pushes 1 if S[-1] == 0 else 0 -* (16) MYADDRESS - pushes the contract's address as a number -* (17) TXSENDER - pushes the transaction sender's address as a number -* (18) TXVALUE - pushes the transaction value -* (19) TXDATAN - pushes the number of data items -* (20) TXDATA - pops one item and pushes data item S[-1], or zero if index out of range -* (21) BLK_PREVHASH - pushes the hash of the previous block (NOT the current one since that's impossible!) -* (22) BLK_COINBASE - pushes the coinbase of the current block -* (23) BLK_TIMESTAMP - pushes the timestamp of the current block -* (24) BLK_NUMBER - pushes the current block number -* (25) BLK_DIFFICULTY - pushes the difficulty of the current block -* (26) BLK_NONCE - pushes the nonce of the current block -* (27) BASEFEE - pushes the base fee (x as defined in the fee section below) -* (32) SHA256 - pops two items, and then constructs a string by taking the ceil(S[-1] / 32) items in memory from index S[-2] to (S[-2] + ceil(S[-1] / 32) - 1) mod 2^256, prepending zero bytes to each one if necessary to get them to 32 bytes, and takes the last S[-1] bytes. Pushes the SHA256 hash of the string -* (33) RIPEMD160 - works just like SHA256 but with the RIPEMD-160 hash -* (34) ECMUL - pops three items. If (S[-2],S[-1]) are a valid point in secp256k1, including both coordinates being less than P, pushes (S[-2],S[-1]) * S[-3], using (0,0) as the point at infinity. Otherwise, pushes (2^256 - 1, 2^256 - 1). Note that there are no restrictions on S[-3] -* (35) ECADD - pops four items and pushes (S[-4],S[-3]) + (S[-2],S[-1]) if both points are valid, otherwise (2^256 - 1,2^256 - 1) -* (36) ECSIGN - pops two items and pushes (v,r,s) as the Electrum-style RFC6979 deterministic signature of message hash S[-1] with private key S[-2] mod N with 0 <= v <= 3 -* (37) ECRECOVER - pops four items and pushes (x,y) as the public key from the signature (S[-3],S[-2],S[-1]) of message hash S[-4]. If the signature has invalid v,r,s values (ie. v not in [27,28], r not in [0,P], s not in [0,N]), return (2^256 - 1,2^256 - 1) -* (38) ECVALID - pops two items and pushes 1 if (S[-2],S[-1]) is a valid secp256k1 point (including (0,0)) else 0 -* (39) SHA3 - works just like SHA256 but with the SHA3 hash, 256 bit version -* (48) PUSH - pushes the item in memory at the index pointer + 1, and advances the index pointer by 2. -* (49) POP - pops one item. -* (50) DUP - pushes S[-1] to the stack. -* (51) SWAP - pops two items and pushes S[-1] then S[-2] -* (52) MLOAD - pops two items and sets the item in memory at index S[-1] to S[-2] -* (53) MSTORE - pops two items and sets the item in memory at index S[-1] to S[-2] -* (54) SLOAD - pops two items and sets the item in storage at index S[-1] to S[-2] -* (55) SSTORE - pops two items and sets the item in storage at index S[-1] to S[-2] -* (56) JMP - pops one item and sets the index pointer to S[-1] -* (57) JMPI - pops two items and sets the index pointer to S[-2] only if S[-1] is nonzero -* (58) IND - pushes the index pointer -* (59) EXTRO - pops two items and pushes memory index S[-2] of contract S[-1] -* (60) BALANCE - pops one item and pushes balance of the account with that address, or zero if the address is invalid -* (61) MKTX - pops four items and initializes a transaction to send S[-2] ether to S[-1] with S[-3] data items. Takes items in memory from index S[-4] to index (S[-4] + S[-3] - 1) mod 2^256 as the transaction's data items. -* (63) SUICIDE - pops one item, destroys the contract and clears all storage, sending the entire balance plus the contract deposit to the account at S[-1] - - -As mentioned above, the intent is not for people to write scripts directly in Ethereum script code; rather, we will release compilers to generate ES from higher-level languages. The first supported language will likely be the simple C-like language used in the descriptions above, and the second will be a more complete first-class-function language with support for arrays and arbitrary-length strings. Compiling the C-like language is fairly simple as far as compilers go: variables can be assigned a memory index, and compiling an arithmetic expression essentially involves converting it to reverse Polish notation (eg. (3 + 5) * (x + y) -> PUSH 3 PUSH 5 ADD PUSH 0 MLOAD PUSH 1 MLOAD ADD MUL). First-class function languages are more involved due to variable scoping, but the problem is nevertheless tractable. The likely solution will be to maintain a linked list of stack frames in memory, giving each stack frame N memory slots where N is the total number of distinct variable names in the program. Variable access will consist of searching down the stack frame list until one frame contains a pointer to the variable, copying the pointer to the top stack frame for memoization purposes, and returning the value at the pointer. However, these are longer term concerns; compilation is separate from the actual protocol, and so it will be possible to continue to research compilation strategies long after the network is set running. - - -## Fees - -In Bitcoin, there are no mandatory transaction fees. Transactions can optionally include fees which are paid to miners, and it is up to the miners to decide what fees they are willing to accept. In Bitcoin, such a mechanism is already imperfect; the need for a 1 MB block size limit alongside the fee mechanism shows this all too well. In Ethereum, because of its Turing-completeness, a purely voluntary fee system would be catastrophic. Instead, Ethereum will have a system of mandatory fees, including a transaction fee and six fees for contract computations. The fees are currently set to: - -* TXFEE (100x) - fee for sending a transaction -* NEWCONTRACTFEE (100x) - fee for creating a new contract, not including the storage fee for each item in script code -* STEPFEE (1x) - fee for every computational step after than first sixteen in contract execution -* STORAGEFEE (5x) - per-byte fee for adding to contract storage. The storage fee is the only fee that is not paid to a miner, and is refunded when storage used by a contract is reduced or removed. -* DATAFEE (20x) - fee for accessing or setting a contract's memory from inside that contract -* EXTROFEE (40x) - fee for accessing memory from another contract inside a contract -* CRYPTOFEE (20x) - fee for using any of the cryptographic operations - - -The coefficients will be revised as more hard data on the relative computational cost of each operation becomes available. The hardest part will be setting the value of x. There are currently two main solutions that we are considering: - -* Make x inversely proportional to the square root of the difficulty, so x = floor(10^21 / floor(difficulty ^ 0.5)). This automatically adjusts fees down as the value of ether goes up, and adjusts fees down as computers get more powerful due to Moore's Law. -* Use proof of stake voting to determine the fees. In theory, stakeholders do not benefit directly from fees going up or down, so their incentives would be to make the decision that would maximize the value of the network. - -A hybrid solution is also possible, using proof of stake voting, but with the inverse square root mechanism as an initial policy. - - -## Conclusion - -The Ethereum protocol's design philosophy is in many ways the opposite from that taken by many other cryptocurrencies today. Other cryptocurrencies aim to add complexity and increase the number of "features"; Ethereum, on the other hand, takes features away. The protocol does not "support" multisignature transactions, multiple inputs and outputs, hash codes, lock times or many other features that even Bitcoin provides. Instead, all complexity comes from a universal, Turing-complete scripting language, which can be used to build up literally any feature that is mathematically describable through the contract mechanism. As a result, we have a protocol with unique potential; rather than being a closed-ended, single-purpose protocol intended for a specific array of applications in data storage, gambling or finance, Ethereum is open-ended by design, and we believe that it is extremely well-suited to serving as a foundational layer for a very large number of both financial and non-financial protocols in the years to come. - - -## References and Further Reading - -1. Colored coins whitepaper: https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit -2. Mastercoin whitepaper: https://github.com/mastercoin-MSC/spec -3. Decentralized autonomous corporations, Bitcoin Magazine: http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/ -4. Smart property: https://en.bitcoin.it/wiki/Smart_Property -5. Smart contracts: https://en.bitcoin.it/wiki/Contracts -6. Simplified payment verification: https://en.bitcoin.it/wiki/Scalability#Simplifiedpaymentverification -7. Merkle trees: http://en.wikipedia.org/wiki/Merkle_tree -8. Patricia trees: http://en.wikipedia.org/wiki/Patricia_tree -9. Bitcoin whitepaper: http://bitcoin.org/bitcoin.pdf -10. GHOST: http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf -11. StorJ and Autonomous Agents, Jeff Garzik: http://garzikrants.blogspot.ca/2013/01/storj-and-bitcoin-autonomous-agents.html -12. Mike Hearn on Smart Property at Turing Festival: http://www.youtube.com/watch?v=Pu4PAMFPo5Y -13. Ethereum RLP: http://wiki.ethereum.org/index.php/RLP -14. Ethereum Merkle Patricia trees: http://wiki.ethereum.org/index.php/Patricia_Tree -15. Ethereum Dagger: http://wiki.ethereum.org/index.php/Dagger -16. Ethereum C-like language: http://wiki.ethereum.org/index.php/CLL -17. Ethereum Slasher: http://blog.ethereum.org/?p=39/slasher-a-punitive-proof-of-stake-algorithm -18. Scrypt parameters: https://litecoin.info/User:Iddo/ComparisonbetweenLitecoinandBitcoin#SHA256miningvsscryptmining -19. Litecoin ASICs: https://axablends.com/merchants-accepting-bitcoin/litecoin-discussion/litecoin-scrypt-asic-miners/ \ No newline at end of file diff --git a/pages/white-paper/[japanese]-white-paper.md b/pages/white-paper/[japanese]-white-paper.md deleted file mode 100644 index 82945709d..000000000 --- a/pages/white-paper/[japanese]-white-paper.md +++ /dev/null @@ -1,1315 +0,0 @@ ---- -name: White Paper -category: ---- - -# Ethereum 白書 - -### 次世代 Smart contract と 分散型アプリケーション基盤 - -ナカモトサトシの論文により、2009年に開発された Bitcoin は通貨・貨幣における革新的な発明だと -謳われ、金兌換のような後ろ盾がなく、中央通貨管理局をもたないはじめての デジタル財産 の例です。( [intrinsic value](http://bitcoinmagazine.com/8640/an-exploration-of-intrinsic-value-what-it-is-why-bitcoin-doesnt-have-it-and-why-bitcoin-does-have-it/) ) しかし、その壮大な Bitcoin の実験における、より特筆すべき重要部は別の所にあります。 -それは分散型大衆決定のツールとして、まさにその基礎をなす Blockchain の技術であり、急速に人々の注目を集めつつあります。 - -一般的に、 -blockchain テクノロジーを引用している Bitcoin の代替アプリで、 -blockchain 上の電子財産を実装したものとして: - -* 一定取引量のある通貨や金融商品をあらわすもの([ colored coins ](https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit)) -* 基礎となる物理デバイスの所有権 ([ smart property ](https://en.bitcoin.it/wiki/Smart_Property)) -* ドメインのような投資対象外の財産 ([ Namecoin ](http://namecoin.org)) - -があり、より複雑なアプリケーションとしては以下のものが挙げられます: - -* ( 役人や銀行員に取って代わり、)コーディングであらゆるルールを実装し、個々の電子資産を管理するもの([ smart contracts ](http://szabo.best.vwh.net/smart_contracts_idea.html)) -* 上記のスマートコントラクトを blockchain 上で実装したもの ([ DAO ](http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/)) - -Ethereum が提供しようとしているものは、チューリング完全なプログラミング言語の完成品を - blockchain に埋め込み提供することにあります。 -この言語は、"contract" を生成するために使用され、 -"contract" とはあらゆる 関数 をプログラムしたものです。 -これにより、ユーザーは上記の全てのシステムを実装することが可能で、 -われわれがまだ想像すらしていない多くの可能性が、 -論理を秘めし数行のコードを書き上げるだけで実現できるようになります。 - - -### 目次 - -* [歴史](#歴史) - * [状態遷移システム としての Bitcoin](#状態遷移システム-としての-bitcoin) - * [採掘](#採掘) - * [マークル木](#マークル木) - * [Blockchain を用いた代替アプリケーション](#blockchain-を用いた代替アプリケーション) - * [スクリプト言語による記述](#スクリプト言語による記述) -* [Ethereum](#ethereum) - * [Ethereum アカウント](#ethereum-アカウント) - * [メッセージ と トランザクション](#メッセージ-と-トランザクション) - * [Ethereum の 状態遷移関数](#ethereum-の-状態遷移関数) - * [コード実行](#コード実行) - * [Blockchain と 採掘](#blockchain-と-採掘) -* [アプリケーション](#アプリケーション) - * [証明書発行のシステム](#証明書発行のシステム) - * [金融ディリバティブ と 安定価格通貨](#金融ディリバティブ-と-安定価格通貨) - * [Identity と Reputation のシステム](#identity-と-reputation-のシステム) - * [分散型ファイルストレージ](#分散型ファイルストレージ) - * [分散型自律組織](#分散型自律組織) - * [その他のアプリケーション](#その他のアプリケーション) -* [雑録 と 関心事](#雑録-と-関心事) - * [GHOST の修正実装](#ghost-の修正実装) - * [手数料](#手数料) - * [計算 と チューリング完全](#計算-と-チューリング完全) - * [通貨 と 発行](#通貨-と-発行) - * [マイニング集中](#マイニング集中) - * [スケーラビリティ](#スケーラビリティ) -* [結論](#結論) -* [脚注 及び 参考文献](#脚注-及び-参考文献) - -## Bitcoin への導入 と 既存の概念 - -### 歴史 - - -上述した資産登録マシンのような代替アプリや、 -分散型デジタル通貨の概念が現れ始めたのは、ここ数十年です。 -80〜90年代にかけて、David Chaum の「ブラインディング署名 blinding sgnature」をよりどころとした -匿名のデジタル通貨プロトコルがたくさん開発され、高いプライバシーをもつ通貨を提供しましたが、 -これらは中央集約型の媒体に依存していたため、広く注目を浴びるには至りませんでした。 -1998年に発表された、Wei Daiによる [b-money](http://www.weidai.com/bmoney.txt) が、 -現行の分散型のコンセンサスと同様の、計算問題を解くことによって -お金を創造するというアイデアを、はじめて導入した事例となります。 -しかし、このプロポーザルの詳細は不十分であったため、実用的な分散型の大衆意思決定を実装することができませんでした。 -2005年、Hal Finney が、暗号通貨のコンセプトをつくりあげるために、 -ABCD Hashcash パズル[jp-1] と b-money からアイデアをしぼり作られたシステムである "[reusable proofs of work](http://www.finney.org/~hal/rpow/)" というコンセプトを発表しましたが、バックエンドに、信用のある計算機を使用しなければならなかったため、真に分散型とは呼べず、再び失敗しました。 -2009年のナカモトサトシによる実用的な実装がはじめての分散型の通貨となりました。 -これは、昔からあった「公開鍵暗号(所有権を管理) 」と -大衆意思決定アルゴリズムである「 "proof of work" (誰がコインを所有しているのか追跡)」 -を結びあわせたものとなります。 - - -proof of work の背景にある技術は宇宙史に名を刻むほどの飛躍的進歩でありました。 -なぜなら proof of work は、同時に二つの難題を解決したのです。 - -* ひとつめは、単純明快で適切な影響力をもつ大衆意思決定のアルゴリズムの提供で、 -ネットワーク上のノードはBitcoinの帳簿の「一般規則に従う状態更新」ができるようになりました。 -* ふたつめは、大衆意思決定のプロセスへの自由参加を可能にするメカニズムの提供で、 -誰が、コンセンサスに影響をもたらすのかということを決める政治的問題を解決したのです。 - -これは次のようにして、参加基準を定式化したということです。 - -1. ノードに対し、特定リストにおける唯一性の証明書の提出を要求し、 -2. さらに「大衆意思決定のプロセスにおける単位ノードの重みは、ノードのもつ計算能力に応じて分配する」 -という エコノミックバリア[jp-2] を採用する - - - -### 状態遷移システム としての Bitcoin - -![statetransition.png](http://vitalik.ca/files/statetransition.png?2) - -技術的観点から見て、Bitcoin をはじめとした暗号通貨の帳簿は、全 bitcoin の所有状況をあらわす「状態」と、状態と取引(トランザクション、状態遷移関数のこと)から新たな状態を出力する「状態遷移関数」をもった、「状態遷移」のシステムと見てとれます。 -一般的銀行のシステムでは、たとえば「状態」はバランスシートにあたり、 -「トランザクション」はAからBにXドル移動してくれ、というリクエストにあたり、 -この状態遷移関数は、XドルだけAの口座の残高を減らし、Bの残高を増やします。 -もし、Aの口座の残高がXドルに満たなかった場合には、 -状態遷移関数はエラーを返します。 -このようして、定式化をすると - - APPLY(S,TX) -> S' or ERROR - -この銀行システムは以上で定義され、以下は適用例です。 - - APPLY({ Alice: $50, Bob: $50 },"send $20 from Alice to Bob") = { Alice: $30, Bob: $70 } - - APPLY({ Alice: $50, Bob: $50 },"send $70 from Alice to Bob") = ERROR - - -Bitcoin における「状態 state」とは、全コインの集合 であり、 -技術的に説明いたしますと、 -発行されているコインのうちで「UTXO(未使用の取引出力値)」の全集合 となり、各 UTXO には、それぞれ「残高」と「所有者」が記録されています。 -「所有者」は、基本的に、暗号理論における公開鍵[1]である20バイト(160bit)のアドレスとなります。 -「トランザクション」は、状態遷移関数であり、一以上の入力値 と 一以上の出力値 をとります。 -各入力値は、「既存の UTXO への参照」と「所有者のアドレスと関連付けられた秘密鍵による暗号署名」 から構成され、 -各出力値は、「新しく生成された UTXO」を保持しています。 - -状態遷移関数 `APPLY(S,TX) -> S'` を定義するプログラムの概略は以下となります。: - -1. For each input in `TX`: - * If the referenced UTXO is not in `S`, return an error. - * If the provided signature does not match the owner of the UTXO, return an error. -2. If the sum of the denominations of all input UTXO is less than the sum of the denominations of all output UTXO, return an error. -3. Return `S` with all input UTXO removed and all output UTXO added. - -ひとつめのステップにおける -前半部により、トランザクションの送信者が、存在しないコインを不正に送ることを防止し、 -後半部により、トランザクションの送信者が、他人のコインを勝手に送ることを防止します。 -ふたつめのステップによって、トータルバリューの保存(入力値の総計 が 出力値の総計 と等しい)が執行されます。 -これを実用的な支払いに適用するための、プロトコルは以下のようになります。 - -アリスがボブに 11.7BTC を送信したいとします。 -まずはじめに、アリスは、利用可能な UTXO を自分の持っているものの中からかき集め、 -少なくとも総計11.7BTCになるようにします。アリスの UTXO を集めてちょうど11.7BTCをつくることはできず、6+4+2=12 BTC がアリスの得る最小の値です。 -そして彼女は、3つの入力値と2つの出力値をもつトランザクションをつくります。 -ひとつめの出力値は11.7BTCでボブのアドレスが所有者として記録され、 -ふたつめの出力値は0.3BTCの"お釣り"がアリス自身を所有者として記録されます。 - - - -### 採掘 - -![block_picture.jpg](http://vitalik.ca/files/block_picture.png) - -もし、アクセス対象として信用取引可能な 中央集約型 のサービスを使っているのであれば、 -このシステムの実装は至極簡単なものであったでしょう。 -単に上記のプログラムコードを記すのに、中央サーバーのハードディスクを使用し、「状態」を記録・維持すれば済む話であったでしょう。 -しかし、わたしたちが Bitcoin を用いてやろうとしているのは、分散型通貨システムの構築です。 -なので、トランザクションの順番をみんなが合意できることを確約するために、 -状態遷移システム と 大衆意思決定のシステム をくっつけてやらなくてはなりません。 -Bitcoin の分散型大衆決定プロセスでは、「ブロック」と呼ばれる「トランザクションを梱包したもの」を作り続けようとする、 -ネットワーク上のノードが必要です。 -ネットワークは、だいたい10分毎にひとつの ブロック を生成するように設計されており、 -各々のブロックは、 - -* 「タイムスタンプ」 -* 「ノンス」 -* 「直前のブロックへの参照値」 -* 「(直前のブロック生成後から現在までに遂行された)トランザクションのリスト」 - -を保持します。( ※ ノンス:ブロック生成時にインクリメントされ続ける個体識別ハッシュ値で、マイナーがブロックを掘り当てることを目標にして独自にインクリメントする。) -このブロックが時間発展することによって、 -Bitcoin の帳簿を最新状態に更新し続ける、 -永続的かつ恒久的成長をなす " blockchain " (ブロックの鎖)を生成します。 - - -現パラダイム下において、ブロックが有効かどうかをチェックするアルゴリズムは以下となります: - -1. Check if the previous block referenced by the block exists and is valid. -2. Check that the timestamp of the block is greater than that of the previous block[2] and less than 2 hours into the future -3. Check that the proof of work on the block is valid. -4. Let `S[0]` be the state at the end of the previous block. -5. Suppose `TX` is the block's transaction list with `n` transactions. For all `i` in `0...n-1`, set `S[i+1] = APPLY(S[i],TX[i])` If any application returns an error, exit and return false. -6. Return true, and register `S[n]` as the state at the end of this block. - -基本的に -ブロック内の各トランザクションは、 -トランザクション執行前の 過去の状態 をもとにして、有効な状態遷移を提供しなければなりません。 -「状態」はいかなる点においても、ブロック内に記述されないことに注意してください。(ブロックは状態遷移関数をつなげ合わせた関数そのものであり、入力値 である「状態」については何も書かれていません); -(このアルゴリズムは、「検証ノード」を説明する簡単な抽象例であり、 -どのブロックの検証においても、開始状態から、全ブロックの全トランザクションを順番に適用することによって、目的となるブロックの示す状態を計算すれば十分となります。) -さらに「採掘者 miner」がトランザクションをブロックに取り込む順番がとても重要だということに注意してください。 -(もし、A、Bという二つのトランザクションがあって、BはAの生成した UTXO(未使用出力値) を使う場合において、 -AのあとにBがきているブロックは有効ですが、そうでない場合は無効となってしまいます。) - - -他のシステムでは見受けられない仕様として、 -上述のトランザクションリストにおいて「一有効性条件」(有効なものを一つ選ぶための条件)が - "proof of work" には必要となります。 -厳密な定義は、 -全てのブロックの double-SHA256 hash値(256bit の数値)が -動的に変化するように設計された「目的値 target」より小さくなること、であり、 -目的値は、これを執筆している当時では、約2187でした。 -これは、ブロック生成を計算科学上 "難しく" する為であり、 -その結果、Sybil Attack(ひとりでノードを多数生成し多数決的に攻撃する手法)による攻撃者が自身の好きなように 全 blockchain を改竄してしまうことを防止いたします。 -SHA256(エスエイチエーにごろ)は、完全に予測不可能な擬似乱数関数として設計されており、 -有効なブロックをつくる唯一の方法は、単に ノンス をインクリメントしてはその新しい hash値 が適合するかを確かめるという、試行錯誤を繰り返すしかありません。 - - - -現在における~2187の「目的値」では、 -ネットワークは~269 回の試行錯誤をしてやっとブロックを見つけることができます。 -ふつう、目的値 は、ネットワーク上で2016ブロック生成される毎に再設定され、 -ネットワーク上にあるノードによるブロックの発掘が平均して10分毎に生じるよう調整されます。 -採掘者に競わせてこの計算をさせるための設定として、 -ブロックを採掘したものは、どこからともなく湧いた自分への25BTCの報酬を、 -トランザクションとして最後に付け加えます。 -さらに、 -全入力値が全出力値よりも大きいような全てのトランザクションにおける、 -その差額は「取引手数料 transaction fee」として、採掘者のもとへ行く仕組みです。 -ところで、これはBitcoinが発行される唯一のメカニズムとなります。 -つまり、初期状態においては、Bitcoin は皆無であったわけです。 - - - -マイニングの目的をより深く理解するために、 -悪意ある攻撃者のおこす事件によって何がおこるのかを見ていきましょう。 -Bitcoin の基礎となる暗号理論はセキュリティの高いものと知られているので、 -攻撃者の狙い目としては、直接、暗号理論で守られていない部分 : トランザクションの順序 となるでしょう。 - -攻撃者の戦略は簡単なものです: - -1. ある商売人に 100 BTC をある商品の購入代金として送る (瞬間的な発送ができるデジタル商品が好まれます) -2. 商品の到着を待つ -3. 自分自身に 100 BTC を送る別のトランザクションを生成する -4. ネットワークが、後に作った方のトランザクションの順番が最初にくるようなブロックを、承認するように試みる - -一度、ステップ 1 が履行されると -数分後に採掘者がトランザクションをブロックに含めます。 -ブロック番号は 270000 とします。 -一時間後、5個以上のブロックが、そのブロックの後ろに追加され、 -この5つのブロックが、間接的にそのトランザクションを参照しているため、 -トランザクションは「承認 confirming」されたということになります。 -この時点で、 -商売人は、支払いが確定したものとみなし、商品を発送します。 -ここではデジタル商品を考え、商品がすぐに届くこととします。 -さていま、攻撃者が、別のトランザクションを作成し、自分宛に 100BTC を送るものとします。 -攻撃者が、もし単にそれを野に放っただけならば、 -そのトランザクションは受理されないでしょう。 -法の番人である採掘者は、`APPLY(S,TX)` を実行するとき、`TX` が、使用済みUTXO を使用しようとしていることに気づくでしょう。 -なので代わりに、 -攻撃者はブロックチェーンを分岐させ、 -親として同じ 269999 番目のブロックを参照する 270000 番目の新しいバージョンのブロックを生成します。 -ここでは、もとのブロックに含まれていたトランザクションは含まれず、新しいトランザクションが追加されていくこととなります。 -ブロックのデータの中身が違うので、 -攻撃者は proof of work をやり直す必要があります。 -さらに、攻撃者の新しいブロック 270000 では、異なるハッシュ値を生成するので、 -もとのブロックチェーン上のブロック 270001 ~ 270005 は、このブロックを参照しません。 -このように、もとのブロックチェーンと攻撃者のチェーンは完全に分断されるのです。 -このとき適用されるルールは次のようになります。 -ブロックチェーンの分岐時は、 -一番長いブロックチェーンが "信用" あるものとして選択されます。 -なので、攻撃者が新しい 270000 のブロックチェーン上で採掘し続ける傍で、 -このシステムの法の番人である採掘者達はもとの 270005 のブロックチェーンを採掘し続けることになります。 -攻撃者が、自分のブロックチェーンを最長にするためには、 -ネットワーク上の残りのすべてのノードの総和より、高い計算能力を誇る必要があり、 -これを「51%攻撃」と呼びます。 - - - - - - - - -### マークル木 - -![SPV in bitcoin](https://raw.githubusercontent.com/ethereum/www/master-postsale/src/extras/gh_wiki/spv_bitcoin.png) - - -_革新  :   -分岐の正当性の証明には、少しのノードを与えてやるだけでよい_ - -_伝統  :   -どの部分にいかなる変化を付与しても、鎖の上方で必ず不一致を生む_ - - - - - -Bitcoin の重要なスケーラビリティ特性は「ブロックは多層データ構造で保管される」ということです。 -ブロックの「ハッシュ値」とは実は、ブロックヘッダ(先頭部)のハッシュ値 に過ぎず、これは約 200 byte のデータであり、 - -* タイムスタンプ -* ノンス -* 直前のブロックの ハッシュ値 -* マークル木(ブロック内の全トランザクションを保持するデータ構造)の ルート(根の元となる部分)の ハッシュ値 - -を保持します。マークル木は、バイナリ木のひとつで、以下の三つから構成されます。 - -* 基礎データを保持する木構造の最下層の「葉(リーフノード)」の集合 -* 二つの 子ノード のハッシュ値である「枝(中間ノード)」の集合 -* 唯一の「根(ルートノード)」(二つの子ノードのハッシュ値で "頂上" にくるもの) - -マークル木は、ブロック中のデータをバラバラに運搬するためにつくられました。 -ノードは、ひとつのソース(ネットワーク上の自身とは別のノード)からブロックヘッダだけを、 -別のソースから、必要なトランザクションに関連する小さな部分木を、ダウンロードすることができ、それでもなお全データの整合性を保証できるのです。 -これがうまく動作する所以は、ハッシュ値が上に伝播していくところ です。: -もし悪意のあるユーザーが偽物のトランザクションをマークル木の底のノードと取り替えようとすると、この変化はその親のノードを変化させ、繰り返し伝播することで最終的にルートの値を変化させます。 -つまり、ブロックのハッシュ値が変化し、マークル木のプロトコルにより、結果として、全く別のブロックとして記録され、このブロックは十中八九 proof of work が無効となります。 - - -マークル木のプロトコルは、言うまでもなく長期にわたるアプリケーションの維持のために必要です。 -Bitcoin ネットワークにおける「完全ノード、フルノード」とは、「全ブロックの全トランザクションを保管・処理するノード」のことで、 -2014年4月の時点で 15GB の容量をとり、ひと月あたり1GB以上の速さで増え続けています。 -現在、これはデスクトップコンピュータ上で目視できますが、携帯電話では確認できません。 -容量的な観点から、後々の未来、完全ノード に参加できるのは、ビジネスや趣味の範疇に限られてくるでしょう。 -「SPV (簡素な支払検証)」として知られるプロトコルにより、「完全ノード」とは別タイプのノードが開発されました。 -「軽量ノード、ライトノード」と呼ばれ、このノードは、ブロックヘッダをダウンロードし、ブロックヘッダで proof of work を検証し、そして自身に関係のある トランザクションの「枝、ブランチ」だけをダウンロードします。 -軽量ノードは、セキュリティを強く保ったまま、トランザクション履歴や残高を、状態遷移関数により決定することができるというのに、 -全ブロックチェーンの小さな部分木をダウンロードすればよい、というものなのです。 - - - -### Blockchain を用いた代替アプリケーション - -基礎技術である blockchain の他コンセプトへの応用は、これもまた、長い歴史があります。 -2005 年 Nick Szabo が "[secure property titles with owner authority(自己の権威によるセキュアな財産の獲得)](http://szabo.best.vwh.net/securetitle.html)" というコンセプトを発表しました。この論文は、複製データベースの技術の進歩により、いかにして -blockchain 基調のシステムが、土地所有の登記 の保管を可能にするのかを記述し、 -「開拓 homesteading」「不法占有 adverse possesion」「ジョージの土地課税 Georgian land tax」といったコンセプトを含む枠組みを、苦労して築き上げました。 -しかし、残念ながら、当時利用できる、効果的な複製データシステムがなかったため、プロトコルが実際に実装されることはありませでした。 -とは言うものの、2009 年に Bitcoin の分散型コンセンサス が一度開発されてからは、急速に代替アプリが出現し始めました。 - - -* **Namecoin** - 2010年に作られた [Namecoin](https://namecoin.org/) は「分散型名前登録データベース」と表現されます。 -Tor や Bitcoin , BitMessage のような分散型プロトコルでは、個体識別に アカウント が必要で、そのため他人による干渉が可能ですが、 -どのようにしても利用可能な識別子は、`1LW79wp5ZBqaHW1jL5TCiBCrhQYtHagUWy`のような擬似乱数となります。 -できれば "ジョージ" のような名前をつけることができたらいいな、と考えるでしょう。 -しかしながら、問題なのは "ジョージ" という名前を誰でも、同じプロセスをたどることで登録でき、"ジョージ"として振舞えるのです。 -唯一の解決策は 「fist-to-file パラダイム」を用いることです。 -これは、最初(first)の登録者は登録(file)に成功し、二番目以降では失敗するというものです。 -この問題は Bitcoin の大衆意思決定のプロトコルに完全に合致し、 Namecoin は一早くにこの考えを使って名前登録のシステムを実装し、見事に成功しました。 - -* **Colored coins** - [colored coins](https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit) の目的は、Bitcoin の blockchain 上に「自身で作ったデジタル通貨」や、 -通貨の重要な性質である少額使用の例としてユニットを採用した「デジタルトークン」を、構築できるプロトコルを提供することです。 -colored coins のプロトコルでは、 -特定の Bitcoin UTXO に「色」を設定することで、 -新しい通貨を "発行" します。 -プロトコルは、colered coins を生成するトランザクションの入力値に「色」が付いていれば、他の UTXO も同じ「色」であるものと再帰的に定義します。 -(様々な「色」の入力が混じった場合は、特別なルールが適用されます。) -このことで、ユーザーは特別な色の UTXO だけを保持する財布を維持し、 -ほとんど Bitcoin と同じように周囲に対し送金することが可能で、 -受け取った UTXO の色を特定するには blockchain を遡ります。 - -* **Metacoins** - -metacoins の背景となる思想は「 Bitcoin を土台として、その上で動作するプロトコルをもつ」であり、 -metacoins のトランザクションの保管に、Bitcoin のトランザクションを使用しますが、Bitcoin とは別の 状態遷移関数 `APPLY'` を保持します。 -metacoins のプロトコルは、無効な metacoins トランザクションが Bitcoin blockchain 上にでてくることを防止するために、 -規則「 if `APPLY'(S,TX)` returns an error, -the protocol defaults to `APPLY'(S,TX) = S -」を加えます。 -metacoins は、任意の独自暗号通貨をつくるための 簡単なメカニズム を提供しており、 -Bitcoin 自体のシステム内部においては表面化することのない 先進的な独自機能 を持たせることができます。 -採掘とネットワークのシステムといった複雑な部分がすでに Bitcoin プロトコルによって処理されているので、 -開発コストはとても低く済みます。 -metacoins はいくつかの金融契約や名前登録や分散型両替所を実装するのに使われています。 - - -一般的に言って、大衆意思決定プロトコルを構築する方法は二種類あります。 -「独自のネットワークをつくる方法」と「Bitcoin を土台とする方法」です。 -前者の方法は、namecoin では適度な成功を収めたものの、実装するのが大変です。 -と言いますのは、独自の実装はそれぞれにおいて、独自のブロックチェーンをつくる必要があり、 -同様に、それに必要な状態遷移とネットワークを構成するコードのあらゆるビルド・アンド・テストが必要となります。 -さらに、そうしてできた分散型大衆決定のアプリケーションの数々の集合は、 -採掘(power)と検証(law)の分散を招き、仮にアプリケーションの中では多数派であったとしても、 -規模が小さすぎて自分のブロックチェーンを公正なものとすることができない、といった事態を招きます。 -そして次のことを認識するに至りました。 -大きな種類の分散型アプリがあったとして、とりわけ分散型自動組織では、 -それらはお互いに手を取り合わなければなりません。 - -一方で、「Bitcoin を土台とする方法」では、Bitcoin の SPV 特性 を継承しないという欠陥があります。 -SPV は Bitcoin では動作しますが、それは blockchain におけるブロックの「深さ」が その正当性 を代弁するためです。 -一度、トランザクションの祖先が深いところへ行ってしまえば、 -そのトランザクションは、現在の「状態」を構成する正当な状態遷移関数であると、安心して言うことができます。 -一方、meta プロトコル では、そのコンテクスト内でトランザクションが無効であっても、 -Bitcoin の blockchain において、それが組み込まれることを阻止する方法はありません。 -(Bitcoin のコンテクスト と Meta プロトコル のコンテクストは異なります。) -このように、もし、完全にセキュアな SPV meta プロトコルの実装 が存在したならば、 -あるトランザクションが有効かどうかを判定するために、 -Bitcoin の blockchain の一番最初まで全過程を遡ってスキャンする必要があるでしょう。現在、meta プロトコル の軽量実装は、データを提供する信用機関としてのサーバーに依存しており、 -言うまでもなく、とりわけ暗号通貨の当初の目的の一つが「信用機関の必要性の消去」であるような状況下では、最良の結果であるとは到底言えません。 - - -### スクリプリト言語による記述 - -たとえまったく拡張をせずとも、実は、Bitcoin プロトコルは「 smart contracts 」コンセプトの 機能的に弱いバージョン を簡単に実装したものなのです。 -Bitcoin の UTXO は、「公開鍵」に保持されるだけでなく、 -簡素なスタック・ベース・プログラミング言語で表現される少し複雑な「スクリプト」が、保持することもできます。 -このパラダイムの下で、 -トランザクションが、 -スクリプト保持の UTXO を 入力値 とすれば、 -スクリプトの記述内容を満たすデータが 出力値 となるように、 -トランザクションの記述がされなければなりません。 -さらには、 -基本的な 公開鍵保有メカニズム(その公開鍵を使用したトランザクションがブロック内にあるかどうかを検証するメカニズム) -でさえ、スクリプトを通して実装されています。 -そのスクリプトは、 -ブロック生成の証である 楕円曲線署名 を入力値として受け取り、 -トランザクションとその UTXO を所有するアドレス(公開鍵)に対してその署名を検証し、 -検証が成功すれば 1 を返し、そうでなければ 0 を返します。 -他にも、より複雑なスクリプトが様々な使用場面のために存在します。 -例えば、 -トランザクション検証の際、与えられた三つの鍵の組のうち二つの署名を必要とする スクリプト(マルチシグ multisig)や、 -企業アカウントや、セキュリティの高い口座アカウント、商売におけるエスクローが必要な状況に役立つ 初期設定 を構築することができます。 -スクリプトは、計算問題の答えに対する懸賞金の支払いにおいても使用され、 -「もしあなたがこの額の Dogecoin のトランザクションを送信したという SPV proof を提供できるならば、この Bitcoin はあなたのものだ」といったようなことを記述したスクリプトでさえ構築可能です。 -そして基本的には、分散型のクロス暗号通貨の取引が可能です。 - -しかしながら、Bitcoin に実装されたようなスクリプト言語にはいくつかの重要な制限があります。: - -* **チューリング完全性の欠如** - -つまるところ、Bitcoin スクリプト言語 は計算理論の大部分をサポートしていますが、ほぼ全てという訳ではありません。 -サポートしていない代表的なものとして ループ が挙げられます。 -これは、トランザクションの検証中に無限ループに陥る事を避けるために除外されました。 -理論的には、プログラマにとってはこれは簡単に克服できる障害で、if文と一緒に基本コードを繰り返せば、あらゆるループを模倣できますが、 -スクリプトを記録する(ブロックチェーン上の)スペースを極めて非効率に使用することになります。 -たとえば、楕円曲線署名の代替アルゴリズムをスクリプト上に実装したならば、 -全く同じである掛け算の命令セットが256回個別に記述されてしまいます。 - -* **値が定まらない問題** - -UTXO を保持する スクリプトが、取引量をきめ細やかに管理する方法はありません。 -たとえば、 -もしも、神のみぞ知るような内容の契約の大きな取引だっとしたら、それは価格操作等の生じうるヘッジング契約となってしまうでしょう。 -それは次のような状況です。 -AとBがそれぞれ $1000 相当のBTC をスクリプトに提出し、スクリプトが30日後に$1000相当のBTCをAに残りをBに送るものとします。 -30日後の 1 BTC の USドル価格 を決定するのには神託が必要となり、しかし、これは、現在利用可能な完全な中央集約型の方法でさえ、信用とインフラの観点で大きな改良がひつようとなります。 -しかしながら、 UTXO は使うか使わないかの2択なので、 -神託が提示しうるすべての価格を UTXO で表すには、2進数計算しかなく、そのため極めて非効率な UTXO の"ハッキング"が必要で、様々な残高の UTXO を用意する必要があります。 -たとえば、2k の値をもつ UTXO を k = 0 ,..., 30 まで 31個 つくれば良いでしょう。 - -* **状態の欠如** - UTXO は使うか、使われないかのどちらかを必ず決定してやらなければなりません。 -このため、内部に「状態」を保持する多層形式の契約やスクリプトを記述することができません。 -このことにより、多分岐選択可能な契約や、分散型取引のオファー、2段階の暗号理論による決定プロトコル(セキュリティの高い計算問題の賞金を与える場合に必要です)をつくるのはとても困難となってしまいます。 -さらに、 -UTXO は単純な一度きりの契約をつくることにしか使用できず、分散型組織のような、より複雑な「状態」を保持する契約を記述できず、 -meta プロトコルの実装を困難なものとします。 -また、値の定まらない2進数状態では、「引き出し制限」が不可能となります。これは重要なアプリケーションであり、大きな弊害であると言えるでしょう。 - -* **Blockchain が見えない問題** - -UTXO は、ノンス、タイムスタンプ、直前のブロックのハッシュといった blockchain のデータに対して盲目です。 -このことにより、スクリプト言語が、ランダム性の観点で潜在的価値のあるソースを参照するのを防いでしまい、 -ギャンブル・アプリケーションや他のカテゴリのいくつかを、厳しく制限してしまうことになります。 - -このように、 -暗号通貨の上に進化型のアプリケーションを構築する方法を3つ見てきました。 -ひとつめは、新しい blockchain を Bitcoin を土台とした上につくり、スクリプト言語を使用し、meta プロトコルを実装する方法です。 -ふたつめは、新しい blockchain をつくる方法で、その性質を決定するのに無限の自由が得られますが、 -開発時間に関するコスト問題、スタートアップに関する問題とセキュリティー面の問題も同様に得られます。 -みっつめは、Bitcoin のスクリプト言語を使用する方法で、開発や一般化は簡単ですが、 -可能性が限られてくること、meta プロトコルの実装は簡単ですが、スケーラビリティの欠点に悩むことになります。 - -Ethereum では、 -われわれは、代替となる骨格を築き上げ、 -簡単な開発であっても、大きな成果物が得られ、 -スマフォのようなライト・クライアントのもつ財産に対しても強固なものを提供し、 -同時に、アプリケーションが 経済環境 と blockchain セキュリティ とを共有できるものを提供することを意図しています。 - - -## Ethereum - -Ethereum の目的は、分散型アプリケーションのための代替プロトコルを創造し、 -大規模な分散型アプリケーションにとって、われわれが非常に役立つだろうと信じるところの、数々の修正を加え提供することであります。 -ここにおいて、アプリの高速開発にかかる時間、小規模かつ滅多に使われないアプリに対するセキュリティ、他アプリ間の効率のよい相互作用を可能とすること、が重要視されます。 -Ethereum は、基本的に究極の抽象基盤層となるものの構築により、以上の目的を果たします。 -究極の抽象基盤層とは、埋め込み型チューリング完全なプログラム言語を伴う blockchain であり、 -これにより、所有・トランザクションの形式・状態遷移関数に関する、任意の独自規則を創造することのできる機能を備えた - smart contracts と 分散型アプリ をだれでも記述することができます。 -Namecoin の骨格だけを抜き出した実装は、二行のコードで記述できます。 -通貨や評判を管理するシステムは20行以下で構築可能です。 -「 Smart contracts 」と呼ばれる暗号理論で実装された「箱」は、値を保持し、ある条件が整った時にだけ、解錠できます。 -この smart contracts は Ethereum プラットフォーム上に構築可能であり、 -チューリング完全性、値が定まる仕様、状態の保持および blockchain への参照が可能となるところから、 -Bitcoin スクリプトにはない、広大かつより強力なプラットフォームとなります。 - - -### Ethereum アカウント - -Ethereum では、「状態」は、「アカウント」と呼ばれるオブジェクトから作り上げられ、各「アカウント」は、20 byte の アドレス と、アカウント間における値や情報の直接的やりとりである 状態遷移 を保持します。Ethereum アカウントは4つのフィールドを含みます。 - - -* **nonce** 、各トランザクションの処理が一度きりであることを確約するためのカウンター -* アカウントの現在の **ether balance** -* アカウントの **contract code** (もし存在すれば) -* アカウントの **storage** (デフォルトは空) - -Ether は、Ethereum における主要な内部暗号燃料であり、トランザクション手数料を支払うために使用されます。 -一般的に、アカウントには二つの種類があります。 -秘密鍵により管理される **EOA (externally owned accounts)** と自身のコントラクトコードにより管理される **contract (contract account)** です。 -EOA はコードを持たず、EOA からトランザクションを生成し署名することによって メッセージ を送ることができます。contract では、メッセージを受信した時はいつも保持コードをアクティベートし、内部ストレージを読み書き可能にし、メッセージを送信するもしくは新しいコントラクトを作る、といった内容のことが順番に実行されます。 - -Ethereum における contract は履行されるべきあるいは一緒にコンパイルされるべきものというよりかはむしろ、 -Ethereum 実行環境を職場とする「自動金融エージェント」といったものに似ており、メッセージやトランザクションによって起動されたときには、いつもある特定のコードを実行し、自身の ether 残高と、なんども使う変数を把握するのに必要な key/value ストレージ を直接管理する権限を持っている、ということに注意してください。 - - -### メッセージ と トランザクション - -Ethereum において、「トランザクション」は、 -EOA から送られたメッセージを貯蔵する 署名付データパッケージ を参照するために使用されます。 -トランザクションは、以下を含みます。 - -* メッセージの受領人 -* 送信者を特定する署名 -* 送信者から受領人へ送られる ether の量 -* オプショナルデータフィールド(署名付きデータパッケージ) -* `STARTGAS` 値:トランザクションの実行にかかる 計算のステップ数 の最大値 -* `GASPRICE` 値:送信者が支払う、1計算ステップあたりの手数料 - -最初の3つは、どんな暗号通貨にもある標準的な、トランザクションの「フィールド」です。 -4つ目のデータフィールドは、デフォルトでは関数を持ちません。 -しかし、Ethereum 仮想マシンは、contract が使用する opcode を保持する必要があり、その際このデータフィールドが使用されます。 -opcodeとは、「 contract がデータにアクセスするのに使用する opcode(オペレーションコード)」です。 -もし、contract が blockchain 上のドメイン登録サービスとして機能しているならば、 -contract は投げられたデータをふたつの「フィールド」を保持するものとして解釈したがることでありましょう。 -ひとつめのフィールドは、登録するドメインで、ふたつめのフィールドはIPアドレスです。 -コントラクトは、 opcode によって、メッセージに含まれるこれらの値を読み込むことで、適切にストレージの中に配置することが可能となるわけです。 - -`STARTGAS` と `GASPRICE` のフィールドは Ethereum サービス に対するモデル拒否運動を封じ込める狙いがあります。 -偶発的あるいは故意による無限ループや他の計算理論的に無駄なコードの消費を避けるために、 -各トランザクションにはそれらが実行するコードの計算ステップ数の上限を設ける必要があります。 -計算の基本ユニットは「 gas 」と呼びます。 -たいてい、1計算ステップは 1 gas を消費します。 -しかし、幾つかの命令では、計算量的に見てより高価であるため、 -少しおおきな gas の量が必要とされます。 -また、状態の一部として保持しなければならないデータ量が増えたりします。 -トランザクションにデータを埋め込む際には、1 byte 毎に 5 gas の「手数料」もかかります。 -「手数料」システムの意図するところは、攻撃者に対し、計算資源や帯域、ストレージを含めた、 -彼らが消費する全リソースの量に比例した支払いを強要するためです。 -このようにして、ネットワークが消費するどんなリソースにも、それが大量消費とつながるような状況を生み出す、 -すべてのトランザクションに対して、消費量の増加に比例した gas の支払いを強要することとなります。 - - - -### Messages - -contract は他の contract に対して「メッセージ」を送信することが可能です。 -「メッセージ」はネットワークに対して配信されることがなく、 -Ethereum 実行環境内でのみ存在します。メッセージは以下を含みます。 - -* メッセージの送信者 (implicit) -* メッセージの受信者 -* メッセージと一緒に送信されるetherの量 -* オプショナルデータフィールド -* `STARTGAS` 値 - -基本的には「メッセージ」はトランザクションのようなものですが、 -contract により生成され、外部での動作はしない、という点で異なります。 -メッセージは contract が `CALL` opcode を実行している時に生成され、 -この opcode は「メッセージ」を生成し、実行します。 -トランザクションのように、 -メッセージは、そこに記述されたコードを実行する 受信者のアカウント へと導かれます。 -このようにして、contract はEOAのやり方と全く同じ方法で、他の contract と関係性をもつことができます。 - -ただし、以下のことに注意してください。 -トランザクションやコントラクトによって署名された gas の許容値は、そのトランザクションとトランザクション配下の実行ステップにおいて消費される gas の総量に適用されます。 -たとえば、もし、外部管理者である A が B に対し、1000 gas と一緒にトランザクションを送信し、B は、C にメッセージを送信する前に 600 gas を消費し、C の内部実行として戻り値を返すまでに 300 gas が消費されたとすると、 B は、「ガス欠」とならないためには、もう 100 gas を使用することが可能です。( ガス欠 となってしまうとエラーを返し、トランザクションは実行されません。) - -### Ethereum の 状態遷移関数 - -![ethertransition.png](http://vitalik.ca/files/ethertransition.png?1) - -Ethereum の 状態遷移関数, `APPLY(S,TX) -> S'` は次のように定義できます: - - -1. トランンザクションが 「 well-formed 」であるか(例えば、値が正しい数値であるか)チェックし、 -署名が有効であれば、ノンスが送信者のアカウントのものと合致するかチェックします。もし、そうでなければ、エラーを返します。 -2. トランザクションの手数料を `STARTGAS * GASPRICE` として計算し、署名から送信アドレスを決定します。 -送信者のアカウントの残高から手数料を差し引き、送信者のノンスを次の値へとインクリメントします。 -もし、残高不足であれば、エラーを返します。 -3. `GAS = STARTGAS` として、`GAS` 値を初期化し、トランザクションにおける byteデータ量 のぶんだけ byte あたり一定量の gas を支払います。 -4. 送信者のアカウントから受信者のアカウントにトランザクションの値を転送します。もし、受信者のアカウントが存在しないものであったならば、あたらしくつくります。もし、受信者のアカウントが contract であれば、すべての実行が完了するか、あるいは ガス欠 になるまで contract のコードを実行します。 -5. もし、送信者が十分なお金を持っていなかったり、 ガス欠 のために、値の転送が失敗した場合には、手数料の支払いを除いて、全状態を元に戻し、手数料はマイナーのアカウントに加えます。 -6. そうでなければ、余った全ての gas を全て送信者に返し、消費した gas は採掘者に支払われる手数料として送信します。 - - -たとえば、contract コード が以下であるような場合を考えましょう。 - - if !self.storage[calldataload(0)]: - self.storage[calldataload(0)] = calldataload(32) - -実際は、contract コードは低級EVM言語(アセンブラ)であることに注意してください。 -このコードは Ethereum における高級言語であるひとつである Serpent 言語で書かれており、コードを確約したものにするために、 -低級EVMコードへコンパイルすることが可能です。 -さらに次に記す状況を想定しましょう。 -この contract のストレージは空の状態から始まり、 -* 10 ether の値と、 -* 0.001 ether / gas の gasprice で 2000 gas 、そして -* 64バイトのデータ(0-31バイトが数字`2`を表し、32~63バイト番地が`CHARLIE`という string を表しているものとします。) - -の3つが、トランザクションとともに送信されるものとします。 -この場合、状態遷移関数のプロセスは以下のようになります。 - -1. トランザクションが有効かつ well-formed であるか確認する。 -2. トランザクション送信者が、最低限 2000 * 0.001 = 2 ether を所持しているか確認する。 -もし、所持していれば、2 ether を送信者のアカウントから差し引く。 -3. gas の量を gas = 2000; として初期化します。トランザクションのバイト長が 170 byte であるとすると、byte あたりの手数料が 5 であったことから、850 を差し引くことなり、1150 gas が残ります。 -4. 送信者のアカウントから 10 ether を差し引き、それを送信先である contract アカウントに加えます。 -5. コードを走らせます。今回はとてもシンプルです。 -まず contract は自身のストレージにおける `2` 番目の項目が使われているか確認し、 -未使用であることを確認し、ストレージの `2` 番地に `CHARLIE` という値をセットします。 - -この操作で、187 gas を消費するとしましょう、すると残りの gas は 1150 - 187 = 963 となります。 - -6. 963 * 0.001 = 0.963 ether を送信者のアカウントに返金し、結果として出てきた「状態」を返します。 - -もしも、トランザクションの受信側に contract がなかったら、当該トランザクションにおける全手数料は、たんに、トランザクションのバイト長に 与えられた `GASPRICE` の値をかけたものとなり、トランザクションと一緒に送られたデータは全く関係のないものとなってしまうでしょう。 - - -Note that messages work equivalently to transactions in terms of reverts: -もしメッセージが gas を使い果たしてしまったらば、そのメッセージあるいはそのメッセージが引き金となるすべての実行処理がもとにもどされてしまいますが、その「親」の実行に関しては、やり直しになる必要がありません。 -これは、contract が他の contract を呼ぶことに関して「安全」であることを意味し、これは、A が G gasもって B を呼び出すと、A による実行はたかだか G gas 分であることが保証されている、と捉えることができます。 - -最後に、contract を生成する opcode である `CREATE` があることに注意してください。 -その実行メカニズムは一般的に言って `CALL` に似ていますが、実行結果があたらしく作られたコントラクトのコードを返すという点を除いて同じになります。 - -補足:contract が実際に信用あるものとして、機能するかどうかについてですが、 -例として2人間の賭博をあげますと、二人のお金を預けることになるコントラクトはきちんと仕事をするという保証が必要です。 -片一方が作成し、騙し取るということが可能に思われます。しかし、これは簡単に解決できます。片方により作成されたコントラクトの公開鍵はわかっているので、そのコードが実行する内容は明るみにでており、エミュレーターを使って、きちんと動作することを確認することで、簡単にコントラクトの安全性を逐一確認することができます。 - - -### コード実行 - -Ethereum の contract コードは低級スタック・ベース・バイトコード言語で書かれており、「 Ethereum 仮想マシンコード 」や「 EVM code 」などと呼ばれております。 -そのコードは一連のbyte列から構成されており、各 byte はひとつの命令を表しております。 -一般的に、コード実行とは、プログラムカウンターが現在示すところの命令を実行してはプログラムカウンターを1つインクリメントする繰り返しにより構成される、無限ループであり、エラーや `STOP` あるいは `RETURN` といった命令が検出されるまで終わることがありません。 - -EVM における 命令 はデータを貯蔵するために必要な 三種類の スペース にアクセスします。 - -* **stack**, 後入れ先出しのコンテナで、push と pop という二つの命令により値を出し入れします。 -* **Memory**, 無限拡張および無限展開可能なバイト配列 -* **storage**, contract が保持する長期保存用ストレージで 、Key/value の貯蔵庫。スタックやメモリでは計算実行後毎にリセットされるのに対し、storage では長期間、値が保持される。 - -コードも、受信したメッセージにおける 値・送信者・データ にアクセス可能です。また ブロックヘッダ のデータにも同様にアクセスできます。コードは出力として byte 配列のデータ を戻り値として返すことも出来ます。 - -EVM コード における、形だけの実装が施された実行モデルは、驚くほどシンプルです。Ethereum 仮想マシン が動作しているとき、 -ネットワーク全体における、全仮想マシン計算状態 は次のタプルにより決定されます。`(block_state, transaction, message, code, memory, stack, pc, gas)` -ここで、 - `block_state` は、全アカウントを保持し、残高やストレージといったデータをひきこんだ「 global な状態 」を表します。 -実行の開始時毎に、「 命令 」は、変数`pc`番目の byte コードを取ってきます。`pc >= len(code)`の条件下では 0 となります。 -各命令はタプルに対して、どのように影響するのかという点に関して、独自の定義があります。 -例えば、 -`ADD` はスタックから、二つアイテムを引き出し(pop)、その合計をまたスタックへ押し込めます(push)。 -`SSTORE`は上部からふたつのアイテムを pop の上、二つ目のアイテムを contract のストレージにおける、一つ目のアイテムが示す番地に格納します。 -即時コンパイルによる EVM マシン実行最適化の方法はたくさんありにもかかわらず、Ethereum は基本的に、実装すると数百行ほどの byte コードスペースを費やします。 - -### Blockchain と 採掘 - -![apply_block_diagram.png](http://vitalik.ca/files/apply_block_diagram.png) - -Ethereum の blockchain は多くの点で Bitcoin のそれと似ていますが、いくつか違う点があります。 -bockchain のアーキテクチャに関する Ethereum と Bitcoin の違いは、次のようになります。 -Bitcoin とは違い Ethereum のブロックはトランザクションのリストとブロック生成時点の 状態 のコピーを内部に保持しています。 -脇道にそれますが、ブロック番号 と difficulty という、べつの二つの値もブロックに貯蔵されます。 -Ethereum における基本的な、ブロック有効化 アルゴリズム は以下となります。 - -1. ブロックの参照する 直前のブロック が存在し、それが有効であるかをチェックします。 -2. タイムスタンプが 、直前のにおけるそれよりも値が大きく、15分さきの未来まで後出のものより値が小さいことを確認します。 -3. ブロック番号、難易度、トランザクションのルート、Uncle のルート および ガスの上限(様々な、低級Ethereumの仕様概念)が有効であるか確認します。 -4. ブロックの有効証である proof of work が有効であるか確認します。 -5. 直前のブロックの最後の状態を `S[0]` とする。 -6. `TX` をトランザクション・リストとし、`n` 個のトランザクションを含むものとする。 -`0...n-1` までの全ての数に対し、`S[i+1] = APPLY(S[i], TX[i])` とする。 -もし、アプリケーション群のどれか一つでもエラーを返したり、ブロックで消費される全 gas 量がこの段階で `GASLIMIT` を超過していたりすると、エラーを返します。 -7. `S[N]` を `S_FINAL` としますが、採掘者へのブロック採掘に対する報酬も加えます。 -8. 状態 `S_FINAL` の マークル木 の ルート がブロックヘッダにおいて与えられる 最終状態のルート と一致するか確かめます。 -もしそうであれば、ブロックは有効で、そうでなければ、ブロックは無効です。 - -さっと目を通しただけでは、このアプローチはとても非効率に思うかもしれません。 -なぜならば、このやり方では、各ブロックで 全ネットワークの状態 を保存する必要があるからです。 -しかし、現実的には、Etherum の効率は、Bitcoin のそれと比べなければなりません。 -というのは、ここで 保存される状態 は、そのデータ木構造に貯蔵され、ブロック毎に、その小さな部分木が変更される必要があります。 -このようにすると、一般的に、隣り合う二つのブロック間では、木の大部分は同じとなるはずであり、 -そうであるがゆえ、データは、一度貯蔵され、ポインタ(つまり部分木のハッシュ値)を使用して二度 引用符 が付加される、という形式をとります。 -この「状態」の保存方法を達成するために「 パトリシア木 」と呼ばれる 特別なデータ木 が使われ、 -パトリシア木は、マークル木のコンセプトに対して修正がなされており、ノードの挿入・削除が可能であり、 -ただ変わるだけでなく、効率が良くなります。 -さらに、全状態の情報が、最新のブロックに含まれますので、ブロックチェインの全履歴を保存する必要がありません。 -これは、Bitcoin に適用されたら、5 - 20倍のスペース節約になる 技術戦略 です。 - -ひろく尋ねられるのが、「どこで contract が実行されるのか」という質問で、物理デバイス上でどこか?ということです。 -この質問に対しては、シンプルな回答があります。 -「 contract の実行プロセスは、その状態遷移関数の定義の一部であり、それ故ブロックの有効化アルゴリズムの一部となります。 -なので、もしトランザクションがブロック `B` に付加されたならばそのトランザクションにより生まれるコード実行は全てのノードで実行されます。 -その時点より未来において、ブロック`B`をダウンロードした全てのノードということです。」 - - -## アプリケーション - -一般的に、Ethereum 上には、3 種類のアプリケーションがあります。 -一つ目のカテゴリーは、金融系のアプリケーションで、金銭を使用する契約に対し、導入・管理の強力な手段をユーザへ提供するものです。 -これには、副次通貨、金融ディリバティブ、ヘッジング契約、預金、資産相続文書や、さらに言及しますと、労働契約書まるまる含めたものなどがあります。 -二つ目のカテゴリは、準金融系アプリであり、非金融的事象の結果に対して金銭を絡めてくるようなもので、その良い例として、計算理論における難題に対し懸賞金を自動執行するようなアプリが挙げられます。 -三つ目としては、オンライン選挙 や 分散型統治機構 があります。 - - -### 証明書発行のシステム - -ブロックチェイン上の 証明書発行システム (token system) には、多々のアプリケーションがあり、 -USドルや金を表す副次通貨から、株式、スマートプロパティとして個人発行した証明書、堅牢で偽造不可な商品券、あるいは全くの無から新たに作られた貨幣証書でさえその範囲に含まれ、経済原理となる(人々の行動の動機付けとなる)ポイント(稼ぎ)のシステムとして使われます。 - -Ethereum 上で 証明書発行システム を実装するのは驚くほどに簡単です。 -理解するために重要点は、 -通貨や証明書システムといった基軸となるものはすべて、 -あるひとつの操作をともなうデータベース だということです。 -そのひとつの操作とは : - -``` -A から X 単位を差し引き、それを B にやる -その時の条件として -(1) A は トランザクション以前に 少なくとも X 単位 を保持している -(2) トランザクションが A によって承認される -``` - -トークンシステムの実装するのにかかる手間は、このロジックを contract に実装するだけです。 -トークンシステムの Serpent における実装の基本コードは以下のようになります: - - def send(to, value): - if self.storage[msg.sender] >= value: - self.storage[msg.sender] = self.storage[msg.sender] - value - self.storage[to] = self.storage[to] + value - -これは、基礎的に、このドキュメントの冒頭で説明した"銀行システム" の状態遷移関数の文字通りの実装となります。 -このコードとは別に、初期化ステップとして通貨単位を共有するあるいはその他特例のために、数行必要となり、 -理念としては、ある function は、他の contract に、あるアドレスの残高を探索してもらうために追加されるものですが、 -コードの記述はこれで十分です。 -理論的に、Ethereum 基盤の証明書発行システムで副次通貨としてふるまうものは、 -潜在的に別の重要な特徴を持っています。それは Bitcoin 基盤の meta currency には無いもので、 -副次通貨で直接トランザクションの手数料の支払いが可能だという機能です。 -もしこれを実装すらならば、 -手数料支払いに使用される ether を送信者に 再振込 する方法をとり、 -contract は、その時の ether 残高を維持管理することになるかと思います。 -手数料支払い時、および常駐のオークションにおいて副次通貨を再度売る時、に使用される、この内部保持されている副次通貨単位を集めることで、ether の残高を再度満たすことになるでしょう。 -ユーザはこのため ether でアカウントをアクティベートする必要がありますが、 -一度 ether が確認されると、contract がその度ごとに再度振込をするので、再利用可能となるでしょう。 - - -### 金融ディリバティブ と 安定価格通貨 - -金融ディリバティブ は、最も一般的な、smart contract のアプリケーションであり、コード実装が最も簡単なもののひとつです。 -金融契約の実装における主な試練は、その大部分が価格表示器への外部参照が必要となるということです。 -例えば、とても望ましいアプリケーションの例として、USドルに対するEther のボラティリティ(取引規模に由来する凶暴性)に対して、ヘッジ(囲い込み:高値で売り、安値で買う)をおこなう smart contract がありますが(これは価格安定化に寄与します)、 -これを行うには、ETH/USD の価格がいくらであるかを知るための contract が必要となります。 -いちばんシンプルな実行方法としては、必要に応じて contract を更新する能力をもつように設計された(NASDAQのような) 特定のパーティにより維持管理される「 データフィード contract 」を通す方法があります。これにより、他の contract はそのデータフィード contract にメッセージを送信し、価格情報が与えられた返答を受け取ることができます。 - - -それらの深刻材料が与えられた条件下において, ヘッジング contract は次のようになるでしょう : - -1. パーティ A が 1000 ether 入金するのを待ちます -2. パーティ B が 1000 ether 入金するのを待ちます -3. 1000 ether の USD での価値を記録します。これはデータフィード contract を探索することで計算され、ストレージに対し、「Xドルだ」と告げます(記録します) -4. 30日後、(データフィード contract から得られた新しい価格によって計算された)Xドル相当の ether をAに送信し、 -残りをBに送るのに、A もしくは B が 該当 contract を再アクティベートすることができるようにします。 - - -このような contract には暗号取引における重要な潜在価値があるでしょう。 -暗号通貨を取引等に引用するときに現れる主要な問題として、極めてボラティリティが高いということがあります。 -多くのユーザや商売人が暗号通貨の取引の利便性やセキュリティを望んでいるかもしれないにもかかわらず、 -たった1日で資金の23%を失うという場面には直面したくないでしょう。 -この問題に対して、いままでに提案された、最も一般的な解決策としてあるのは、発行者の後ろ盾のある財産 です。 -この考えは、発行者が発行並びに無効化の権利を有した副次通貨をつくり、 -金やUSDのような特定の基礎財産の一単位をオフラインで提供する全ての人に対し、その副次通貨の一単位を提供するというものです。 -そして発行者は、暗号副次通貨が送り返されたときには、基礎財産を提供することを約束します。 -この仕組みによって、全ての非暗号化財産が、暗号財産へと "上場" されることが可能となりますが、これは発行主体が信用可能であることにより実現します。 - - -しかし実際は、発行主体は常に信用に価するとは限らず、 -中には、その銀行システムはあまりにも脆弱であったり、 -あまりにも顧客対抗的であるようなことが見受けられ、 -これは金融サービスとしてはとてもあるまじきものとなりえます。 -金融ディリバティブ はこれに取って代わり、よりよいサービスを提供します。 -金融ディリバティブにおいては、財産をバックアップするための資金を提供する単一の発行主体の代わりに、 -分散型の投資市場、つまり ETH ような暗号参照財産の価格が上昇するか賭けをする場所、がその役割を担います。 -発行主体とは違って、投資家は自分たちの都合で売り出しをなかったことにすることができません。というのは、「 ヘッジング contract 」がエスクローとして資金を保持しているからです。この方法でも、まだ完全に非中央集約化したわけではないことに注意してください。というのは、価格表示器を提供するのに信用あるデータソースが必要となります。とはいうものの、中央集約型のインフラに対する要求事項を減らし、かつ詐欺の潜在性を減らした点で大きな進歩と言えます。(副次通貨の発行主体となるのとは違って、価格データの発行はライセンスが必要とされず、表現が自由な範疇に分類される可能性が高いのです。(そのため参入への垣根が低い自由競争をもたらします。)) - - -### Identity と Reputation のシステム - -すべての代替暗号通貨のなかでいちばん早くに登場した [Namecoin](http://namecoin.org/) は、 -名前登録サービスに Bitcoin と似た blockchain を用いる試みを行いました。 -そこでは、ユーザは他のデータとともに 名前 を公共的なデータベースに登録することができます。 -Namecoin の最も広く普及した利用方法は、[DNS](http://en.wikipedia.org/wiki/Domain_Name_System) システムとして使う方法で、 -"bitcoin.org" のような名前を、IPアドレスに対応( mapping )づけたものです。 -他の使用方法として、email authentication や、潜在的発展性のある reputation システム などが考えられます。 -以下に、Namecoin に似た名前登録システムの Ethereum 上での、基本 contract を示します。 - - def register(name, value): - if !self.storage[name]: - self.storage[name] = value - -contract はとてもシンプルです。 -システムの全容は、追加のみが可能で削除および修正が不可能な Ethereum ネットワーク内部にあるデータベースです。 -誰でも、幾つかの値とともに名前を登録することが可能で、その登録内容は永遠に保管されます。 -より洗練された名前登録 contract は、他の contract がその内容を探索できるようにするための 関数節( (内部)関数 )をもつでしょう。 -同様に、(例えば、初期登録者のような) 名前の所有者 がデータを変更したり所有権を移行したりするためのメカニズム のようなものも考えられます。 -reputation や web上の信用度 といった機能性さえ、システムの上層に追加可能です。 - - - -### 分散型ファイルストレージ - -過去数年にわたり、オンライン上でのファイルストレージ・サービスのスタートアップが出現し、たくさんの非常に人気あるものが生まれました。 -一番人気のあるのが、Dropbox です。ユーザはハードドライブのバックアップをアップロードし、保管してもらうことが可能で、月額使用料と引き換えにそのデータにアクセスできます。 -しかしながら、使用料金支払いの点でファイルストレージの市場は比較的非効率です。 -この使用料金問題に関する様々な[現存の解決方法](http://online-storage-service-review.toptenreviews.com/)を概観しても、" uncanny valley "と呼ばれる、20-200 GBレベルでは、無料利用や企業割引が全く存在せず、ファイルストレージのアクセスに対する月額料金は、同等容量のハードドライブの調達に要する全コストをたった一ヶ月のうちに上回ってしまいます。 -Ethereum の contract によって、分散型ファイルストレージという新しい経済圏を開発することが可能で、そこでは、個人ユーザが自分のハードドライブを貸し出すことで、小遣い稼ぎが可能となり、さらに未使用領域が使用されれば、ファイルストレージのコストは下がります。 - -そのようなデバイスを裏で繋ぎとめておくための 鍵 として、" 分散型 Dropbox contract " と命名したものがあります。 -この contract は次のように動作します。 - -1. まずはじめに、保存したいデータをブロックに分割し、プライバシーのために各ブロックを暗号化し、 -その暗号化したブロック群から、(データ保管木として)ひとつのマークル木を作り上げます。 -2. N ブロック毎に、contract は マークル木からランダムに参照先を選び、 -(ランダム性を提供するものとしては直前のブロックハッシュを使用し、contract コードでアクセスできるようにします)、 -そのデータ木におけるその特定の参照先におけるそのブロックの所有のSPV証明のようなもの(ブロックを預けた人は当然ながら秘密鍵を持っており、その預け人の出すクイズに対して簡潔に回答した証明書)を載せたトランザクションを一番はじめに提供した個人に対して、X ether を与えます。 - -ユーザがそれらのファイルを再ダウンロードしたいときは、 -[micropayment channel プロトコル](https://bitcoinj.github.io/working-with-micropayments) を使用することができ、 -(例えば 32 KBで 1 szabo 支払うといった具合で、) ファイルを復元することできます。 -micropayment channel を利用した最も支払い効率のよい方法は、 -支払い者がその終わりまでトランザクションを発行せず、 -かわりに、そのトランザクションを32KB毎に同じノンスを使用して -微量ではあるもののより利益を生むトランザクションに置き換え続けるというやり方です。 - -この 分散型 dropbox protocol の重要な性質として、 -預け人はたくさんの乱雑なノードがファイルを忘れてしまうという決定をしないものと信用しているように見えるかもしれませんが、 -秘密共有を通して、ファイルをたくさんの断片へと分割することで、また各断片がどこかのノードに未だに保存されていることを確認するために contract を監視することで、そのリスクは限りなくゼロに近づきます。 -もし、その contract がお金の支払いを続けていたならば、それは、誰かまだファイルを所有している人がいるといった 暗号学的証拠 を提供していることとなります。 - - - -### 分散型自律組織 - -分散型自律組織 Decentralized autonomous organization (DAO) の一般的な概念としては、 -会員あるいは株主が、67%以上の多数派を占めると、contract コードの修正や、資金の消費が可能となる、仮想団体としてのものです。 -会員であれば、まとまることで資金の使い道を決定することができるでしょう。 -資金の使い道としては、懸賞金、給料、あるいは、労働報酬として使用価値のある域内通貨のような、 -異文化地域における仕組みにさえ、適用するこができます。 -これは基礎的に、 -伝統的な会社や非営利組織を合法的にとらえることのできる枠組みでありますが、 -執行に際し使用するのは、暗号理論に則った blockchain テクノロジー だけとなります。 - -DAO の議論をさらに進めると、配当株主や株券をともなう 分散型自律株式会社 DACorp (decentralized autonomous corporation) といった資本主義を推し進めるモデルに行き当たりました。 -代案としてある、分散型自律共同体 DACom (decentralizd autonomous community) では、 -会員の除名あるいは入会を承認するといった決定に関し、全会員が平等に権利を保持し、在籍会員の67%の承認を必要とします。 -というのは、一人一会員のみという要望があれば、グループによってまとまって執行される必要が有るのです。 -(非中央型自動株式会社では、当然大株主が決定権を支配するので、こういった要望は、却下されるでしょう。) - -DAO をコード化する方法の概要は次のようになります。 -一番シンプルな設計を示しますと、それは「もし、2/3の会員が賛同すれば、変更する」といった 自己修正コード です。 -理論的には contract コードは不変なものですが、 -別のところに contract を複数保持し、 -ストレージは修正可能なので、そこに呼び出す contract のアドレスを保持することで、 -事実として、contract の書き換えが可能となります。 -DAO contract のようなものの簡素な実装において、そのトランザクションが提供するデータによって、 -三種類に分けることができます。 - -* `[0,i,K,V]` to register a proposal with index `i` to change the address at storage index `K` to value `V` -* `[0,i]` to register a vote in favor of proposal `i` -* `[2,i]` to finalize proposal `i` if enough votes have been made - -contract はこれら各種類ごとに、複数の条項を持つでしょう。 -contract は、誰が投票したかというリストに従い、全オープンストレージの書き換えを維持管理するでしょう。 -さらに、contract は、全会員のリストも保持するでしょう。 -どんなストレージの変化も、それが投票する会員の2/3に達したとき、ある最終決定トランザクションがその変化を執行できることとなるでしょう。 -より洗練された枠組みとしては、 -トランザクションの送信、会員の除名や入会のような特徴を組み込んだ投票システムを保持するものもあり、 -そして流動的民主主義 [Liquid Democracy](http://en.wikipedia.org/wiki/Delegative_democracy) スタイルの代議員議会の投票でさえ提供可能です。 -(※誰でも代議員選出が可能で、その選出投票は、遷移的であり、結果、もしAがBを、BがCを選出したならば、CはAの投票権を保持することになります。) -この設計であれば、DAO は分散型コミュニティとして、有機的成長を遂げることが可能で、 -民衆は結果的に、会員の選出作業を専門家に委任することが可能となります。 -しかし、これは "現行の政治システム"にみうけられるようなものとは異なり、 -個々のコミュニティメンバが提携先を変えることで、時間軸上において、専門家は簡単に出現と消失(取り替え)することが可能です。 - -代わりとなる分散型株式会社のモデルでは、0以上の株式をもつアカウントがあり、株式の 2/3 が決定に必要とされます。 -完璧な枠組みとしては、財産管理機能や、株式売買の申請機能および受諾機能を備えたものがあるでしょう。( contract 内部に注文一致させる機能があることが望ましいでしょう) -代議員選出による委任は、流動的民主主義を存在させ、" 意思決定機関 " という概念を一般化するものでしょう。 - - -### その他のアプリケーション - -**1. 預金ウォレット**. 次のような場面を考えて下さい。アリスは、自分の資金を安全に管理したいとします。 -しかし彼女は、資産を失うことや秘密鍵がハッキングされることを心配しています。そこで彼女は、銀行となるボブとともに、 -contract をつくり、ether をその中に保管します。それは以下のようになります。 - -* アリスは自分一人で1日あたり最大資金の1%を引き出すことが可能です。 -* ボブは自分一人で1日あたり最大資金の1%を引き出すことが可能です。しかし、アリスは自分の秘密鍵でこのボブの能力を奪い去るトランザクションを作成することができます。 -* アリスとボブは一緒であればどんな額でも引き出し可能です。 - -通常、1日1%というは、アリスにとって十分な額であり、もしそれ以上引き出したいのであれば、ボブに頼めば済む話となります。 -もし、アリスが秘密鍵をハッキングされたならば、アリスは、ボブのところに駆け寄り、ふたりで新しい contract に資金を移します。 -もし、彼女が秘密鍵をなくしてしまえば、結果として、ボブは資金を引き出すことになるでしょう。 -もしも、ボブが悪意をもっているとわかったならば、アリスは、ボブの引き出し能力を消去できます。 - -**2. 農作物保険**. 金融ディリバティブ contract は簡単に作成可能ですが、データフィードとして、価格表示器でなく天候を使用します。 -アイオワ にいる農家が、逆にアイオワ における降水量を基盤として逆に支払いをするディリバティブを購入したとすると、 -もし干ばつがあったならば、農家は自動的にお金を受け取り、もし十分な降水があったなら、作物が同様の働きをしてくれるので、農家は幸運を手に入れることができます。これは一般的に、自然災害の保険にも拡張可能です。 - -**3. 分散型データフィード**. 金融 contract その他において、"[SchellingCoin](http://blog.ethereum.org/2014/03/28/schellingcoin-a-minimal-trust-universal-data-feed/)" と呼ばれるプロトコルを通してデータフィードを分散化することが実際可能です。 -SchellingCoin は基本的に次のように動作します。 -N 個のパーティが全て、ある与えられた一つのデータ(例えば ETH/USD の価格)の値をそれぞれ提供するものとします。 -その価格の値はソートされ、その値の順番が 25% ~ 75% であるものが、報酬を得られるようにします。 -全員が、他の全員が提供するだろう答えを提供するインセンティブを保持し、その大多数のプレイヤが現実的に認める唯一の価格が、明白な基準となり、これは信用のおけるものとなります。 -これによって、理論的にどんな数値をも提供することが可能な、分散型プロトコルが作られます。 -それには、ETH/USD価格、ベルリンの気温、あるいは特定の重い計算の結果、でさえ含まれます。 - -**4. スマート・マルチシグネチャ 認証**. Bitcoin では マルチシグネチャ・トランザクション contact が可能で、例えば、5つの秘密鍵のうち、3つが揃えば資金を使用できるといったものです。 -Ethereum では、より詳細な設計が可能です。たとえば、5つのうち4つで全て使用可能とし、5つのうち3つで1日10%使用可能とし、5つのうち2つで1日0.5%使用可能とすることができます。 -加えて、Ethereum マルチシグネチャは同期します。というのは二つのパーティが、別々の時間に blockchain 上に署名を登録することが可能で、その最後の署名が行われれば、自動的にトランザクションは送信されます。 - - -**5. クラウド・コンピューティング**. EVM テクノロジは、検証可能な計算環境を構築する目的でも使用され、 -ユーザは他人に対して、計算の実行を依頼することができます。またオプションとしてランダムに選択したチェックポイントにおける、計算の整合性を示した証拠の提出を依頼することができます。 -これによって、クラウド・コンピューティングの市場を作ることが可能で、どんなユーザでも、デスクトップ型あるいはノートパソコンあるいは特化型サーバを用いて参加することが可能です。そして、セキュリティ課金を用いたスポットチェックにより、システムが信用に足るかということを確かめます。(結果ノードはチートすることによって、より利益を得ることはできません。) -このようなシステムは、あらゆるタスクに適する、ということはないかもしれません。たとえば、内部プロセスにおける高度な連携が必要なタスクだと複数のノードによる大きなクラウドにおいて、簡単に計算することは不可能です。 -しかしながら、他のタスクは容易に並列化可能で、SETI@home 、folding@home や 遺伝的アルゴリズム のようなプロジェクトは簡単に、プラットフォーム上に構築可能です。 - -**6. P2P 賭博**. P2P賭博プロトコルはいくらでも実装可能で、例えば、 -Frank Stajano と Richard Clayton による [Cyberdice](http://www.cl.cam.ac.uk/~fms27/papers/2008-StajanoCla-cyberdice.pdf) は Ethereum blockchain 上で実装できます。 -簡素な賭博プロトコルは実はただの次のブロックのハッシュ値を当てるだけの contract で、より進化したプロトコルはそこから作り上げることが可能で、チート不可能な手数料が0に近い賭博サービスを作ることができます。 - -**7. 市場予測**. SchellingCoin あるいは Oracle が提供されることで、市場予測もまた実装が容易となります。 -市場予測と SchellingCoin が一緒になることで、非中央組織の統治プロトコルである [futarchy](http://hanson.gmu.edu/futarchy.html) の主流アプリケーションとしては初のものと成る可能性があります。 - -**8. blockchain 上の商取引市場**, Identity と Reputation のシステムを基盤とします。 - - - - - -## 雑録 と 関心事 - -### GHOST の修正実装 - - -Greedy Heavist Observed Subtree (GHOST) は、Yonatan Sompolinsky と Aviv Zoharによって[2013年12月](http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf)に初めて導入されたイノベーションです。 -GHOST開発の動機は、blockchain の検証時間を短縮すると、 -現行のシステムでは、「非同期状態」(最新のブロックと同期していない状態)の割合が増えるため、 -セキュリティを減少させてしまうという問題に苦しんでいます。 -というのは、ブロックはネットワークを通して伝播するのにある程度の時間がかかるため、 -もし、マイナーAがブロックを発掘し、つぎにマイナーBがたまたまAのブロックがBに伝わってくる前にその他のブロックを見つけた場合、 -マイナーBのブロックは最終的に無駄となり、ネットワークセキュリティに貢献しないこととなります。 -さらには中央集約の問題があります。 -それは、もしマイナーAが30%の採掘能力を持つマイニングプールで、Bが10%の採掘能力を持つものとすると、 -Aには、採掘時間の70%は無効なブロックを生成するリスクがあり、 -(採掘時間の30%のあいだ、Aは有効な最終ブロックを生成しているということなので、採掘データをすぐに得る事ができます。) -一方、Bには、採掘時間の10%は無効なブロックを生成するリスクがあります。 -このよう状況で、 -ブロック生成の間隔が「非同期状態」の割合が高くなるぐらいに十分、ブロック間のインターバルが短いと、 -Aは、単に自身のプールのサイズから得られる効能によって、実質上さらに効率的となります。 -これら二つの効果が結びつくことで、 -ブロック生成の速いブロックチェーンは、ネットワーク上の採掘能力のうち大きな割合を占めやすくなり、 -マイニングのプロセス全体をコントロールできるマイニングプールを生み出してしまいます。 - -Somopolinsky と Zohar の説明によると、 -GHOSTは、最長チェインの計算上において、無効ブロックを採り入れることで、 -一つ目のネットワークセキュリティ損失の問題を解決します。 -つまり、親ブロックや先祖ブロックのみでなく、 -proof-of-workの裏付けされネットワーク上で最長チェインを誇る、 -先祖ブロックの無効な子孫ブロック ( ethereum 用語では 「 uncle (叔父) 」) が計算に加えられます。 -二つ目の中央集約のバイアスがかかるという問題を解決するためには、 -Somopolinsky と Zohar によって描かれたプロトコルのさらに先を考える必要があり、 -無効ブロックへの報酬を供給する必要があります。 -無効ブロックは元となる報酬の87.5%を受け取り、 -uncle として無効ブロックを採り入れた nephew (甥)ブロックには残りの12.5%が贈られます。 -しかしながら、トランザクション手数料は uncle には与えられません。 - -Ethereum は、7層だけ遡る簡易版 GHOST を実装しました。 -仕様としては以下の通りです。 - -* A block must specify a parent, and it must specify 0 or more uncles -* An uncle included in block B must have the following properties: - * It must be a direct child of the kth generation ancestor of B, where 2 <= k <= 7. - * It cannot be an ancestor of B - * An uncle must be a valid block header, but does not need to be a previously verified or even valid block - * An uncle must be different from all uncles included in previous blocks and all other uncles included in the same block (non-double-inclusion) -* For every uncle U in block B, the miner of B gets an additional 3.125% added to its coinbase reward and the miner of U gets 93.75% of a standard coinbase reward. - -この制限版の GHOST では、7世代上までの uncle を取り込みますが、これが採択されたのには2つの理由がありました。 -ひとつめとして、無制限の GHOST だと、与えられたブロックに対し、どの uncle が有効なのか確かめる計算が複雑になりすぎます。 -ふたつめとして、無制限の GHOST と Ethereum で使用されている報酬の方法が合わさると、採掘者が、メインチェイン上で採掘する動機を取り去ってしまい、攻撃者のチェインにおいてはそうでないので、攻撃されすくなります。 - - - -### 手数料 - -blockchain 上に発行される全トランザクションは、ネットワークに対し、 -ダウンロードと検証に際し必要なコストの支払いを強いるので、 -乱用を防ぐために、トランザクション手数料に代表される、何らかの規制メカニズムが必要となります。 - - -Bitcoin でとられている初期のアプローチでは、純粋な寄付金としての手数料をとり、 -採掘者に対し、「門番」の役割と動的な最小額を決める役割を依頼しています。 -このアプローチはBitcoinコミュニティには好意的に受け入れられました。 -これには、採掘者とトランザクション送信者間の需給バランスにより価格が決まる、といった市場原理に基づくという理由があります。 -しかしながら、この論理の道筋には問題があって、トランザクションの処理は市場ではないのです。というのは、 -トランザクションを採掘者が送信者にオファするサービスと捉えることには本質的魅力がありますが、 -実際は、採掘者が採り入れた全トランザクションは、ネットワーク内の全てのノードにおいて処理される必要があるため、 -トランザクション実行のための大きなコストはサードパーティによって担われ、 -あるトランザクションを取り入れるかどうかの決定は採掘者に担われている訳ではないのです。 -このような仕組みでは、コモンズの悲劇の問題が発生する確率が非常に高いのです。 - -市場原理に基づくメカニズムにおけるこの欠陥が明るみにでましたが、 -ある特定の厳密でないシンプルな仮定のもとで、その欠陥を手品のようにキャンセルすることができます。 -論拠は以下のようなものです。 - -1. `k`個のオペレーションを含むトランザクションに対して、送信者がそのオペレーションを含める採掘者に対して`kR`の報酬をオファーする。ここで、`R`は送信者によって決定され、`k`と`R`は採掘者に対しておおよその値が事前に分かるようにする。 -2. 一つのオペレーションはどのノードにとっても`C`という実行コストを持つ(すなわち、すべてのノードは同じ効率をもつ) -3. `N`個のマイニングノードが存在するとき、それぞれは全く同じ処理能力を持っている(すなわち `1/N`である) -4. 採掘をしない フルノード は存在しない - -採掘者は、期待できる報酬がコストより大きければ、トランザクションを喜んで処理します。 -そして、採掘者が次のブロックを見つける確率は`1/N`なので、予想される報酬は `kR/N`となり、 -採掘者にとっての処理コストは`kC`だけです。 -このように考えると、採掘者は `kR/N > kC` つまり `R > NC`の時、トランザクションを取り込みます。 -ここで、`R`は送信者がオペレーション処理の前に支払う手数料で、 -送信者がトランザクション送信による利益を享受するのに必要な最低料金となります。 -NCはオペレーションを処理するためのネットワーク全体のコストであり、 -よって、採掘者は、実利のトータルがコストを超えるトランザクションだけを取り入れようとします。 - -しかし、実際の仮定では、いくつか重要な逸脱が生じます。 - -1. 採掘者は実際には他の検証ノードよりもトランザクション処理に高いコストを払う事があります。それは、追加の検証時間がブロックの伝搬を遅らせ、ブロックが無効になる可能性が増加するためです。 -2. 採掘を全くしないフルノードが存在します。 -3. 現実には採掘能力の分散は非常に不平等なものとなります。 -4. 投機家、政敵、ネットワークの存在に対して攻撃を仕掛ける道具をもった狂人が存在しまう。彼らは頭が良く、contract において、自分たちのコストが他の検証ノードが払うコストよりもかなり低いような環境を設定します。 - -(1)は採掘者が少ししかトランザクションを取り込まない傾向を生み出してしまいます。 -(2)は`NC`を増加させます。よって、(1)と(2)は、少なくとも互いに部分的にキャンセルします。 -(3)(4)は重要な問題です。これらの問題を解決する方法としては、単純に上限を設定しました。 -どのブロックも`BLK_LIMIT_FACTOR`回 x `長期指数関数移動平均` 以上のオペレーションを行うことはできません。 -つまり、 - - blk.oplimit = floor((blk.parent.oplimit * (EMAFACTOR - 1) + floor(parent.opcount * BLK_LIMIT_FACTOR)) / EMA_FACTOR) - -`BLK_LIMIT_FACTOR` と `EMA_FACTOR` は、当分は、65536と1.5に設定される定数で、さらに解析が進めば、変更される可能性があります。 - -Bitcoin に見られる大きなブロックを推奨しない別の理由として、 -大きなブロックは伝播するのに、時間がかかります。 -そして、このように、高確率で新鮮でないものとなってしまいます。 -Ethereum においては、ガス消費量の大きいブロックも同様に伝播するのに時間がかかります。 -それには、物理的に大きいトランザクションの状態遷移を検証するのに時間が掛かるという双方の理由があります。 -この遅延に対すす非推奨はBitcoin においては重要な問題ですが、 -Ethereum においては、GHOST プロトコルのおかげでそれほど問題ではありません。 -このように、ブロックを規制することにより、より安定した基盤工程ができあがります。 - - -### 計算 と チューリング完全 - -Ethereum 仮想マシン が チューリング完全 だというのはとても重要なことです。 -これは、EVMコード が無限ループを含む計算もコード化できることを意味します。 -EVMコード は二つの方法でループを可能にします。 -第一に、 -`JUMP` 命令はプログラムにコードの以前のどこか指定した場所へジャンプします。 -`JUMPI`命令は`while x<27; x= x*2`のような条件分岐を可能にします。 -第二に contract は別の contract を呼ぶ事ができ、 -潜在的に再帰によりループが可能となります。 -この方法では当然問題に行き当たります。 -悪意をもったユーザは、無限ループに陥らせる事で採掘者を黙らせ、フルノードをダウンさせることができるのか?という問題で、 -これは、コンピュータサイエンスの「実行停止問題」として知られる問題を浮かび上がらせます。 -実行停止問題とは、一般的に与えられたプログラムがいつまでも停止しないかどうかを知る方法が無いというものです。 - -"状態遷移の章" で説明したように我々の解決方法は、 -トランザクションに対し、許される最大の計算ステップ数を設定し、もし実行が長引けば計算を元に戻し、費用だけを支払うといったもので、 -メッセージも同じ方法をとります。 -我々がこの解法を選んだ動機を理解するために、以下のような例を考えてみましょう。 - -* 攻撃者が、無限ループを引き起こす contract を作り、採掘者に対してそのループを引き起こすトランザクションを送信します。 -採掘者はトランザクションを実行し、無限ループを実行し、そして燃料が切れるのを待ちます。実行は燃料切れになり、途中で止まりますが、トランザクションはまだ有効であり、採掘者は各実行ステップのための手数料を攻撃者に要求し続けています。 -* 攻撃者は非常に長い無限ループを作り、数ブロックが認証されるほどの時間、採掘者を計算させ続け、採掘者がトランザクションを含めて手数料を要求することを不可能にさせます。しかし、攻撃者は計算ステップ数の上限を決める`STARTGAS`の値を提供する必要があるので、採掘者は計算が非常に大きなステップ数であることを前もって知ります。 -* 攻撃者は `send(A,contract.storage[A]); contract.storage[A] = 0` のようなコードを持った contract を見て、最初のステップのみ実行できて二番目のステップは実行できないような量の燃料を持ったトランザクションを送付します。 -(つまり、引き出しはするが差額を減らさせない)。contract の作者はそのような攻撃に対する防御を考える必要はない。なぜならば、実行が途中で終わる時には状態の変化は元に戻ります。 -* ある金融 contract がリスクを減らすために9つの固有のデータフィードの中央値をとるとします。DAO の章で説明したような、呼出アドレスを変数化するメカニズム を通して変更可能な設計をされている一つのデータフィードを攻撃者は乗っ取り、無限ループを引き起こすように変更し、金融 contract から資金を要求するものを燃料切れにしていきます。しかしながら、金融 contract は、メッセージ上で燃料の上限を設定できるので、このような問題は防ぐ事ができます。 - - -チューリング完全 に取って代わるものは、チューリング不完全 です。`JUMP` や `JUMPI` 命令は存在せず、 -コールスタックにはそれぞれの contract の一つだけのコピーが存在できます。 -このシステムではこれまでに述べた手数料システムや我々の解決策の効果についての不確実性は必要なくなります。 -なぜなら contract を実行するコストはそのサイズによって上限が決まるからです。 -さらに、チューリング不完全 はそれほど大きな制約ではありません。 -というのは、我々が内部で想像した全ての contract の例で、一つのみがループを必要とし、 -さらにそのループはコードを26回繰り返す事によって取り除くことができました。 -チューリング完全 のもたらす厳しさや限定された利益を考えた時、 -何故チューリング不完全な言語を使用しないのでしょうか? -しかし実際は、チューリング不完全では、与えられた問題の正しい解決からはほど遠いものです。 -その理由を知るために、以下のcontractを考えましょう。 - - C0: call(C1); call(C1); - C1: call(C2); call(C2); - C2: call(C3); call(C3); - ... - C49: call(C50); call(C50); - C50: (run one step of a program and record the change in storage) - -いまあるトランザクションをAに送ります。 -このように、51個のトランザクションにおいて、250 の計算ステップを持つ contract を保持するものとします。 -採掘者はそれぞれの contract に付随する、 -最大の計算ステップ数や、contract が呼出す contract を前もって見る事によって -そのような論理爆弾を事前に察知することが可能ですが、これには、採掘者が他の contract を作り出す contract を禁止する必要が有ります。 -(なぜなら、上記の 51 個の contract の生成と実行は簡単に一つの contract に書き記すことができるのです。) -他の問題となるポイントはメッセージのアドレスフィールドが変数であり、一般的に contract が呼出す他の contract を事前に理解することが不可能なことです。 -よって、我々は驚くべき結論を得ます。 -チューリング完全 では驚く程容易に管理でき、 -一方、チューリング不完全 では、チューリング完全と同じ機能を持たせようとすると、驚く程管理が難しくなります。 -そのような場合、チューリング完全にしない理由はありません。 - - -### 通貨 と 発行 - -Ethereum のネットワークは ether という、自身の組込型通貨を保持し、 -二つの主要レイヤを保持します。 -種々のデジタル資産の効率的交換と、さらに重要なものとして、 -トランザクション手数料の支払いのメカニズムを提供します。 -簡便性のためと将来の議論を避けるため Bitcoin における mBTC/uBTC/satoshi に関する現在の議論を参照してください。通貨単位は設定済みで以下の通りです。 - -* 1: wei -* 103: lovelace -* 106: babbage -* 109: shannon -* 1012: szabo -* 1015: finney -* 1018: ether - -これはドルとセント、あるいは BTC と satoshi のコンセプトの拡張であり、 -近い将来、ether は通常のトランザクションで使用され、finney はマイクロトランザクションで使用され、szabo と wei は手数料やプロトコル実装の技術討論で用いられると我々は予想しています。残りの単位は後に必要となるかもしれませんが、現在の所、クライアント・サイドの実装には含まれていません。 - -Ether 発行 のモデルは以下の通りとなります。 - -* Etherは1BTCあたり1000-2000 etherの価格で通貨販売でリリースされます。このメカニズムは Etehereum Organization の資金調達の目的と、Mastercoin や NXT のような成功した他の基盤を引き継ぎ開発するための支払い目的を意図しています。 -初期の購入者は大きなディスカウントを得る事ができます。販売で得られたBTCは、全て、開発者の給与や賞金、Etehreum や仮想通貨エコシステムの様々な利益、非利益プロジェクトへの投資に使用されます。 -* 0.099 x プリセール販売額 ( 60102216 ETH ) が、初期の貢献者へ報いるために Ethereum Organization へ与えられます。 -ブロック生成開始前にETH建てで経費は支払われ、残りは長期に保有されます。 -* 0.099 x プリセール販売額 が長期保存用として維持管理されます。 -* 0.26 x プリセール販売額 が一年あたり採掘者に割り当てられる総額で、永遠に提供されます。 - -| Group | At launch | After 1 year | After 5 years -| ------------- | ------------- |-------------| ----------- | -| Currency units | 1.198X | 1.458X | 2.498X | -| Purchasers | 83.5% | 68.6% | 40.0% | -| Reserve spent pre-sale | 8.26% | 6.79% | 3.96% | -| Reserve used post-sale | 8.26% | 6.79% | 3.96% | -| Miners | 0% | 17.8% | 52.0% | - - -**長期における供給成長率** - -![SPV in bitcoin](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/inflation.png) - -_線形的な通貨の発行に関わらず、しかしながら、Bitcoin のように長期的に供給成長率は零となる傾向がある_ - - -上記モデルにおける主要な二つの選択として、 -(1)基金プールの存在とその規模、 -(2)供給上限があるBitcoinと異なった永久に全供給量が増え続ける仕組み -が挙げられます。 -基金プールの存在に対する正当性は次のとおりです。 -もし基金プールが存在せず、 -同じインフレ率を提供するために線形発行量を0.217倍に減少させると、 -etherの全供給量は16.5%減り、一単位の価値は19.8%上昇します。 -この19.8%の不均衡を埋めるために、より多くのetherがセールで購入され、 -結果、1単位が以前と全く同じ価値を持つところで平衡を保ちます。 -組織は1.198倍のBTCを持ちますが、 -それは二つに分ける事ができます。 -オリジナルのBTCと追加の0.198倍のBTCです。 -このように考えると、基金プールを持たない状況は、基金プールがある状況と _厳密に等価_ ですが、 -一つだけ重要な違いがあります。 -組織は純粋にBTCを保持し、ether の価値を維持するインセンティブを持ちません。 - -永遠に線形的に全供給量が増えるモデルでは、Bitcoin で見られた一部に富の超過集中リスクを減らします。 -そして、現在を生きる個人と未来を生きる個人に対して公平な通貨獲得の機会を与えます。 -同時に、供給増加レートがゼロに向かうため、Etherを得て保持しようという強いインセンティブを与えます。 -不注意や死やその他の理由でコインは常に失われて行き、 -コインの損失は一年あたりの総供給量に対する割合でモデリングすることができ、 -全循環通貨供給量はゆっくりと年間発行量を損失率で割った値に近づいて行くということから上記の理論化を行っています。 -(すなわち、損失率が1%の場合、ひとたび供給量が26Xになったら、0.26Xが採掘され、0.26Xが毎年失われるところで均衡します)。 - -将来、Ethereum はセキュリティ向上のため proof of stake モデルに切り替える可能性が高く、発行需要量を0-0.05X/年の間に減らす考えがあります。Ethereum Organization が資金を失ったり他の理由で消失した場合に備えて、オープンな、 -「 social contract 」をあとに残す考えがあります。 -誰もが Ethereum の未来候補版を作成する権利があり、唯一の条件は ether の総額は、 -せいぜい `60102216 * (1.198 + 0.26 * n)` ( `n` : ブロック生成開始からの年数 ) に等しくなることです。 -クリエータは開発費用を捻出するために自由に -クラウドセールを行ったりあるいは、 -POS 上での供給拡大と最大許容供給拡大の間の差の一部あるいは全てを自由に使用することができます。 -socail contract に合致しない候補版のアップグレードが -準拠版として公正にフォークされる可能性もあります。 - - -### マイニング集中 - - -Bitcoin のマイニングアルゴリズムは、基本的に、採掘者にブロックヘッダの少しだけ変更したバージョンについて何百万回も繰り返してSHA256を演算をさせ、最終的に一つのノードがあるターゲット以下(現在は2192)のハッシュ値になることによって成立しています。しかしながら、このマイニングアルゴリズムは二つの中央集権化に対する脆弱性を持っています。一つは、マイニングのエコシステムがASIC(application-specific integrated circuits)に支配されるようになってきています。ASIC はマイニング専門にチップがデザインされているためビットコインマイニングのタスクに対して数千倍の効率を持っています。これはBitcoinのマイニングはもはや分散型ではなく、効率的に参加するためには数百万ドルが必要となり、平等主義を追求していないことを意味しています。第二に殆どのBitcoinマイナーはブロックの認証プロセスを実際には一人では行っていません。その代わりにブロックヘッダを見つけるための中央集権化されたマイニングプールに依存しています。こちらの問題はおそらくもっとひどいものです。この文章を書いている時で、トップ3のマイニングプールは直接的ではないですが、Bitcoinネットワークの約50%をコントロールしています。マイナーはもしマイニングプールや連立が51%アタックをしようとしたときに他のマイニングプールに移動できるのですが、それでも良くないものです。 - -現在 Ethereum が使用しようとしているアルゴリズムは採掘者が「 状態 」から ランダムなデータ を生み出し、 -ブロックチェインの最後のNブロックからランダムに選ばれたトランザクションを計算し、結果のハッシュを返すというものです。これは二つの重要な利点があります。第一に、Etehreum の contract はどのような種類の演算も取り込む事ができます、つまりEtehreum用のASICを開発するとしたら、本質的にどのような演算も早いASIC ー それはすなわち、より良いCPUということになります。第二に、マイニングにおいてブロックチェイン全体にアクセスすることが必要になり、マイナーにブロックチェイン全体を保持することと、少なくとも全てのトランザクションを検証できるということを要求する事になります。これは中央集権化したマイニングプールの必要性を取り除くことになります;マイニングプールは報酬の分配のランダムさを平等にする、正当な役割を果たす事はできますが、この機能はP2Pプールによって中央集権無しに実現できます。 - -このモデルはまだテストされていません。そしてマイニングアルゴリズムとしてcontractの実行をさせる時に、賢く最適化を利用されることを避ける難しさがあると思われます。しかしながら、このアルゴリズムの面白い特徴は非常に大きな数のcontractを、特にあるASICの妨害をするように設計して、ブロックチェインに入れることで誰でも井戸に毒を盛る事ができるということです。ASIC 製造者にはお互いにそのようなトリックを使って攻撃する経済的なインセンティブが存在します。よって、我々が開発中のソリューションは純粋なテクニカルなものというよりも究極の経済的なヒューマンソリューションとなります。 - - - -### スケーラビリティ - - -Ethereum に関する大勢の関心の一つは スケーラビリティ です。 -Bitcoin のように Etehreum はすべてのトランザクションがネットワーク上の全てのノードで実行される必要があるという欠点があります。 -Bitcoin では現在のブロックチェインは約15GBであり、一時間あたり1MB増加しています。 -もし Bitcoin ネットワークが Visa のように一秒当たり 2000 トランザクション を処理する場合、 -3秒当たり1MB(1時間あたり1GB, 一年当たり8TB)もの増加をすることになります。 -Etehreum も同じような成長パターンに苦しむことになります。 -さらに悪い事には、単なる貨幣として使用されているBitcoinと異なり、 -Ethereum のブロックチェインは様々なアプリケーションが実行されることになります。 -しかし、Ethereum のフルノードはブロックチェインの履歴全てではなく、状態だけを保持すれば良いという事実が良い方向に働くでしょう。 - - -このような巨大なブロックチェインのサイズには中央集約化リスクが存在します。 -仮にブロックチェインのサイズが100TBになったとします。 -そのとき、もっともあり得るシナリオは非常に少ない数の巨大なビジネス組織のみがフルノードを動作させており、通常のユーザーは皆ライトSPVノードを使っているというものです。そのような状態では、なんらかの利益のためにお互いが手を組んでずるをして合意するという潜在的な危機が浮かび上がります(例えば、ブロックの報酬を変更して、彼らにBTCを与える)。ライトノードはこれを即座に見つけ出す方法を持っていません。もちろん少なくとも一つの誠実なフルノードが存在しているでしょう、そして、欠陥についての情報が数時間のちにRedditのようなチャンネルを通してじわじわ広まったとして、そのタイミングではもう遅すぎます:与えられたブロック -をブラックリスト化する努力を計画するかは一般ユーザに委ねられ、またうまく出来た51%アタックを抜き出すのと同じ規模の、巨大でおそらく不可能な整合作業となるでしょう。Bitcoin の場合、このことは現在問題になっています。しかし[Peter Todd の提案](http://sourceforge.net/p/bitcoin/mailman/message/31709140/)がこの問題を緩和するでしょう。 - - -近い将来、Ethereum はこの問題に取り組むために二つの戦略を追加する予定です。 -第一に、ブロックチェインベースのマイニングアルゴリズムのために、 -すくなくとも全てのマイナーがフルノードである必要があり、 -フルノードの数の下限を作ります。 -第二に、これはさらに重要なのですが、 -それぞれのトランザクションを処理した後にブロックチェイン内部に中間状態木のルートを含めます。 -もしブロック認証が中央集権化してしまったとしても、一つの正直な認証ノードが存在している限り、 -中央集権問題は認証プロトコルによって避ける事が可能です。 -もし、採掘者が有効でないブロックを提供した場合、 -そのブロックはフォーマットが間違っているか、 -もしくは状態`S[n]`が正しくないかです。 -`S[0]`は正しい事が分かっているので、どこかに`S[i-1]`は正しいが、`S[i]`は正しくないという最初の状態が存在します。検証ノードは `APPLY(S[i-1],TX[i]) -> S[i]` を実行するのに必要なパトリシアツリーのノードの部分木による誤りの検証プロセスによって、index `i`を見つけます。ノードはこれらのノードを演算の一部として実行し、与えられた`S[i]`と異なる`S[i]`を見つけます。 - - -他のより洗練された攻撃として、 -悪意のある採掘者が不完全なブロックを提出することで、 -ブロックが有効かどうかの決定に際し、完全な情報不足状態をつくることができます。 -この攻撃に対する解決策は challenge-response プロトコルです。 -検証ノードは、該当トランザクション索引 の形式で「 challenge 」を発行し、 -ひとつのノードを受け取った 軽量ノードは、 -採掘者あるいは検証者が、有効性の証明としてパトリシアノードの部分木を送るまでブロックを信用できないものとして扱います。 - - -## 結論 - - -Ethereum のプロトコルは元々、暗号通貨のアップグレード版で、ブロックチェイン上のエスクローや、引き出しの上限、金融contract、ギャンブルマーケットのような先進的な特徴を、高度一般化したプログラミング言語を通して提供するものだと考えられてきました。 -Ethereum のプロトコルはどんなアプリケーションも直接にはサポートせず、チューリング完全なプログラミング言語のみが存在します。 -それは、理論的にはどんなトランザクションタイプやアプリケーションのための任意の contract を作る事ができるということです。 -しかし、Ethereum について、さらに興味深い事は、Ethereum のプロトコルは単なる通貨を超えているということです。 -分散型ファイルストレージ、分散型コンピューティング、分散型市場予想や、その他多数の概念のプロトコルは、 -コンピュータ業界の効率の増加とともに本質的な潜在性が開花するものと思われますが、 -最初は経済のレイヤーでP2Pプロトコルを加速しました。 -最終的には、通貨と全く関係のない沢山の本質的なアプリケーションの可能性が広がっています。 - - -Ethereum のプロトコルによって実装されている任意の状態遷移関数のコンセプトはユニークな潜在性をもった基盤です。 -閉じた単一の目的である、データストレージや、賭博、金融アプリケーション用のプロトコルと異なり、 -Ethereum は非常にオープンな設計です。 -我々は数年で、金融や非金融の両方のプロトコルにおいて、 -多数の基礎レイヤーとして使われる事になると信じています。 - -# 脚注 及び 参考文献 - -#### 脚注 - -1. 洗練された読者は Bitcoin のアドレスは公開鍵そのものでは無く、 -楕円曲線公開鍵のハッシュであることに気がつくでしょう。 -しかしながら、じつのところ、暗号用語は公開鍵そのものとして公開鍵ハッシュを扱っても成立します。 -これは Bitcoin の暗号がカスタムなデジタル署名アルゴリズムと考えることが可能で、 -そこでは公開鍵は ECC 公開鍵 のハッシュで構成されており、 -署名はECC公開鍵をECC署名と重ねたもので構成されており、 -認証アルゴリズムは署名の中のECC公開鍵が公開鍵として与えられているECC公開鍵ハッシュに対して正しいかチェックすることを含んでおり、 -よって、ECC 署名 が ECC 公開鍵 に対して正しいかのチェックになっているからです。 -2. 技術的には、11個前までのブロックの中央値です。 -3. 内部的には 2 も "CHARLIE" も両方とも番号です。 -後者は ビッグエンディアンの256ビットベース の表現です。番号は最小で 0 、最大で 2256-1 を取る事ができます。 - - -#### 参考文献 - -1. Intrinsic value: http://bitcoinmagazine.com/8640/an-exploration-of-intrinsic-value-what-it-is-why-bitcoin-doesnt-have-it-and-why-bitcoin-does-have-it/ -2. Smart property: https://en.bitcoin.it/wiki/Smart_Property -3. Smart contracts: https://en.bitcoin.it/wiki/Contracts -4. B-money: http://www.weidai.com/bmoney.txt -5. Reusable proofs of work: http://www.finney.org/~hal/rpow/ -6. Secure property titles with owner authority: http://szabo.best.vwh.net/securetitle.html -7. Bitcoin whitepaper: http://bitcoin.org/bitcoin.pdf -8. Namecoin: https://namecoin.org/ -9. Zooko's triangle: http://en.wikipedia.org/wiki/Zooko's_triangle -10. Colored coins whitepaper: https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit -11. Mastercoin whitepaper: https://github.com/mastercoin-MSC/spec -12. Decentralized autonomous corporations, Bitcoin Magazine: http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/ -13. Simplified payment verification: https://en.bitcoin.it/wiki/Scalability#Simplifiedpaymentverification -14. Merkle trees: http://en.wikipedia.org/wiki/Merkle_tree -15. Patricia trees: http://en.wikipedia.org/wiki/Patricia_tree -16. GHOST: http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf -17. StorJ and Autonomous Agents, Jeff Garzik: http://garzikrants.blogspot.ca/2013/01/storj-and-bitcoin-autonomous-agents.html -18. Mike Hearn on Smart Property at Turing Festival: http://www.youtube.com/watch?v=Pu4PAMFPo5Y -19. Ethereum RLP: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP -20. Ethereum Merkle Patricia trees: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree -21. Peter Todd on Merkle sum trees: http://sourceforge.net/p/bitcoin/mailman/message/31709140/ diff --git a/pages/white-paper/[korean]-white-paper.md b/pages/white-paper/[korean]-white-paper.md deleted file mode 100644 index 791729d08..000000000 --- a/pages/white-paper/[korean]-white-paper.md +++ /dev/null @@ -1,553 +0,0 @@ ---- -name: White Paper -category: ---- - -### 차세대 스마트 컨트랙트와 탈중앙화된 어플리케이션 플랫폼 -(A Next-Generation Smart Contract and Decentralized Application Platform) - -사토시 나카모토가 2009년 개발한 비트코인은 종종 화폐와 통화분야에서 매우 근본적인 혁신으로 묘사되어 왔는데, 이것은 비트코인이 어떤 담보나 내재적인 가치를 가지지 않으며 중앙화된 발행기관이나 통제기관도 없는 디지털 자산의 첫번째 사례였기 때문이다. 하지만 비트코인 실험의 더욱 중요한 측면은 비트코인을 떠받치고 있는 분산합의수단으로서의 블록체인 기술이며, 이에 대한 관심이 급격하게 늘어나고 있다. - -블록체인 기술을 이용한 대안적 어플리케이션들에는 다음과 같은 것들이 자주 거론되고 있다. 사용자 정의 화폐와 금융상품을 블록체인 위에 표현하는 컬러드 코인("colored coins"), 물리적 대상의 소유권을 표현하는 스마트 자산("smart property"), 도메인 이름과 같은 비동질적 자산을 기록하는 네임코인("Namecoin"), 임의적인 계약규칙을 구현한 코드에 의해 다지털 자산을 관리하는 좀 더 복잡한 형태의 스마트 컨트랙트 ("smart contracts"), 더 나아가 블록체인을 기반으로 한 탈중앙화된 자율 조직( "decentralized autonomous organizations" , DAOs) 등이다. - -이더리움이 제공하려는 것은 완벽한 튜링완전(turing-complete) 프로그래밍 언어가 심어진 블록체인이다. 이 프로그래밍 언어는, 코딩된 규칙에 따라 '어떤 상태'를 다르게 변환시키는 기능(arbitrary state transition functions)이 포함된 "계약(contracts)"을 유저들이 작성할 수 있게 함으로써 앞서 설명한 시스템들을 구현 가능하게 할 뿐만 아니라 우리가 아직 상상하지 못한 다른 많은 어플리케이션도 매우 쉽게 만들 수 있도록 도와줄 것이다. - -### 목차 - -* [역사](#%EC%97%AD%EC%82%AChistory) - * [상태변환시스템으로서의 비트코인](#%EC%83%81%ED%83%9C%EB%B3%80%ED%99%98%EC%8B%9C%EC%8A%A4%ED%85%9C%EC%9C%BC%EB%A1%9C%EC%84%9C%EC%9D%98-%EB%B9%84%ED%8A%B8%EC%BD%94%EC%9D%B8bitcoin-as-a-state-transition-system) - * [채굴](#%EC%B1%84%EA%B5%B4) - * [머클트리](##%EB%A8%B8%ED%81%B4%ED%8A%B8%EB%A6%AC) - * [블록체인 사용한 다른 사용사례](#%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8-%EA%B8%B0%EC%88%A0%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EB%8B%A4%EB%A5%B8-%EC%9D%91%EC%9A%A9-%EC%82%AC%EB%A1%80-alternative-blockchain-applications) - * [스크립팅](#%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8C%85) -* [이더리움](#%EC%9D%B4%EB%8D%94%EB%A6%AC%EC%9B%80) - * [이더리움 어카운트](#%EC%96%B4%EB%8D%94%EB%A6%AC%EC%9B%80-%EC%96%B4%EC%B9%B4%EC%9A%B4%ED%8A%B8) - * [메시지와 트랜잭션](#%EB%A9%94%EC%8B%9C%EC%A7%80%EC%99%80-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98) - * [이더리움 상태변환함수](#%EC%9D%B4%EB%8D%94%EB%A6%AC%EC%9B%80-%EC%83%81%ED%83%9C-%EB%B3%80%ED%99%98-%ED%95%A8%EC%88%98ethereum-state-transition-function) - * [코드 실행](#%EC%BD%94%EB%93%9C-%EC%8B%A4%ED%96%89code-execution) - * [블럭체인과 채굴](#%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8%EA%B3%BC-%EC%B1%84%EA%B5%B4blockchain-and-mining) -* [어플리케이션들](#%EC%96%B4%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98applications) - * [토큰 시스템](#%ED%86%A0%ED%81%B0-%EC%8B%9C%EC%8A%A4%ED%85%9Ctoken-systems) - * [금융 파생상품](#%ED%8C%8C%EC%83%9D%EC%83%81%ED%92%88%EA%B3%BC-%EA%B0%80%EC%B9%98%EC%95%88%EC%A0%95%ED%86%B5%ED%99%94) - * [신원조회와 평판시스템](#%EC%8B%A0%EC%9B%90%EC%A1%B0%ED%9A%8C--%ED%8F%89%ED%8C%90-%EC%8B%9C%EC%8A%A4%ED%85%9Cidentity-and-reputation-systems) - * [탈중앙화된 파일 저장공간](#%EB%B6%84%EC%82%B0%ED%98%95-%ED%8C%8C%EC%9D%BC-%EC%A0%80%EC%9E%A5%EC%86%8Cdecentralized-file-storage) - * [탈중앙화된 자율 조직](#%ED%83%88%EC%A4%91%EC%95%99%ED%99%94%EB%90%9C-%EC%9E%90%EC%9C%A8%EC%A1%B0%EC%A7%81decentralized-autonomous-organizations) - * [추가적인 어플리케이션들](#%EC%B6%94%EA%B0%80%EC%A0%81%EC%9D%B8-%EC%96%B4%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98%EB%93%A4further-applications) -* [기타 이슈들](#%EA%B7%B8-%EB%B0%96%EC%9D%98-%EC%9D%B4%EC%8A%88%EB%93%A4) - * [수정된 GHOST 도입](#%EC%88%98%EC%A0%95%EB%90%9C-ghost-%EB%8F%84%EC%9E%85modified-ghost-implementation) - * [수수료](#%EC%88%98%EC%88%98%EB%A3%8C) - * [연산과 튜링완전성](#%EC%97%B0%EC%82%B0%EA%B3%BC-%ED%8A%9C%EB%A7%81%EC%99%84%EC%A0%84%EC%84%B1computation-and-turing-completeness) - * [통화와 발행](#%ED%86%B5%ED%99%94-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%EB%B0%9C%ED%96%89currency-and-issuance) - * [채굴 중앙집중화](#%EC%B1%84%EA%B5%B4-%EC%A4%91%EC%95%99%EC%A7%91%EC%A4%91%ED%99%94mining-centralization) - * [확장성](#%ED%99%95%EC%9E%A5%EC%84%B1scalability) -* [결론](#%EA%B2%B0%EB%A1%A0) -* [주석과 추가 자료](#%EC%A3%BC%EC%84%9D%EA%B3%BC-%EC%B6%94%EA%B0%80%EC%9E%90%EB%A3%8C) - -## 비트코인과 기존 개념들에 대한 소개(Introduction to Bitcoin and Existing Concepts) - -### 역사(History) - -분산화된 디지털 통화의 개념은, 재산등록 같은 대안 어플리케이션과 마찬가지로 지난 수십 년간 우리 주변에 있었다. 1980~90년대 익명 e-cash 프로토콜은 주로 ‘Chaumian blinding’으로 알려진 ‘로우레벨 암호 알고리즘(cryptographic primitive)’에 기반하였고 개인정보를 강력하게 보호하는 화폐를 제공하였으나 중앙집권적인 중개인에 의존했기 때문에 별다른 주목을 받지 못했다. 1998년 'Wei Dai'의 [b-money](http://www.weidai.com/bmoney.txt)는 분산 합의와 계산 퍼즐을 풀게 하는 방식을 통해서 화폐를 발행하게 하는 아이디어를 최초로 제안하였지만 분산 합의를 실제로 어떻게 구현할지에 대한 자세한 방법은 제시하지 못했다. 2005년에 'Hall Finney'는 "재사용 가능한 작업증명([reusable proofs of work](http://www.finney.org/~hal/rpow/))" 개념을 소개하였다. 이 시스템은 b-money의 아이디어에 Adam Back의 ‘계산 난이도 해시캐시 퍼즐(computationally difficult Hashcash puzzles)’을 조합한 것이었다. 그러나 외부의 신뢰를 필요로 하는 컴퓨팅(trusted computing)을 그 기반에 둠으로써, 이상을 구현하는데에는 또 다시 실패했다. 2009년 사토시 나카모토에 의해 처음 실제적으로 구현된 탈중앙화된 화폐는 공개키 암호방식을 통한 소유권 관리를 위해 사용되던 기존의 알고리즘을 ‘작업 증명(proof of work)’이라고 알려진 합의 알고리즘과 결합함으로써 가능하게 되었다. - -작업증명의 기반이 되는 작동방식은 매우 혁신적인 것이었는데, 이것은 두가지 문제를 동시에 해결하기 때문이다. 첫째, 이것은 간단하면서도 상당히 효과적인 합의 알고리즘을 제공해주었다. 즉, 네트워크 상에 있는 모든 노드들이 비트코인의 장부상태(state of the Bitcoin ledger)에 일어난 표준 업데이트의 집합(a set of canonical updates)에 공동으로 동의할 수 있도록 해주었다는 것이다. 둘째, 누구나 합의 프로세스에 참여할 수 있도록 허용해줌으로써 합의결정권에 대한 정치적 문제를 해결할 수 있을 뿐만 아니라 동시에 시빌공격(sybil attacks)도 방어해줄 수 있는 메커니즘을 제공했다. 이것은 합의 프로세스에 대한 참여의 조건으로 ‘특정한 리스트에 등록된 주체이어야만 한다’라는 어떤 형식적 장벽대신에, 경제적 장벽 - 각 노드의 결정권의 크기를 그 노드의 계산능력에 직접적으로 비례시키는 방식으로 대체하는 것이었다. - -이후로, 지분증명(proof of stake)이라는 새로운 방식의 합의 알고리즘이 등장했는데, 이는 각 노드가 가진 계산능력이 아니라 화폐의 보유량에 따라 각 노드의 결정권 정도를 계산해야 한다는 것이다. 이 두 방식의 상대적인 장점들에 대한 논의는 이 백서에서는 다루지 않겠지만, 두 방법 모두 암호화화폐의 기반으로서 사용될 수 있다는 점은 지적해두고자 한다. - -### 상태변환시스템으로서의 비트코인(Bitcoin As A State Transition System) - -![statetransition.png](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/statetransition.png) - -기술적인 관점에서 보았을 때, 비트코인과 같은 암호화 화폐의 장부는 하나의 상태변환시스템(state transition system)으로 생각해볼 수 있다. 이 시스템은, 현재 모든 비트코인의 소유권 현황으로 이루어진 하나의 “상태(state)” 와 이 현재 상태와 트랜잭션을 받아서 그 결과로써 새로운 상태를 출력해주는 “상태변환함수(state transition function)”로 구성되어 있다. 표준 은행 시스템에 비유하자면 상태는 모든 계좌잔고표(balance sheet)이고 트랜잭션은 A에서 B로 $X를 송금하라는 요청이며, 상태변환함수에 의해 A의 계좌에서는 $X가 감소하고 B의 계좌에서는 $X가 증가한다. 만약 처음에 A의 계좌에 있는 금액이 $X 이하인 경우에는 상태변환함수가 에러를 리턴한다. -이러한 상태변환를 비트코인 장부에서는 다음과 같이 정의할 수 있다. - - APPLY(S,TX) -> S' or ERROR - -은행 시스템 예시에서는 다음과 같다. - - APPLY({ Alice: $50, Bob: $50 },"send $20 from Alice to Bob") = { Alice: $30, Bob: $70 } - - APPLY({ Alice: $50, Bob: $50 },"send $70 from Alice to Bob") = ERROR - -비트코인에서 "상태(state)"는 생성되었지만 아직 사용되지 않은 모든 코인들의 집합(기술적표현으로는 '소비되지 않은 트랜잭션 출력', UTXO(Unspent Transaction Outputs))이다. 각 UTXO들에는 각자의 코인금액이 표시되어 있고 이 UTXO의 소유자(20byte의 주소로 정의되는 암호화된 공개키(public key)[1])정보가 들어 있다. 트랜잭션은 하나 이상의 입력(inputs) 및 출력을 포함한다. 각 입력에는 보내는 쪽 지갑주소에서 선택된 기존 UTXO에 대한 참조정보와, 해당지갑주소에 대응되는 개인키(private key)가 생성한 암호화된 서명을 담고 있다. 그리고 각 출력들은 상태에 추가될 새로운 UTXO정보를 가지고 있다. - -상태변환함수 `APPLY(S,TX) -> S'` 는 다음과 같이 정의할 수 있다. - -1. TX의 각 입력에 대해 : - * 만약 참조된 UTXO가 `S`에 없다면, 에러를 리턴. - * 만약 서명이 UTXO의 소유자와 매치되지 않으면, 에러를 리턴. -2. 만약 입력에 사용된 UTXO들 금액의 합이 출력 UTXO들 금액의 합보다 작으면, 에러를 리턴. -3. 입력에 사용된 UTXO가 삭제되고 출력 UTXO가 추가된 `S`를 리턴. - -여기서 1번의 첫번째 과정은 존재하지 않는 코인이 트랜잭션에 사용되는 것을 막기 위한 것이고 1번의 두번째 과정은 다른 사람의 코인이 트랜잭션에 사용되는 것을 막기 위한 것이다. 위 절차를 실제 비트코인 지불과정에 적용하면 다음과 같다. Alice가 Bob에게 11.7 BTC를 보내고 싶다고 가정하자. 먼저 Alice 지갑주소로부터 표시된 금액의 합이 적어도 11.7 BTC 이상인 UTXO의 집합을 찾는다. 실제 대부분의 경우에는 11.7 BTC를 정확히 바로 선택할 수 없다. Alice의 지갑주소에서 각각 6, 4, 2 BTC 가 표시된 3개의 UTXO를 참조할 수 있다고 하자. 이 3개의 UTXO가 트랜잭션의 input이 되고 2개의 output이 생성된다. Output 중 하나는 11.7 BTC가 표시된 새로운 UTXO이며 소유자는 Bob의 지갑주소가 된다. 그리고 다른 하나는 12(6+4+2) - 11.7 = 0.3 BTC의 "잔돈(change)"이 표시된 새로운 UTXO이며 소유자는 Alice 자신의 지갑주소가 된다. - -### 채굴 - -![block_picture.jpg](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/block.png) - -만일 우리가 위에서 기술한 내용을 신뢰를 기반으로 하는 중앙집권화된 서비스 방식으로 구현하자면 매우 간단한 일이 될텐데, 왜냐하면 중앙 서버 하드드라이브에 상태변화의 과정을 저장만 하면 되기 때문이다. 그러나 비트코인에서는, 탈중앙화된 통화시스템을 구축하고자 하는 것이며, 이를 위해서는 모든 사람이 수긍할 수 있는 트랜잭션 순서 합의 시스템을 상태변화시스템과 결합해야만 한다. 비트코인의 분산 합의 과정은 네트워크에 "블록(blocks)"이라 불리는 트랜잭션 패키지를 계속적으로 생성하고자 시도하는 노드들을 필요로 한다. 이 네트워크는 약 10분마다 하나의 블록을 생성하도록 계획되어 있고 각 블록은 타임스탬프, 논스(nonce), 이전 블록에 대한 참조(이전 블록의 해시), 그리고 이전 블록 이후에 발생한 모든 트랜잭션의 목록을 포함한다. 이 과정을 통해서 지속적으로 성장하는 블록체인이 생성되게 되는데, 비트코인 장부의 최신상태(state)를 나타내기 위해 지속적인 업데이트가 이루어진다. - -이 체계에서 하나의 블록이 유효한지 아닌지를 확인하기 위한 알고리즘은 다음과 같다. - -1. 이 블록에 의해 참조되는 이전 블록이 존재하는지, 유효한지 확인한다. -2. 타임스탬프 값이 이전 블록의 타임스탬프 값보다 크면서 2시간 이내인지 확인한다. -3. 작업증명(proof of work)이 유효한지 확인한다. -4. `S[0]`를 이전 블록의 마지막 상태(state)가 되도록 설정한다. -5. `TX`를 `n`개의 트랜잭션을 가지는, 블록의 트랜잭션 목록으로 가정한다. 폐구간 `0...n-1`의 모든 i에 대해, `S[i+1] = APPLY(S[i], TX[i])`집합 중 어느 하나라도 에러를 리턴하면 거짓(false)을 리턴하며 종료한다. -6. 참(true)을 리턴하고, `S[n]`를 이 블록의 마지막 상태로 등록한다. - -기본적으로 블록의 각 트랜잭션은 유효한 상태변환을 일으켜야 한다. 여기서 상태가 블록 내에 어떠한 방법으로로 기록되지 않았다는 점에 주목해보자. 상태는 유효성을 검증하는 노드가 매번 계산해서 기억해야 할 완전히 추상적 것(abstraction)인데, 이것은 원시상태(genesis state)부터 해당 블록까지의 모든 트랜잭션을 순차적으로 적용함으로써 계산될 수 있다. 채굴자가 블록에 포함시키는 트랜잭션의 순서에 주목해보자. 만약 어떤 블록에 A와 B라는 두 트랜잭션이 있고 B가 A의 출력 UTXO를 소비한다고 하자. 이때 A가 B이전의 트랜잭션인 경우 그 블록은 유효하지만, 그렇지 않을 경우 유효하지 않다. - -블록 유효성 검증 알고리즘에서 특징적인 부분은 "작업증명(proof of work)"의 조건 즉, 256 비트 숫자로 표현되는 각 블록의 이중-SHA256 해시값이 동적으로 조정되는 목표값(이더리움 영문 백서를 작성하는 시점에서 대략 2187)보다 반드시 작아야 된다는 조건이다. 작업증명의 목적은 블록 생성을 계산적으로 어렵게 만들어서 sybil 공격자들이 마음대로 전체 블록체인을 조작하는 것을 방지하는 것이다. SHA256은 전혀 예측불가능한 유사난수 함수(pseudorandom function)로 설계되었기 때문에 유효 블록을 생성하기 위한 유일한 방법은 블록헤더의 논스(nonce) 값을 계속해서 증가시키면서, 생성되는 새로운 해시값이 위의 조건을 만족하는지 확인하는 과정을 반복하는 것 뿐이다. -현재 목표값인 2187하에서 하나의 유효블록을 발견하기 위해서 평균적으로 264번의 시도를 해야만 한다. 일반적으로 이 목표값은 매 2016개의 블록마다 네트워크에 의해 재조정되어서 네트워크의 현재 노드들이 평균적으로 10분마다 새로운 블록을 생성할 수 있도록 한다. 이러한 연산작업에 대한 보상으로 현 시점의 각 블록의 채굴자들은 25 BTC를 획득할 자격을 가진다. 그리고 출력금액보다 입력금액이 큰 트랜잭션이 있다면 그 차액을 "트랜잭션 수수료(transaction fee)"로 얻는다. 이것이 BTC가 발행되는 유일한 방법이며, 원시상태(genesis state)에는 아무런 코인이 포함되지 않았다. - -채굴 목적을 더 잘 이해하기 위해서, 악의적인 공격자가 있을 때 어떤 일이 발생하는지 알아보자. 비트코인의 뼈대를 이루는 암호기법은 안전한 것으로 알려져 있다. 그러므로 공격자는 비트코인 시스템에서 암호기법에 의해 직접 보호되지 않는 부분인 '트랜잭션 순서'를 공격 목표로 잡을 것이다. 공격자의 전략은 매우 단순하다. - -1. 어떤 상품(가급적이면 바로 전달되는 디지털 상품)을 구매하기 위해 판매자에게 100 BTC를 지불한다. -2. 상품이 전송되기를 기다린다. -3. 판매자에게 지불한 것과 같은 100 BTC를 공격자 자신에게 보내는 트랜잭션을 생성한다.(이중지불 시도) -4. 비트코인 네트워크가, 공격자 자신에게 보내는 트랜잭션이 판매자에게 지불하는 트랜잭션보다 먼저 수행된 것으로 인식하도록 한다. - -1번 과정이 발생하고 몇 분 후에 몇몇 채굴자가 그 트랜잭션을 블록에 포함할 것이다. 이 블록 번호를 270000이라 하자. 대략 1시간 후에는 이 블록 다음의 체인에 5개의 블록들이 추가될 것이다. 이 5개의 블록들은 위 1번 트랜잭션을 간접적으로 가리킴으로써 "컨펌(confirming)"한다. 이 시점에서 판매자는 지불이 완료된 것으로 판단하고 상품을 전송할 것이다. 디지털 상품으로 가정했으므로 전송은 바로 끝난다. 이제 공격자는 판매자에게 보낸 것과 동일한 100 BTC를 공격자 자신에게 보내는 다른 트랜잭션을 생성한다. 만약 공격자가 그냥 단순하게 트랜잭션을 시도한다면, 채굴자들이 `APPLY(S,TX)`를 실행하고 이 `TX`는 상태에 더 이상 존재하지 않는 UTXO를 소비하려 한다는 것을 알아차리므로 이 트랜잭션은 진행되지 않는다. 그러므로 대신에, 같은 부모 블록 269999을 가리키지만 판매자에게 보낸 것을 대체하는 새로운 트랜잭션이 포함된 다른 버전의 블록 270000을 채굴함으로서 블록체인 "분기점(fork)"을 생성한다. 이 블록 정보는 원래 것과 다르므로 작업증명(proof of work)이 다시 수행되어야 한다. 그리고 공격자의 새버전 블록 270000은 기존 270000과 다른 해시를 가지므로 원래 블록 270001부터 270005는 공격자의 블록을 가리키지 않는다. 그러므로 원래 체인과 공격자의 새로운 체인은 완전히 분리된다. 이러한 분기점에서 비트코인 네트워크의 규칙은 가장 긴 블록체인을 참으로 인식하는 것이다. 공격자가 자신의 체인에서 혼자 작업을 하는 동안 정당한 채굴자들은 원래의 270005체인에서 작업할 것이기 때문에 공격자 자신의 체인을 가장 길게 만들기 위해서는 네트워크의 다른 노드들의 계산능력 조합보다 더 큰 계산능력을 가져야 한다.(이를 51% attack이라 한다.) - -### 머클트리 - -![SPV in bitcoin](https://raw.githubusercontent.com/ethereum/www/master-postsale/src/extras/gh_wiki/spv_bitcoin.png) - -_왼쪽: Merkle tree(머클트리)의 몇몇 노드만 보아도 곁가지(branch)의 유효성을 입증하기에 충분하다._ - -_오른쪽: Merkle tree의 어떤 부분을 바꾸려는 시도는 결국 상위 해시값 어딘가에 불일치를 만든다._ - -비트코인의 중요한 확장 기능은 블록이 여러 계층 구조(multi-layer data structure)에 저장된다는 것이다. 어떤 블록의 "해시(hash)"란 사실 블록헤더의 해시만을 의미한다. 이 블록헤더에는 타임스탬프, 논스(nonce), 이전 블록 해시, 그리고 블록에 포함된 모든 트랜잭션 정보에 의해 생성되는 머클트리(Merkle tree)의 루트 해시가 들어있는 200 바이트 정도의 데이터이다. 머클트리(Merkle tree)는 이진트리(binary tree)의 일종으로서 트리의 최하위에 위치하고 기저 데이터가 들어있는 수 많은 잎노드, 자기 자신 바로 하위에 있는 두 자식 노드의 해시로 구성된 중간 노드, 자기 자신 바로 하위에 있는 두 자식 중간노드의 해시로 구성된 트리의 "최상위(top)"에 있는 하나의 루트 노드의 집합이다. 머클트리(Merkle tree)의 목적은 어떤 블록의 데이터가 분리돼서 전달될 수 있도록 하는 것이다. 만약에 비트코인의 어떤 노드가 한 소스로부터 블록헤더만을 다운로드 받고, 이 블록헤더와 관계된 트랜잭션 정보는 다른 소스로부터 다운받아도 이 데이터들이 여전히 정확하다는 것이 보장된다. 이것이 가능한 이유는 Merkle tree에서 하위 노드들의 해시값이 상위 노드에 영향을 주기 때문에 어떤 악의적인 유저가 머클트리 최하위에 있는 트랜잭션 정보를 가짜로 바꿔치기 하면 상위 부모들의 해시값들이 변해서 결국 트리의 루트값이 바뀌므로, 결과적으로 이 블록의 해시가 달라지기 때문이다. 이렇게 되면 이 블록은 완전히 다른 블록으로 인식되게 되며, 이것은 유효하지 않은 작업증명을 가지고 있게 될 것이 분명하다. - -머클트리 프로토콜은 비트코인 네트워크를 장기간 지속가능하게 만드는 기초가 된다. 비트코인 네트워크에서 각 블록의 모든 정보를 저장하고 처리하는 "완전노드(full node)"는 2014년 4월 기준으로 거의 15 GB의 디스크 공간을 필요로 하며 매달 1 GB 넘게 증가하고 있다. 현재 데스크탑 컴퓨터 정도에서는 수용할 수 있지만 스마트폰에서는 불가능하다. 그리고 나중에는 소수의 사업체들이나 풀 노드를 유지할 수 있을 것이다. 반면 "단순화된 지불검증(simplified payment verification, SPV)"으로 알려진 프로토콜은 "가벼운 노드(light node)"라고 불리는 또 다른 형태의 노드를 가능하게 해준다. 가벼운 노드는 블록헤더를 다운로드하고 그 블록헤더에서 작업증명을 검증한다. 그리고 관련 트랜잭션들에 대한 "곁가지들(branches)"만을 다운로드 한다. 이렇게 전체 블록체인의 매우 작은 비율만을 다운로드 함에도 불구하고 강한 안전성을 보장하면서도, 임의의 트랜잭션의 상태 및 잔고 상태를 알아낼 수 있게 한다. - -### 블록체인 기술을 이용한 다른 응용 사례 (Alternative Blockchain Applications) - -블록체인의 근본 아이디어를 확장해 다른 개념으로 응용하려는 아이디어 역시 오랜 역사를 가지고 있다. 2005년 'Nick Szabo'는 "소유주 권한을 통한 재산권 보장"이라는 글을 발표했다. 그는 정주(homesteading), 불법점유, 지공주의(Georgism) 등의 개념을 포함한 정교한 틀을 설계해 누가 어떤 땅을 가지고 있느냐라는 등기 문제를 블록체인 기반 시스템으로 처리할 수 있음을 보였다. 그는 이것이 "데이터베이스 복제 기술의 새로운 발전"덕분에 가능해졌다고 말했다. 하지만, 불행히도 그 당시에는 쓸만한 효과적인 파일 복제 시스템이 없었기때문에 Nick Szabo의 프로토콜은 실현되지 못했다. 하지만 2009년 이후 비트코인 분권 합의 시스템이 발전하면서 수 많은 대안 응용 사례가 빠르게 부각되기 시작했다. - -* **네임코인** - 2010년에 만들어진 [네임코인](https://namecoin.org/)은 '탈중앙화된 명칭 등록 데이터베이스'라고 부르는 것이 가장 좋을 것이다. 토르, 비트코인, 비트메시지와 같은 탈중앙화된 자율조직 프로토콜을 이용할 때, 사용자는 타인과 서로 교류하기 위해 각자의 계정을 구분해내야 한다. 하지만 현존하는 가능한 구별 방법은 1LW79wp5ZBqaHW1jL5TCiBCrhQYtHagUWy와 같은 식의 의사난수 해쉬를 이용하는 방식이었다. 이상적으로는, 사용자가 "george"같은 일상적인 이름을 계정 이름으로 갖는 것이 좋겠지만 문제는 어떤 사용자가 "george" 라는 이름을 계정으로 만들 수 있다면, 다른 누구도 똑같이 "george"라는 계정을 등록해 흉내낼 수 있다는 점이다. 유일한 해답은 선출원주의로, 먼저 등록한 사람이 성공하고 두 번째 등록한 사람은 실패하도록 하는 것이다. 이는 이미 비트코인 합의 규약에 완벽히 적용된 문제이기도 하다. 네임코인은 이런 아이디어를 응용한 가장 오래되고 가장 성공적인 명칭 등록 시스템이다 - -* **컬러드 코인** - [컬러드 코인](https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit)의 목적은 누구나 비트코인 블록체인 위에서 자신만의 고유한 디지털 화폐를 발행할 수 있는 프로토콜 역할을 하는 것이다. 또는 (그 디지털 화폐의 발행량이 한 단위 밖에 없는 단순한 경우로 환원할 수 있는) 자기 자신만의 디지털 토큰을 발행하는 프로토콜 역할을 하는 것이다. 컬러드 코인 프로토콜에서, 사용자는 특정 비트코인 UTXO에 공개적으로 색깔을 부여함으로써 새 화폐를 "발행"할 수 있다. 다른 UTXO의 색깔은 이미 소비된(혼합 색깔 입력의 경우에는 몇몇 특별한 규칙이 적용된다) 것으로 간주하는 거래의 입력과 같은 색깔이 되도록 재귀적으로 정의한다. 이 프로토콜은 블록체인을 처음부터 끝까지 역추적해 그들이받은 UTXO의 색깔을 정함으로써, 사용자가 특정 색깔을 가진 UTXO만 지갑에 간직하고 그 코인을 보통 비트코인처럼 여기저기 보낼 수 있게 한다. - -* **메타코인** - 메타코인이 품고 있는 아이디어는, 비트코인 거래를 메타코인 거래 저장에 이용하되, 상태 이동 함수 APPLY' 를 다르게 가짐으로써, 비트코인 시스템 위에서 운영되는 프로토콜을 갖는 것이다. 메타코인 프로토콜만으로는 비트코인 블록체인 속에 무효 메타코인 거래가 나타나는 현상을 예방 수 없기 때문에, 규칙이 하나 더해진다. 즉 만약 APPLY'(S, TX)가 에러를 리턴하면, 프로토콜은 APPLY'(S,TX)=S로 정해진다. 비트코인 스스로는 내부 실행이 불가능한, 잠재적으로 더 발전된 성질을 가진 무작위 암호화폐 프로토콜을 만드는 쉬운 메커니즘이라고 할 수 있다. 반면 이 프로토콜의 개발비용은 적은데 왜냐하면 채굴과 네트워킹의 복잡성 문제가 이미 비트코인 프로토콜에 의해 처리되고 있기 때문이다. - -일반적으로 합의 프로토콜을 건설하는 데 두 가지 접근방법이 있다. 하나는 독립적인 네트워크를 세우는 것이고 다른 하나는 비트코인 시스템과 연동되는 프로토콜을 세우는 것이다. 전자의 접근 방법은 네임코인 같은 응용 사례에서는 상당히 성공적이었지만, 실제 실행하는 데 어려움이 있다; 각 개별 실행주체가 모든 필요한 상태변환과 네트워킹 코드를 건설하고 점검해야 할 뿐만 아니라 독립적인 블록체인을 구동시켜야 한다. 나아가, 분권 합의 기술에 관한 어플리케이션의 집합이 멱함수분포를 따를 것으로 예상된다. 즉, 대다수 어플리케이션은 자기 자신의 블록체인을 보장하기에는 너무 작을 것이다. 그리고 또 거대한 클래스의 분권화된 어플리케이션, 즉 서로 교류를 하기 위한 분권화된 자율 기구(DAO)가 생겨날 것이라고 예상한다. - -후자의 접근 방법, 즉, 비트코인에 기반한 접근 방법은 비트코인의 단순 지불 검증(SPV)특징을 물려받지 못한다는 단점이 있다. 단순지불검증은 비트코인에서는 작동한다. 왜냐하면 비트코인은 블록체인 깊이(depth)를 검증 대리 수단으로 이용할 수 있기 때문이다. 한 거래의 근원을 찾아 충분히 뒤로 돌아가보면, 그 상태의 정합성을 증명하는 부분이 있었다고 말해도 무방하다. 반면, 블록체인에 기반한 메타-프로토콜은 무효거래가 블록체인에 포함되지 않도록 막을 방법이 자기 자신의 프로토콜 자체에는 없다. 그렇기 때문에 완전히 안전보장이 된 단순지불검증 메타-프로토콜이라면, 어떤 거래가 유효한지 아닌지를 결정하기위해, 항상 비트코인 블록체인의 원점까지 돌아가 훑어보는 작업이 필요하다. 현재까지 비트코인에 기반한 메타-프로토콜의 모든 "간단한"(light) 클라이언트 구현은 자료를 제공하는 믿을 만한 서버에 의지하고 있는 형편이다. 우리가 암호화폐를 만든 가장 중요한 목적이 제3의 신용기구의 필요성을 없애는 것이었다는 걸 특히 되새겨본다면, 이것은 아주 분명하게도, 차선의 결과가 될 뿐이다. - -### 스크립팅 - -별도의 확장없이도 비트코인 프로토콜은 낮은 수준의 "스마트 계약"의 개념을 가능하게 할 수 있다. 비트코인의 UTXO는 공개키만으로 획득할 수 있을 뿐만 아니라, 단순 스택-기반 프로그래밍 언어로 표현되는 더 복잡한 스크립트로도 획득할 수 있다. 이런 경우에, UTXO를 지출하는 거래는 그 스크립트를 만족하는 데이터를 제공해야만 한다. 사실, 기초적인 공개키 소유권 메커니즘도 스크립트를 통해 실행된다: 그 스크립트는 타원곡선서명을 '입력'으로 받아 그 거래와 UTXO를 가진 주소에 대해 검증을 하고 만약 검증이 성공하면 1을, 실패하면 0을 '출력'한다. 여러 다른 다양한 사용 사례에 대해 좀 더 복잡한 여러 스크립트들이 있을 수 있다. - -예를 들어, 주어진 세 개의 개인 키 가운데 두 개로부터 서명을 받아야만 승인이 되도록 스크립트를 짤 수 있다. 이런 스크립트는 회사 계정, 보안 저축 계정, 상업 공탁 상황 등에 유용하게 쓰일 수 있다. 스크립트는 또한 어떤 계산 문제의 답에 대한 포상금을 지불하는데도 쓰일 수 있다. "만약 당신이 이 액면가의 도기코인 거래를 나에게 보냈다는 SPV 증명을 제공한다면, 이 비트코인 UTXO는 당신 것이다"라는 식으로 말하는 스크립트를 짤 수도 있다. 즉 근본적으로 탈중앙화된 상호-암호화폐 교환을 가능하게 한다. - -하지만 비트코인에 구현된 스크립트 언어는 몇가지 중요한 한계가 있다. - -* **튜링불완전성**: 비트코인 스크립트 언어로 할 수 있는 작업이 많긴 하지만, 모든 경우의 프로그래밍을 다 지원하지는 않는다. 특히 while이나 for와 같은 순환(loop) 명령 카테고리가 빠져 있다. 순환 명령어를 없앤 이유는 거래 증명을 할 때 무한 순환에 빠지는 것을 막기 위해서였다. 이론적으로는 튜링불완전성은 스크립트 프로그래머가 극복할 수 있는 장애물이기는 하다. 왜냐하면 어떤 순환 명령이든 단순히 하위 코드를 여러 차례 if 구문과 함께 반복함으로써 구현이 가능하기 때문이다. 하지만 이것은 아주 공간 비효율적인 프로그램이 된다. 예를 들어 대안 타원곡선서명 알고리즘을 실행하려면 코드 안에 있는 곱셈을 모두 개별적으로 256번 반복하는 것이 필요하다. - -* **가치무지하다**: UTXO 스크립트만으로는 인출 액수를 세밀하게 통제할 방법이 없다. 예를 들어 신탁 계약의 강력한 실용 사례라 할 수 있는 헷지 계약을 살펴보자. A와 B가 $1000어치의 BTC를 공동계좌에 입금했다고 하자. 시간이 지나면 비트코인의 가격이 오를 수가 있다. 두 사람은 30일 후 자동으로 A 가 $1000어치 BTC를 받고 B는 공동계좌의 나머지 잔액을 받는 그런 계약을 맺고 싶다. 하지만 이 계약은 1BTC가 미국 달러로 얼마인지 정해줄 제3자를 필요로 한다. 만약 이런 계약이 실현가능하다면 지금 현존하는 완전 중앙집권적인 금융 시스템 아래에서도 고도로 발전된 계약 형태라고 볼 수 있을 것이다. 하지만 UTXO는 인출액 전부가 송금되거나 말거나 밖에 선택할 수가 없다. 즉 세부 작은 단위로 나눠질 가능성을 포함할 수 없는 것이다. 위에 예를 든 계약 거래를 실행할 유일한 방법은 변하는 UTXO의 액면가 단위를 아주 다양하게 양산하고(예를 들어 1부터 30까지의 모든 자연수 k에 대해 2의 k승의 1 UTXO를 만듦) A가 B에게 이중에서 필요한 금액에 맞는 것을 선택해서 보내게 하는 방식과 같이 매우 비효율적인 편법을 사용하는 길 뿐이다. - -* **다양한 상태를 표현할 수 없다(Lack of State)**: UTXO가 표현할 수 있는 상태는 사용되었거나 안 되거나 둘 뿐이다. 그렇기 때문에 이 두가지 상태 이외에 다른 어떤 내부적 상태를 가지는 다중 단계 계약이나 스크립트를 만들 수가 없다. 이 점이 분산 환전 거래나 이중 암호 실행 프로토콜(계산 보상금을 보장하기 위해 필요하다)과 같은 다중 조건 계약을 어렵게 한다. 즉 UTXO은 단순하고 1회적인 계약에만 이용될 수 있을 뿐, 분산조직과 같은 더 복잡한 "상태적(stateful)" 계약에는 이용될 수 없고 메타프로토콜을 적용하기 어렵게 만든다. - -* **블록체인을 해독할 방법이 없다(Blockchain-blindness)**: UTXO는 논스(Nonce), 타임스탬프,이전 블록해시같은 블록체인 자료를 해독하지 못한다. 이 단점으로 인해 스크랩트 언어 속에 잠재적으로 가치있을 무작위성이 빠지게 된다. 그래서 도박이나 여러 다른 분야의 어플리케이션을 만드는 데 한계를 보인다. - -정리하자면, 발전된 어플리케이션을 만드는 데 3가지 접근법이 있다. 첫번째는 독립적인 블록체인을 만드는 것이고 두번째는 비트코인에 이미 내재된 스크립트를 이용하는 것이며, 세번째는 비트코인 상에서 작동되는 메타-규약을 건설하는 것이다. 독립적인 블록체을 쓰면 무한히 자유로운 프로그램을 짤 수 있지만 개발 기간, 초기 셋업 작업, 보안 등의 비용을 치뤄야 한다. 비트코인에 내재된 스크립트를 이용하면 실행이 간단하고 표준화된다는 장점이 있지만, 이용범위가 제한적이다. 메타규약을 쓰는 것은 간단하긴 하지만, 확장성의 결함을 감수해야 한다. -이더리움을 통해 우리는 개발하기도 쉽고 더 강력한 라이트 클라이언트 기능을 가지는 동시에 경제적인 개발 환경과 블록체인 보안을 공유하는 어플리케이션을 만들 수 있는, 대안 프레임워크(alternative framework)를 건설하려고 한다. - -## 이더리움 - -이더리움의 목적은 분산 어플리케이션 제작을 위한 대체 프로토콜을 만드는 것이다. 대규모 분산 어플리케이션에 유용할 것이라 생각되는 다른 종류의 제작기법을 제공하며, 빠른 개발 시간, 작고 드물게 사용되는 어플리케이션을 위한 보안, 다른 어플리케이션과의 효율적인 상호작용이 중요한 상황에 특히 주안점을 두고 있다. 이더리움은 튜링 완전 언어를 내장하고 있는 블록체인이라는 필수적이고 근본적인 기반을 제공함으로써 이 목적을 이루고자 한다. 누구든지 이 언어를 사용해 스마트 컨트랙트, 분산 어플리케이션을 작성하고 소유권에 대한 임의의 규칙, 트랜잭션 형식(transaction format), 상태변환 함수(state transition function) 등을 생성 할 수 있다. 네임코인의 기본적인 형태는 두 줄 정도의 코드로 작성할 수 있고, 통화나 평판 시스템 관련 프로토콜은 스무 줄 내외의 코드로 만들 수 있다. 어떤 값을 저장하고, 특정한 조건들을 만족했을 때만 그 값을 얻을 수 있게 하는 일종의 암호 상자인 스마트 컨트랙트 또한 이 플랫폼 위에 만들 수 있다. 이것은 비트코인의 스크립팅(scripting)이 제공하는 것보다 훨씬 강력한 기능들이 제공되기 때문에 가능한 것으로, 튜링-완전(Turing-completeness), 가치 인지능력(value-awareness), 블록체인 인지능력(blockchain-awareness), 상태(state)개념 등이 포함된다. - -### 이더리움 어카운트 - -이더리움에서, 상태(state)는 어카운트(account)라고 하는 오브젝트(object)들로 구성되어 있다. 각각의 어카운트는 20바이트의 주소와 어카운트 간 값과 정보를 직접적으로 전달해 주는 상태변환(state transition)을 가지고 있다. 이더리움 어카운트는 다음 네 개의 필드를 가지고 있다. - -* **논스(nonce)**: 각 트랜잭션이 오직 한번만 처리되게 하는 일종의 카운터 -* 어카운트의 현재 **이더(ether) 잔고** -* 어카운트의 **계약 코드** (존재한다면) -* 어카운트의 **저장 공간** (초기설정(default) 상에서는 비어있음) - -이더는 이더리움의 기본 내부 암호-연료(crypto-fuel) 이고, 트랜잭션 수수료를 지불하는데 사용된다. 보통 두가지 종류의 어카운트가 존재하는데, 프라이빗 키에 의해 통제되는 외부 소유 어카운트(Externally Owned Accounts)와 컨트랙트 코드에 의해 통제되는 컨트랙트 어카운트(Contract Accounts)가 있다. 외부 소유 어카운트는 아무런 코드도 가지고 있지 않으며, 이 어카운트에서 메시지를 보내기 위해서는 새로운 트랜잭션을 하나 만들고, 서명(signing)을 해야 한다. 컨트랙트 어카운트는 메시지를 받을 때마다, 자신의 코드를 활성화시키고, 이에 따라 메시지를 읽거나 내부 저장공간에 기록하고, 다른 메시지들을 보내거나, 컨트랙트들을 차례로 생성하게 된다. -이더리움에서 컨트랙트는, 수행되거나 컴파일 되어져야 할 어떤 것이라기 보다는, 이더리움의 실행 환경안에 살아있는 일종의 자율 에이전트(autonomous agents)로서, 메시지나 트랜잭션이 도착하면 항상 특정한 코드를 실행하고, 자신의 이더 잔고와, 영속적인 변수들을 추적하기 위해 자신의 키/값 저장소를 직접적으로 통제하는 역할을 한다. - -### 메시지와 트랜잭션 - -이더리움에서 사용되는 트랜잭션(transaction)이란 용어는 외부 소유 어카운트가 보낼 메시지를 가지고 있는 서명된 데이터 패키지를 말한다. 이 트랜잭션은 다음을 포함하고 있다. - -* 메시지 수신처 -* 발신처를 확인할 수 있는 서명 -* 발신처가 수신처로 보내는 이더의 양 -* 선택적(optional) 데이터 필드 -* STARTGAS 값, 트랜잭션 실행이 수행되도록 허용된 최대 계산 단계수 -* GASPRICE 값, 매 계산단계마다 발신처가 지불하는 수수료 - -처음 세 항목은 암호 화폐에서는 거의 표준처럼 사용되는 값이다. 데이터 필드는 초기값으로 설정된 기능(function)은 가지고 있지 않지만, 버추얼 머신(virtual machine)은 컨트랙트가 이 데이터에 접근할 때 사용할 수행코드(opcode)를 가지고 있다. 예를 들어, 블록체인 위에 도메인 등록 서비스로 기능하고 있는 컨트랙트가 있을 경우, 이 컨트랙트로 보내지는 데이터는 두개의 필드를 가지고 있는 것으로 해석할 수 있다. 첫번째 필드는 등록하고자 하는 도메인이고, 두번째 필드는 IP 주소이다. 컨트랙트는 메시지 데이터로부터 이 값들을 읽어서 저장소 내 적당한 위치에 저장한다. - -STARTGAS 와 GASPRICE 필드는 이더리움의 앤티-서비스거부(anti-DoS) 모델에 있어서 매우 중요한 역할을 한다. 코드내의 우연적이거나 악의적인 무한루프, 또는 계산 낭비를 방지하기 위해 각각의 트랜잭션은 사용할 수 있는 코드 실행의 계산 단계 수를 제한하도록 설정되어야 한다. 계산의 기본 단위는 gas이고 보통, 계산 단계는 1 gas의 비용이 소요되나, 어떤 연산은 더 비싼 계산 비용을 치루거나, 상태의 일부분으로 저장되어야 하는 데이터의 양이 많을 경우 더 많은 수의 gas 비용이 필요하게 된다. 또한 트랜잭션 데이터에 있는 모든 바이트는 바이트당 5 gas 의 수수료가 든다. 이러한 수수료 시스템의 의도는 어떤 공격자가 계산, 밴드위스, 저장소 등을 포함해 그들이 소비하는 모든 리소스에 비례하여 강제로 수수료를 지불하게 하는데 있다. 따라서, 이런 리소스중 어떤 것이라도 상당량을 소비하는 네트웍과 연관된 트랜잭션은 대략 증가분에 비례한 gas 수수료를 가지고 있어야 한다. - -### 메시지(Messages) -컨트랙트는 다른 컨트랙트에게 “메시지”를 전달할 수 있다. 메시지는 따로 저장될 필요가 없는 이더리움의 실행 환경에서만 존재하는 가상의 오브젝트이다. 메시지는 다음의 것을 포함하고 있다. - -* (암묵적으로) 메시지 발신처 -* 메시지 수신처 -* 메시지와 함께 전달되는 이더 -* 선택적 데이터 필드 -* STARTGAS 값 - -본질적으로, 메시지는 외부 실행자가 아닌 컨트랙트에 의해 생성된다는 것을 제외하면 트랜잭션과 유사하다. 현재 코드 수행을 하고 있는 컨트랙트가 메시지를 생성하고 실행하라는 CALL opcode를 만나게 되면 메시지를 생성한다. 트랜잭션과 마찬가지로, 메시지는 해당 코드를 실행하는 수신자 어카운트에 도달하게 된다. 따라서, 컨트랙트는 외부 실행자가 하는 것과 정확히 같은 방식으로 다른 컨트랙트와 관계를 맺을 수 있다. -트랜잭션이나 컨트랙트에 의해 할당된 gas 허용치는 그 트랜잭션과 모든 하위 실행에 의해 소모된 총 gas 에 적용된다. 예를 들어, 외부 실행자 A가 B에게 1000 gas와 함께 트랜잭션을 보내고, B는 600 gas를 소모한 뒤 C에게 메시지를 보내고, C의 내부 실행에 300 gas를 소모한 후 반환하면, B는 gas가 모두 소모되기 전에 100 gas를 더 사용할 수 있다. - - -### 이더리움 상태 변환 함수(Ethereum State Transition Function) - -![ethertransition.png](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/ethertransition.png) - -이더리움 상태 전이 함수 APPLY(S, TX) -> S’ 는 다음처럼 정의될 수 있다. -트랜잭션이 형식에 제대로 맞는지(즉, 올바른 갯수의 값을 가지고 있는지) 체크하고, 서명이 유효한지, 논스가 발신처 어카운트의 논스와 일치하는지를 체크한다. 그렇지 않다면 오류를 반환한다. -STARTGAS * GASPRICE 로 트랜잭션 수수료를 계산하고, 서명으로부터 발신처 주소를 결정한다. 발신처 어카운트 잔고에서 이 수수료를 빼고 발신자 논스를 증가시킨다. 발신처 잔고가 충분하지 않으면 오류를 반환한다. -GAS = STARTGAS 로 초기화 한후, 트랜잭션에서 사용된 바이트에 대한 값을 지불하기 위해 바이트당 gas의 특정양을 차감한다. -발신처 어카운트에서 수신처 어카운트로 트랜잭션 값을 보낸다. 수신처 어카운트가 존재하지 않으면 새로 생성한다. 수신처 어카운트가 컨트랙트이면, 컨트랙트의 코드를 끝까지, 또는 gas가 모두 소모될 때 까지 수행한다. -발신처가 충분한 ‘돈'을 가지고 있지 못해서 값 전송이 실패하거나, 코드 수행시 gas가 부족하면, 모든 상태 변경를 원상태로 돌려놓는다. 단, 수수료 지불은 제외되고, 이 수수료는 채굴자 어카운트에 더해지게 된다. -그 외에는, 모든 남아있는 모든 gas에 대한 수수료를 발신처에게 돌려주고, 소모된 gas에 지불된 수수료를 채굴자에게 보낸다. - -예를 들어, 다음과 같은 컨트랙트 코드를 가정해 보자. - - if !self.storage[calldataload(0)]: - self.storage[calldataload(0)] = calldataload(32) - -실제로 컨트랙트 코드는 로우-레벨 EVM 코드로 작성되나, 이 예제는 이해하기 쉽게 하기 위해, 이더리움 하이-레벨 언어중 하나인 Serpent 로 작성하였다. 이 코드는 EVM 코드로 컴파일 될 수 있다. 컨트랙트의 스토리지는 비어있다고 가정하고, 트랜잭션이 10 ether, 2000 gas, 0.001ether gasprice, 64 바이트의 데이터(0-31 바이트까지는 숫자 2를 나타내고, 32-63 바이트는 CHARLIE 라는 문자열)를 보낸다고 가정하자. 이 경우 상태 변환 함수의 프로세스는 다음과 같다. - -1. 트랜잭션이 유효하고 형식에 제대로 맞는지 확인한다. -2. 트랜잭션 발송처가 최소 2000 * 0.001=2 ether를 가지고 있는지 확인하고, 그럴 경우, 발송처의 어카운트에서 2 ether를 뺀다. -gas=2000으로 초기화 한 후, 트랜잭션은 170바이트 길이를 가지고, 바이트당 수수료는 5라고 가정하면, 850을 빼야 하고 결국 1150 gas가 남게된다. -3. 송신처 어카운트에서 추가 10 ether를 빼고 이것을 컨트랙트 어카운트에 더한다. -4. 코드를 실행시킨다. 이 경우는 간단한데, 컨트랙트의 index 2에 해당하는 스토리지가 사용되었는지 확인하고 (이 경우, 사용되지 않았다.) index 2에 해당하는 스토리지 값을 CHARLIE 로 설정한다. 이 작업에 187 gas 가 소비됐다고 가정하면, 남아있는 gas 의 양은 1150 - 187 = 963 이 된다. -5. 963*0.001 = 0.963 ether를 송신처의 어카운트로 되돌려주고, 결과 상태를 반환한다. - -트랜잭션의 수신처에 컨트랙트가 없으면, 총 트랜잭션 수수료는 제공된 GASPRICE와 트랜잭션의 바이트 수를 곱한 값과 같아지고, 트랜잭션과 함께 보내진 데이터는 관련이 없어지게 된다. - -메시지는 트랜잭션과 마찬가지 방식으로, 상태를 원래 상태로 되돌린다는 것에 주목하자. 메시지 실행시 gas가 부족하게 되면, 그 메시지 실행과 그 실행에 의해 촉발된 다른 모든 실행들은 원래대로 되돌려지게 되지만, 그 부모 실행은 되돌려질 필요가 없다. 이것은 컨트랙트가 다른 컨트랙트를 호출하는 것은 안전하다는 것을 의미한다. A가 G gas를 가지고 B를 호출하면, A의 실행은 최대 G gas만을 잃는다는 것을 보장받게 된다. 컨트랙트를 생성하는 CREATE라는 opcode를 보면, 실행 방식은 대체로 CALL과 유사하나, 실행 결과는 새로 생성된 컨트랙트의 코드를 결정한다는 차이가 있다. - -### 코드 실행(Code Execution) - -이더리움 컨트랙트를 구성하는 코드는 “이더리움 버추얼 머신 코드” 또는 “EVM 코드”로 불리는 로우-레벨, 스택 기반의 바이트코드 언어로 작성된다. 이 코드는 연속된 바이트로 구성되어 있고, 각각의 바이트는 연산(operation)을 나타낸다. 보통, 코드 실행은 0부터 시작하는 현재 프로그램 카운터를 하나씩 증가시키면서 반복적으로 연산을 수행하도록 구성된 무한 루프이고, 코드의 마지막에 도달하거나 오류, STOP, RETURN 명령을 만나면 실행을 멈추게 된다. 연산을 수행하기 위해서는 데이터를 저장하는 세가지 타입의 공간에 접근할 수 있어야 한다. - -* **스택**: last-in-first-out 컨테이너로 여기에 값들을 밀어 넣거나(push) 하거나 뺄(pop) 수 있다. -* **메모리**: 무한대로 확장 가능한 바이트 배열 -* 컨트랙트의 영속적인(long-term) **저장소(storage)**: 키/값 저장소. 계산이 끝나면 리셋되는 스택이나 메모리와는 달리 저장소는 영속적으로 유지된다. - -코드는 또한 블록 헤더 데이터 뿐만 아니라 특정 값이나, 발송자 및 수신되는 메시지의 데이터에 접근할 수 있고, 결과값으로 데이터의 바이트 배열을 반환할 수도 있다. - -EVM 코드의 공식 실행 모델은 놀랍도록 단순하다. 이더리움 버추얼 머신이 실행되는 동안, 모든 계산 상태는 (block_state, transaction, message, code, memory, stack, pc, gas) 튜플(tuple)로 정의될 수 있고, block_state는 모든 어카운트를 포함하는 전역상태(global state)로서 잔고와 저장소(storage)를 포함한다. 반복되는 매 코드 실행 순간의 시작시, code의 pc(프로그램 카운터)번째 바이트의 현재 명령이 실행되고, ( pc 가 코드의 길이보다 크면(pc >= len(code)) pc 는 0), 각각의 명령은 튜플을 어떻게 변화시킬지 대한 그 자신의 정의를 알고 있다. 예를 들어, ADD는 스택에서 두개의 아이템을 꺼내(pop), 그 합을 구한 후 다시 스택에 넣고(push) gas를 1만큼 감소시키고, pc는 1 증가시킨다. SSTORE 는 스택에서 두개의 아이템을 꺼내 이 아이템의 첫번째 값이 가리키는 컨트랙트 저장소 인덱스에 두번째 아이템을 넣는다. 이더리움 버추얼 머신 환경을 JIT 컴파일을 통해 최적화 하는 많은 방법이 있지만, 기본적인 이더리움은 수백줄의 코드로 구현될 수 있다. - -### 블록체인과 채굴(Blockchain and Mining) - -![apply_block_diagram.png](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/apply_block_diagram.png) - -이더리움 블록체인은 여러면에서 비트코인 블록체인과 유사하나, 어느정도 차이점들이 있다. 이더리움과 비트코인에서의 각 블록체인 구조에 대한 주요 차이점으로는 비트코인과는 달리 이더리움 블록은 트랜잭션 리스트와 가장 최근의 상태(state) 복사본을 가지고 있다는 것이다. 그것 외에도, 두개의 다른 값 - 블록 넘버와 difficulty - 이 또한 블록내에 저장된다. 기본적인 이더리움 블록 검증 알고리즘은 다음과 같다. - -1. 참조하고 있는 이전 블록이 존재하는지 그리고, 유효한지 확인한다. -2. 현재 블록의 타임스탬프가 참조하고 있는 이전 블록의 그것보다 크면서, 동시에 현 시점을 기준으로 15분 후보다 작은 값인지 확인한다. -3. 블록 넘버, difficulty, 트랜잭션 루트, 삼촌 루트, gas 리미트등(기타 다양한 이더리움 로우 레벨 개념)이 유효한지 확인한다. -4. 블록에 포함된 작업 증명이 유효한지 확인한다. -5. S[0] 이 이전 블록의 마지막 상태(state)라고 가정 하자. -6. TX를 현재 블록의 n개의 트랜잭션 리스트라고 하자. 0 부터 n-1에 대해, S[i+1] = APPLY(S[i], TX[i]) 로 설정하자. 어플리케이션이 오류를 반환하거나, 이 시점까지 블록에서 소모된 총 gas가 GASLIMIT를 초과하면 오류를 반환한다. -7. 채굴자에게 지불된 보상 블록을 S[n] 덧붙인 후 이것을 S_FINAL 이라 하자. -8. 상태 S_FINAL의 머클 트리 루트가 블록 헤더가 가지고 있는 최종 상태 루트와 같은지를 검증한다. 이 값이 같으면 그 블록은 유효한 블록이며, 다르면 유효하지 않은 것으로 판단한다. - -이러한 접근은 언뜻, 모든 상태를 각 블록에 저장할 필요성 때문에 매우 비효율적인 것처럼 보이지만, 실제로는 효율성의 측면에서는 비트코인과 비교할만 하다. 그 이유로는 상태가 트리 구조로 저장되고, 모든 블록 후에 단지 트리의 작은 부분만이 변경되기 때문이다. 보통, 인접한 두 개의 블록간에는 트리의 대부분의 내용이 같고, 따라서 한번 데이터가 저장되면 포인터(서브트리의 해쉬)를 사용하여 참조될 수 있다. 패트리시아 트리(Patricia tree)로 알려진 이러한 종류의 특별한 트리는 머클 트리 개념을 수정하여 노드를 단지 수정할 뿐만 아니라, 효율적으로 삽입되거나 삭제하여 이러한 작업을 수행할 수 있도록 해준다. 또한, 모든 상태 정보가 마지막 블록에 포함되어 있기 때문에, 전체 블록체인 히스토리를 모두 저장할 필요가 없어지게 된다. 이 방법을 비트코인에 적용한다면 5~20배의 저장 공간 절약의 효과가 생길 것이다. - -물리적인 하드웨어 관점에서 볼 때, 컨트랙트 코드는 “어디에서" 실행되는가 하는 의문이 쉽게 들 수 있다. 간단한 해답은 다음과 같다. 컨트랙트 코드를 실행하는 프로세스는 상태 전환 함수 정의의 한 부분이고, 이것은 블록 검증 알고리즘의 부분이다. 따라서, 트랜잭션이 블록 B에 포함되면 그 트랜잭션에 의해 발생할 코드의 실행은 현재 또는 향후에 블록 B 를 다운로드 하고 검증하는 모든 노드들에 의해 실행될 것이다. - -## 어플리케이션(Applications) - -기본적으로, 이더리움을 이용하여 총 세 가지 카테고리의 어플리케이션을 제작할 수 있다. 첫번째 카테고리는 돈과 직접적으로 연관된 컨트랙트를 계약참여자로 하여금 보다 강력하게 설정-관리하게끔 하는 금융 어플리케이션이다. 이의 예는 하위화폐(=유로/달러 등의 상위화폐와 환율이 연동된 화폐를 지칭), 파생상품, 헷지컨트랙트, 예금용 전자지갑, 유언장, 그리고 최종적으로는 전면적인 고용계약 수준의 것들까지 포함한다. 두번째 카테고리는 준(準)금융 어플리케이션이다. 금전이 관여되어 있지만, 상당부분 비(非)화폐적인 면이 존재하는 계약을 위한 어플리케이션이 이에 해당된다. 이의 좋은 예로는 어려운 연산 문제를 푸는 자에게 자동적으로 포상금이 지급되는 계약이다. 마지막으로, 온라인 투표와 분권형(分權形) 거버넌스(Governance)와 같이 금융과 관련성이 아예 없는 어플리케이션이 있다. - -### 토큰 시스템(Token Systems) - -블록체인토큰시스템(On-blockchain token system)은 미화/금 등과 연동된 하위화폐, 주식과 “스마트자산* (Smart Property: 비트코인의 블록체인 상에서 소유권이 컨트롤/관리되는 자산),” "위조불가능한(secure unforgeable)" 쿠폰, 그리고 통상적인 가치와 연결되어 있지 않은 기타 토큰시스템 (예, 인센티브 부여를 위한 포인트제도) 등에 이르기까지 다양한 형태의 거래시스템을 네트워크 상에서 구현하게끔 해주는 어플리케이션들을 갖고 있다. 이더리움에서 토큰시스템은 놀랍도록 쉽게 구현할 수 있다. 토큰시스템을 이해하는 데에 핵심은 아래와 같다. - -* 모든 화폐 혹은 토큰시스템은 근본은 결국 한 가지 오퍼레이션만을 수행하는 데이터베이스이다. -* A라는 주체로부터 X 단위의 화폐/토큰을 차감하고, 차감한 X 단위의 화폐/토큰을 B에게 지급한다. 단, -거래 전, A는 최소 X단위를 보유하고 있었음 -* A가 이 거래를 승인함 - -이더리움에서 유저는 바로 위의 로직을 컨트랙트에 반영 시키기만 하면 된다. -Serpent 에서 토큰시스템을 실행하는 기본적은 코드는 아래와 같다: - - def send(to, value): - if self.storage[msg.sender] >= value: - self.storage[msg.sender] = self.storage[msg.sender] - value - self.storage[to] = self.storage[to] + value - -이는 기본적으로 본 백서에서 설명한 “은행시스템”의 "상태변환함수(state transition function)"를 아무런 가공없이 그대로적용시킨 것이다. 통화의 단위를 정의하고 배급하기 위한 최초 작업을 위해서, 또는 더 나아가 여타 컨트랙트들이 계좌의 잔금에 대한 정보요청을 처리하기 위한, 몇 줄의 코드가 추가적으로 더 쓰여져야 할 수도 있다. 하지만, 그 정도가 토큰시스템을 만드는 데 필요한 전부이다. 이론적으로, 이더리움에 기반한 하위화폐 체계로서의 토큰시스템은 비트코인에 기반한 메타화폐 (=비트코인 블록체인 연동된 화폐)가 갖고 있지 않는 중요한 특성을 지니고 있을 수 있다: 거래비용을 거래 시 사용한 화폐로 직접 지불할 수 있다는 점이 그것이다. 다음과 같은 과정을 통하여 이 특성은 발현될 수 있다: 컨트랙트을 집행하기 위해서는 발송인에게 지불해야 하는 비용 만큼의 이더 잔고를 유지해야 한다. 그리고 컨트랙트 집행 시 수수료로 받는 내부화폐(하위화폐)를 (상시 돌아가고 있는 내부화폐-이더 거래소에서) 즉각 환전하여 이더 잔고로 충전할 수 있다. 유저들은 그렇게 이더로 그들의 계좌들을 “활성화”시켜야 하지만 각 컨트랙트를 통해 얻어지는 만큼의 금액을 이더로 매번 환전해 주기에, 한 번 충전된 이더는 재사용이 가능하다고 볼 수 있다. - -### 파생상품과 가치안정통화 - -파생상품은 “스마트 컨트랙트”의 가장 일반적인 어플리케이션이며, 코드로 실행할 수 있는 가장 간단한 형태의 어플리케이션 중 하나다. 금융 컨트랙트를 실행하는 데 가장 주된 어려움은 대부분의 경우 계약에서 규정하는 자산에 대한 시세를 외부에서 참조해야 한다는 것이다. 예를 들어, 금융컨트랙트에 매우 필요한 것은 이더(또는 기타 가상화폐)-USD 변동성에 대해 헷지(hedge)하는 어플리케이션인데, 이 헷지컨트랙트를 실행하기 위해서는 ETH/USD의 환율을 제공할 수 있는 컨트랙트가 필요하다. 환율을 알기 위한 가장 쉬운 방법은 주식시장의 NASDAQ과 같은 특정한 제 3자가 실시간으로 제공하는 “데이터피드” 컨트랙트를 통해서이고, 관여주체는 필요할 때 마다 환율을 업데이트할 수 있어야 하며, 여타 컨트랙트들과 환율에 대한 메시지를 주고받을 수 있는 인터페이스를 제공할 수 있어야 한다. - -상기 핵심 요건들을 가정하고, 위 언급한 헷지컨트랙트는 다음과 같은 구조를 띌 것이다: - -1. A가 1000 이더를 입금할 때까지 기다린다 -2. B가 1000 이더를 입금할 때까지 기다린다 -3. 입금된 이더의 달러가치를 기록하며 (환율은 Data feed 컨트랙트로 쿼리를 보냄으로써 계산한다), 이를 $X라 한다 -4. 30일 이후, 당시의 환율을 적용한 금액을 계산하여 A에게는 $X를 송금하고 당시 총금액에 나머지를 B에게 송금하도록 A 또는 B가 컨트랙트를 다시 활성화 시킬 수 있게끔 한다. - -위와 같은 컨트랙트는 가상통화를 이용한 상거래의 향후 발전 가능성을 제시한다. 가상화폐 상거래 활성화의 장애물 중 하나는 가상화폐의 높은 변동성이다; 다수의 유저들과 상인들은 가상화폐 혹은 블록체인자산이 제공하는 보안성과 편의성에 대한 니즈가 있지만, 단 하루만의 그들의 자산가치가 23% 하락할지도 모른다는 리스크는 피하고 싶어한다. 이 문제에 대한 지금까지의 가장 보편적인 솔루션은 자산 발행자가 자산에 대한 보증을 서는 것이었다: 이는 곧, 빌헹자가 하위화폐를 만들어서 그를 통해서 통화량을 조절할 수 있는 권한을 갖고, 누군가가 일정 단위의 하위화폐를 지불하였을 때 그에 상응하는 특정한 베이스 자산 (예, USD, 금)으로 교환해주는 방식을 뜻한다. 이 방식을 본 사례에 적용한다면, 가상화폐 발행자는 가상화폐를 지불하는 자에게 그에 상응하는 베이스자산을 제공할 것이라고 공개적인 약속을 하는 것이다. 이 메커니즘은 비(非)가상화폐 혹은 비(非)디지털자산을 블록체인 자산화(化)자산화 시키는 결과를 낳는다—물론 가상화폐 발행자를 신뢰할 수 있다면 말이다. - -다만, 현실적으로는 자산 발행인을 언제나 신뢰를 할 수 없으며, 몇몇 사례를 보면, 우리의 금융인프라는 자산보증 서비스가 존재하기에는 너무 취약하거나, 때로는 적대적이기도 하다. 파생상품은 이에 대한 대안을 제공해준다. 여기서 자산을 보증하기 위한 펀드를 제공하는 역활을 하나의 자산 발행자가 하는 것이 아니라 -암호화 담보자산(cryptographic reference asset, 예: 이더)의 가격이 올라갈 것이라는 데에 베팅을 하는 투자자들(speculators)의 탈중앙화된 시장이 그 역할을 담당하게 된다. -파생상품을 통한 보증 또한 완전하게 탈중앙화된 방법론은 아니라는 것을 주의하기 바란다. 비록 자산 발행자을 통한 방법 보다 진입장벽(영업허가증 등이 필요 없음)이 없고 사기/조작 가능성이 줄어들기는 하지만, 신뢰성있는 제 3기관이 USD/ETH 시세 또는 환율을 제공해야 하기 때문이다. - -### 신원조회 / 평판 시스템(Identity and Reputation Systems) - -최초의 알트코인(비트코인 이후에 생겨난 가상화폐)인 네임코인은 비트코인과 유사한 블록체인을 이용하여 사용자가 공공DB에 다른 데이터와 함께 본인의 이름을 등록하는 명의등록 시스템을 만들어냈다. 이의 주된 사용례는 “bitcoin.org”와 (Namecoin의 경우에는 “bitcoin.bit”) 도메인명을 매핑하는 DNS 시스템이다. 다른 사용례에는 이메일 인증, 그리고 보다 진일보된 평판 시스템 등이 있다. 이더리움에서 네임코인과 같은 명의등록 시스템의 기본적인 컨트랙트는 아래와 같은 형태를 띈다. - - def register(name, value): - if !self.storage[name]: - self.storage[name] = value - -이 컨트랙트는 매우 단순하게도, 이더리움 네트워크 안에서 저장되어 있는, 추가할 수는 있지만 수정하거나 지울 수 없는 데이터 베이스일 뿐이다. 누구든지 소량의 이더를 이용하여 본인의 명의를 등록할 수 있으며, 한 번 등록하면 영구적으로 보존된다. 보다 정교한 명의등록 컨트랙트는 다른 컨트랙트가 보내는 쿼리에 반응할 수 있는 함수조건이 걸려 있을 것으며, 명의 소유자 (곧, 최초 등록자)가 데이터를 변경하거나 명의소유권을 이전할 수 있는 메커니즘이 장착되어 있을 것이다. 혹자는 평판이나 인터넷신용도 기능등을 그 위에 추가할 수도 있다. - -### 분산형 파일 저장소(Decentralized File Storage) - -지난 몇년 동안, 드롭박스와 같은 웹 상에 파일을 저장시켜주는 인기있는 스타트업이 다수 생겨났다 (월 정액에 유저들이 하드드라이브를 백업 시켜 놓고 백업파일에 액세스 할 수 있는 비즈니스 모델임). 그러나, 현시점에서 파일저장 시장은 종종 상대적으로 비효율적일 때가 많다. [현재 존재하는 솔루션](http://online-storage-service-review.toptenreviews.com/)들의 월정액 가격을 보면 (특히 무료 할당량도 기업 할인도 없는 20-200기가바이트 수준의 기업이 지불하는 월정액), 한달만 써도 전체 하드드라이브의 비용보다 더 비쌀 정도이다. 이더리움의 컨트랙트는 분산형 파일 저장소 생태계의 발전을 가능케한다. 이 생태계에서 유저 개개인은 본인의 하드드라이브를 대여해주는 대가로 소액의 돈을 받을 수 있으며 남는 하드디스크 공간은 파일저장의 비용을 더욱 낮추는 결과를 낳을 것이다. -분산형 파일 저장소의 핵심 기반은, 소위 “분산형 드롭박스 컨트랙트”가 될 것이다. 이 컨트랙트는 다음과 같이 작동한다: 1) 유저가 업로드하려는 데이터를 블록으로 잘라내고, 2) 프라이버시를 위해 해당 데이터를 암호화 시킨 후, 3) 그 데이터로 머클트리를 만든다. 위 데이터에 대한 컨트랙트는 아래와 같은 룰에 의해서 유지된다. - -* N개의 블록 마다 무작위 방식으로 (컨트랙트 코드로 접근가능한 전 블록의 해쉬에 기반한 무작위 방식) 머클트리의 인덱스를 뽑는다. -* 유저가 올린 파일에 해당하는 트리의 특정 인덱스에 대하여, 해당 데이터를 저장해주겠다는 첫 주체에게 (간소화된 지불증명이자 소유권증명의 의미를 띄는) X 이더를 지불한다. - -파일을 올린 유저가 다시 자신의 파일을 다운로드 하고 싶을 때에는, 소액결제 채널 프로토콜(예, 32킬로바이트에 1 szabo를 지불한다)을 사용해서 파일을 복원할 수 있다; 수수료 측면에서 가장 효율적인 접근방법은 파일을 업로드한 유저가 저장이 끝나는 마지막까지 파일에 대한 트랜스액션을 공표하지 않고, 매 32 킬로바이트 마다 동일한 Nonce를 갖고 있는 보다 수익성이 있는 트랜스액션으로 바꿔주는 방법이 있다. - -비록 이 방식은 파일을 업로드한 유저가 다수의 랜덤한 노드들이 나의 파일을 계속 저장하고 있을 것이라고 믿어야 한다는 것을 전제하는 것 처럼 보이지만, 실제로는 유저는 업로드한 파일을 수많은 암호화된 조각으로 잘라내서 여러 노드들과 공유하고 또 컨트랙트를 통해서 외부 노드들이 내가 올린 파일을 저장하고 있다는 것을 모니터링함으로써 내가 올린 파일에 대한 분실 혹은 제 3자에의한 도용이라는 리스크를 거의 0에 가깝게 줄일 수 있다는 것이 분산형 드롭박스 컨트랙트 중요한 특징이다. 컨트랙트가 계속 돈을 지불하고 있다는 것은 곧 네트워크 상에서 누군가는 파일을 저장하고 있다는 것을 증명한다. - -### 탈중앙화된 자율조직(Decentralized Autonomous Organizations) - -“탈중앙화된 자율조직”의 기본적인 개념은특정한 집합의 구성원 또는 주주들을 갖고 있는 가상 독립체(virtual entity)가 필요한 수만큼의 구성원의 동의하에(예, 67% 다수) 조직자금운용 권한 및 코드 변경 권한을 갖는다는 것이다. 구성원들은 그 조직이 어떻게 운영자금을 배분할지를 공동으로 결정할 것이다. DAO의 자금을 배분하는 방식은 포상, 급여 형식부터 보다 색다른 내부화폐로 보상하는 형식까지 다양하다. 이것은 본질적으로 통상적인 기업이나 비영리재단에서 사용하는 법적인 장치들을 그대로 따르는 것이지만, 그 집행의 강제(enforcement)를 위해 암호화 블록체인 기술을 사용한다는 점이 차별점이다. 지금까지의 DAO에 대한 논의는 주로 "자본주의적(capitalist)" 모델인 "탈중앙화된 자율기업(decentralized autonomous corporation, DAC)"에 관한 것이었는데, 이 DAC는 배당을 받는 주주들과 매매가능한 지분을 가지고 있다. 이것에 대한 대안적인 형태로 "탈중앙화된 자율 커뮤니티( decentralized autonomous community)" 같은 개념도 생각해 볼 수 있는데, 이 안에서 구성원들은 의사결정에 있어서 모두 동일한 지분을 갖고있으며, 기존 구성원의 67%의 표결을 통한 동의가 있을 때 구성원을 충원하거나 탈퇴시킬 수 있을 것이다.그렇다면, 한사람이 오직 하나의 멤버십만을 가져야한다는 요건이 그 그룹에 의해 공동으로 시행될 필요가 있을 것이다. -DAO 코딩에 관한 일반적인 개요는 다음과 같다. 가장 간단한 디자인은 단순하게도 구성원 2/3가 동의/거부하였을 시 저절로 코드가 변경되는 컨셉이다. 비록 이론적으로 한 번 세팅된 코드는 바뀔수 없어도, 별도의 코드들을 각각 다른 컨트랙트들로 분리시켜서, 이것을 변경가능한 저장공간에 각각 넣어둔 다음, 이 코드들을 불러낼 수 있는 주소들을 제공함으로써 우리는 실제적으로 코드가 변경된 것과 같은 효과를 만들 수 있다. 아주 간단한 DAO 컨트랙에는 3가지 종류의 트랙잭션들이 있을 수 있는데, 그 구분은 그 트랜잭션이 제공하는 데이터의 종류에 따른다: - -* [0,i,K,V]는 저장공간 인덱스 k 에 있는 주소를 v 값으로 바꾸라는 인덱스 i 를 가진 제안을 등록 -* [0,i]는 제안 i 에 찬성하는 투표를 등록 -* [2,i] 는 충분한 투표가 이루어 졌을 때 제안 i 를 완결 - -컨트랙트는 상기 항목들 각각에 대한 조건절을 갖고 있을 것이다. 컨트랙은 모든 오픈스토리지에 일어난 변화들과 누가그 변화들에 대해 투표했는가하는 리스트를 보관유지하게 될 것이다. 컨트랙은 또한 전체 구성원 리스트도 보관한다. 어떤 스토리지 변경이던지 구성원의 2/3 의 투표를 받으면, 마지막으로 확정시키는 트랜잭션이 그 변경을 집행할 수 있게 된다. 이것보다 좀 더 발전된 형태는 내장 투표 기능을 이용해서 트랜잭션을 송신하거나, 구성원을 충원/탈퇴시키거나, 위임 민주주의 ([Liquid Democracy 또는 Delegative Democracy](http://en.wikipedia.org/wiki/Delegative_democracy))의 투표위임등의 기능도 추가할 수 있을 것이다. 이런 투표위임을 통해 누구에게나 자신을 위해 투표할 수 있도록 위임할 수 있고, 또 이 권한은 다른 사람에게 다시 전가가 될 수도 있다. A가 B에게 위임하고, B는 C에게 위임하면, C가 A의 투표를 결정한다. 이러한 설계를 통해서, DAO는 탈중앙화된 커뮤니티로 유기적으로 성장할 수 있으며, 더 나아가 누가 구성원인지 아닌지를 판단하는 기능을 전문가들에게 위임 할 수도 있도록 해줄 것이다. (물론 "현행시스템"과 달리, 각 커뮤니티 구성원들의 의견이 바뀜에 따라, 그러한 전문가들은 있을 수도/없을 수도 있게 된다.) - -이것과 비교되는 다른 모델은 탈중앙화된 기업이라고 할 수 있는데, 여기에서 각 어카운트는 0 또는 그 이상의 지분을 가질 수 있고, 어떤 결정을 내리기 위해서는 지분의 2/3 가 필요하다. 그것의 가장 단순화된 핵심 골격은 자산 관리 기능, 지분을 매매할 수 있는 오퍼를 낼 수 있는 능력, 그리고 다른 오퍼들을 수락할 수 있는(아마도 컨트랙트내에 있는 주문매칭 메커니즘을 통해) 능력들을 포함하게 될 것이다. "이사회" 개념을 일반화하는 유동식 민주주의(Liquid Democracy) 스타일의 위임제도 또한 있게 될 것이다. - -### 추가적인 어플리케이션들(Further Applications) - -1. **예금용 “전자지갑”**. 펀드를 안전하게 보관하고 싶은 A가 펀드를 잃어버리거나 누군가에게 그녀의 Private key를 해킹당할 것을 걱정한다고 가정해 보자. 그녀는 이더를 B라는 은행과의 컨트랙트에 다음과 같은 방식으로 집어 넣을 것이다. - -* A만이 하루에 그녀가 소유하는 펀드의 최대 1%를 출금할 수 있다. -* B또한 하루에 A가 소유하는 펀드의 최대 1%를 출금할 수 있지만, A는 그녀의 Private key를 통해 트랜스액션을 발송함으로써 B의 출금 권한을 없애버릴 수 있다. -* A와 B는 함께 어떤 금액도 출금할 수 있다. - -일반적으로 하루의 1%라는 상한선은 A에게 충분하며, 그 이상의 금액을 출금하고 싶을 시 A는 B에게 상한 조정 허가를 요청할 수 있다. Alice의 Private key가 해킹 당하였을 경우, B에게 펀드를 새로운 컨트랙트로 이체 시키라고 요청할수 있다. A가 본인의 Private key를 분실하는 경우, B는 오랜 시간에 걸쳐서라도 펀드의 금액을 출금할 수 있다. B가 악당인 경우에는 A는 B의 출금 권한을 정지시킬 수 있다. - -2. **작물보험**. 시세가 아닌 날씨 데이터피드를 이용해서 파생상품을 손쉽게 만들 수 있다. 아이오와주에 있는 농부가 강수량 데이터와 역비례하게 지불금이 산출되는 파생상품을 산다면, 가뭄이 있을 시 농부는 자동적으로 보상을 받을 수 있을 것이다. 이러한 어플리케이션은 자연재해 일반에 대한 보험상품으로 확대될 수 있을 것이다. - -3. **탈중앙화된 데이터피드**. “쉘링코인 ([SchellingCoin](http://blog.ethereum.org/2014/03/28/schellingcoin-a-minimal-trust-universal-data-feed/))”이라는 프로토콜을 사용하여, 변량 (Difference)을 다루는 금융계약(예, 로또)을 탈중앙화된 방식으로 운용할 수 있다. 쉘링코인은 다음과 같이 작동한다: 하나의 주어진 기준치(예, ETH/USD 시세)에 대해 N명의 참여자가 각각 자신들이 맞다고 생각하는 값을 시스템에 제공한다. 이러한 값들은 그 값의 크기에 따라 순위가 매겨지며, 이 때 25번째 퍼센타일과 75번째 퍼센타일 사이에 있는 값을 제시한 사람은 토큰 1개를 보상으로 받게 된다. 이렇게 되면 보상을 받기 위해서 모든 참가자들은 다른 사람들이 제시했을 똑같은 값을 제시하고자 할 것이고, 많은 다수의 참여자가 현실적으로 동의할 수 있는 유일한 값은 결국 명백한 기본값인 참값(truth)이 될 것이다. 이것은 ETH/USD 가격, 베를린의 온도, 심지어는 어려운 연산문제의 결과값까지도 포함하는, 어떤 수의 값들도 이론적으로 제공해줄 있는 탈중앙화된 프로토콜을 만들 수 있게 해준다. - -4. **스마트 멀티시그 공탁 계좌**. 비트코인은 멀티시그 트랜잭션을 만들 수 있게 해주는데, 이는, 가령, 5개의 키 중 3개를 갖고 서명해야 출금을 허용하는 방식의 트랜잭션을 지칭한다. 이더리움은 보다 높은 세밀도를 제공한다. 예를 들어, 5개 중 4개가 있으면 기금은 전체를 사용할 수 있고, 5개 중 3개가 있으면 하루에 기금의 10%을 사용할 수 있고, 2개가 있으면 하루에 0.5%를 사용할 수 있다. 추가적으로, 이더리움의 멀티시그는 동시에 집행해야 할 필요가 없다. 즉, 두 주체는 다른 시기에 블록체인에 본인의 전자 서명을 등록할 수 있고 최종의 전자서명이 이루어졌을 시 자동적으로 트랜잭션이 네트워크로 보내진다. - -5. **클라우드 컴퓨팅**. EVM 기술을 사용하여 입증 가능한 컴퓨팅 환경을 만들 수 있다. 입증 가능한 컴퓨팅 환경의 예시는 다음과 같다: 한 유저가 다른 유저에게 연산을 수행하게 한 후 랜덤한 시점에 연산을 수행한 주체에게 미리 설정된 연산 체크포인트가 올바른지에 대한 증명을 요구할 수 있다. 이 기술은 누구든지 자신의 데스크탑, 노트북, 또는 전문화된 서버를 갖고 참여할 수 있는 클라우드컴퓨팅 시장을 창조하게 될 것이며, 함께 연산의 정확성을 무작위 추출검사를 함으로써 시스템의 신뢰성이 더욱 강화될 것이다 (즉, 노드들이 이익을 내기 위해서는 유저들을 속일 수 없게 된다). 물론 그러한 시스템은 모든 작업들을 수행하는 데에 적합한 것은 아니다; 예를 들어, 높은 수준의 프로세스간 커뮤니케이션이 필요한 작업 같은 경우 여러 개의 클라우드 노드들로 수행하기에는 적합하지 않다. 하지만 그 외 작업들은 보다 수월하게 병렬진행이 가능하다; SETI@home, folding@home, 유전자 알고리즘 같은 경우는 분산화된 클라우드 컴퓨팅 플랫폼에서 쉽게 작업할 수 있는 프로젝트들이다. - -6. **P2P 도박**. Frank Stajano나 Richard Clayton의 [Cyberdice](http://www.cl.cam.ac.uk/~fms27/papers/2008-StajanoCla-cyberdice.pdf) 같은 P2P 도박 프로토콜들은 모두 이더리움의 블록체인 위에 구현될 수 있다. 가장 단순한 도박 프로토콜은 다음 블록의 해시값의 차이에 대한 컨트랙트이며, 0에 가까운 수수료와 그 누구도 사기를 칠 수 없는 보다 발전된 프로토콜이 그 위에 얹혀질 수 있다. - -7. **예측 시장**. 오라클(Oracle) 혹은 쉘링코인(Schelling Coin) 등을 갖고, Robin Hanson이 주창한 것과 같은 예측 시장도 쉽게 구현할 수 있다. 쉘링코인과 함께 예측시장은 분권화된 조직들에 대한 거버넌스 프로토콜로서 “퓨타키([Futarchy]((http://hanson.gmu.edu/futarchy.html), 역주: 정치인들이 국가복지에 관한 정책을 정의하면 예측시장이 정책 중 가장 긍정적인 효과가 많을 수 있는 정책을 결정하는 형식의 거버넌스)의 첫 번째 주류 어플리케이션이 될 수 있다. - -8. **블록체인상의 탈중앙화된 장터**. 신원조회 / 평판 시스템을 기반으로 원활하게 돌아가는 P2P 장터를 구축할 수 있다. - -## 그 밖의 이슈들 - -### 수정된 GHOST 도입(Modified GHOST Implementation) - -GHOST(Greedy Heaviest Observed Subtree)프로토콜은 Yonatan Sompolinsky and Aviv Zohar 에 의해 [2013년 12월](http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf)에 처음 소개된 혁신이다. GHOST의 문제의식은, 현재 빠른 확인시간(confirmation times)을 가지고 있는 블록체인들이 높은 스테일(stale) 비율로 인해 보안성 저하라는 문제를 겪고 있다는 것인데, 이는 블록들이 네트워크를 통해 전파되는데 일정한 시간이 걸리기 때문이라는 것이다. 만일 채굴자 A가 하나의 블록을 채굴했는데, 이 블록이 채굴자 B에게 전파되기전에 채굴자 B가 다른 또 하나의 블록을 채굴했다고 하면, 채굴자 B의 블록은 결국 낭비될 것이고, 네트워크 보안에 기여하지 못하게 될 것이다. - -게다가 중앙집중화(centralization) 이슈도 있다; 만일 채굴자 A가 30%의 해시파워를, 그리고 B가 10%의 해시파워를 가지고 있다면, A가 스테일 블록을 생산할 위험성은 매번 70%가 될 것이고(왜냐하면 다른 30%의 경우에는 A가 마지막 블록을 만들게 되었고, 따라서 즉각적으로 채굴데이터를 가지게 되기 때문이다), 반면 B는 매번 90%의 경우에 스테일 블록을 생산하게 될 위험성을 가지고 있다. 따라서 만일 블록 주기가 스테일 비율이 높은 것에 필요한 만큼 충분히 짧다면, A는 단순히 크기가 크다라는 사실 자체만으로 훨씬 더 높은 효율성을 가지게 된다. 이러한 두가지 효과가 결합되어서, 블록주기가 짧은 블록체인에서는, 높은 해시파워 점유율을 가진 단일한 풀이 채굴과정에 대한 사실상의 통제권을 가지게 될 가능성이 매우 높아진다. - -Sompolinsky와 Zohar가 설명했듯이, GHOST는 어느 체인이 “가장 긴(longest)”것인지 계산할 때 스테일 블록도 포함으로써 위에서 제기한 첫번째 이슈, 즉 네트워크 보안 손실이라는 문제를 해결한다. 다시 말해서 어느 블록이 가장 큰 전체 작업증명을 가지고 있는지 계산함에 있어서, 그 블록의 모블록(parent)과 그 조상(ancestors) 뿐만 아니라, 그 블록의 스테일 자손(stale descendants, 이더리움의 용어로는 “삼촌”)까지도 더한다는 것이다. 중앙화라는 두번째 문제를 해결하기 위해서 우리는 Sompolinsky와 Zohar가 설명한 프로토콜을 넘어서서, 스테일 블록들에 대해서도 블록보상을 제공한다. 스테일 블록도 기본 보상의 87.5%를 받게 되며, 그 스테일 블록을 포함하고 있는 사촌이 나머지 12.5%를 받는다. 하지만 수수료는 삼촌들에게는 주어지지 않는다. - -이더리움은 7단계 레벨만 포함하는 단순화된 GHOST 버전을 구현한다. 그것은 다음과 같이 구체적으로 정의된다; - -* 하나의 블록은 반드시 하나의 모블록을 지정해야 하며, 0 또는 그 이상의 삼촌을 지정해야 한다. -* 블록 B에 포함된 삼촌은 다음과 같은 속성들을 가지고 있어야 한다. - * B의 k번째 조상의 직접적인 자손이어야 한다. 여기서 2 <= k <= 7. - * B의 조상이어서는 안된다. - * 유효한 블록 헤더여야 하지만, 이전에 확인되었을 필요도, 또는 심지어 유효한 블록일 필요도 없다. - * 이전 블록들에 포함된 모든 삼촌들, 그리고 같은 블록에 포함된 모든 다른 삼촌들과는 달라야 한다(중복포함방지) -* 블록 B에 있는 각 삼촌 U에 대해, B의 채굴자는 코인베이스 보상에 더해 추가로 3.125%를 더 받고, U의 채굴자는 기본 코인베이스 보상의 93.75%를 받는다. - -단지 최대 7세대만 삼촌을 포함할 수 있는 제한된 GHOST 버전을 사용하는 이유는 두가지이다. 첫째, 무제한 GHOST는 하나의 블록에 대해 어떤 삼촌이 유효한지에 대한 계산을 매우 복잡하게 만든다.. 둘째, 만일 이더리움과 같은 방식의 보상을 하면서도 무제한 GHOST를 적용하게 되면 채굴자들이 공격자의 체인이 아니라 주체인(mainchain)에서 채굴를 할 동기를 잃게 될 것이다. - -### 수수료 - -블록체인에 올려지는 각 트랜잭션은 그것을 다운로드하고 검증하기 위한 비용을 네트워크에 부과하기 때문에, 남용을 방지하는 어떠한 규제 메커니즘, 일반적으로는 트랜잭션 수수료가 필요하게 된다. 비트코인에서 사용되는 기본적인 접근방법은 순수하게 자발적인 수수료를 징수하면서, 채굴자들이 게이트키퍼(gatekeeper)로서의 역할을 하고 유동적으로 최저액을 설정하도록 하는 것이다. 이런 접근방법은 비트코인 커뮤니티에서 매우 환영 받아왔는데, 그것이 “시장-기반”이기 때문에, 채굴자와 트랜잭션 송신자들간의 수요와 공급이 그 가격을 결정한다는 이유에서였다. - -하지만 이런식의 사고방식에는 문제가 있는데, 트랜잭션 처리는 시장에서 일어나는 것이 아니라는 점이다. 트랜잭션 처리를 채굴자가 송신자에 제공하는 하나의 서비스로 해석하는 것이 직관적으로 솔깃해 보이기는 하지만, 실제적으로는 채굴자가 포함하는 모든 트랜잭션들은 네트워크의 모든 노드들에 의해 처리되어야 하고, 따라서 트랜재션처리에 필요한 대부분의 비용은 제3자가 부담하는 것이지, 그 트랙재션을 포함할지 말지를 결정하는 채굴자들이 아니라는 것이다. 그러므로 공유지의 비극(tragedy-of-the-commons) 문제들이 매우 일어나기 쉽다는 것이다. - -하지만, 이러한 시장기반 메커니즘의 결함은 어떤 부정확한 단순화 전제들이 주워졌을 때, 마술처럼 그 결함자체를 상쇄하게 된다. 그 주장은 다음과 같다. -다음을 전제해 보자: - -1. 하나의 트랜잭션이 `k`개의 작업들(operations)을 초래하는데, 이 트랙잭션을 포함하는 채굴자에게 `kR`만큼의 보상을 제공하게 된다. 여기서 `R`은 송신자에 의해서 설정되고, `k` 와 `R`은 (대략적으로) 채굴자에게 사전에 노출된다. -2. 하나의 작업은 어떤 노드에 대해서든 C 만큼의 처리비용을 가진다(즉, 모든 노드들은 똑같은 효율성을 가지고 있다). -3. `N`개의 채굴노드들이 있고, 각각은 정확히 똑같은 처리파워(즉, 전체의 `1/N`)를 가지고 있다. -4. 채굴을 하지 않는 완전노드(full nodes)는 없다. - -채굴자는 어떠한 트랜잭션이 그 비용보다 기대보상이 클 경우 처리하려고 할 것이다. 따라서, 기대 보상은 kR/N인데, 왜냐하면 채굴자는 다음번 블록을 처리할 1/N 확률을 가지고 있으며, 이 채굴자에게 처리비용은 단순히 kC이다. 그러므로 채굴자들은 kR/N > kC 이거나, R > NC일때 트랜잭션들을 포함하려 할 것이다. 여기서 R은 송신자에 의해 제공된 단위작업(pre-operation)당 수수료이고, 따라서 이것은 송신자가 그 트랜잭션에서 보게 될 혜택에 대한 하한값이 되고, NC는 하나의 작업을 처리하기 위해 전체 네트워크에 부과된 비용임을 주목하자. 따라서 채굴자들은 비용보다 전체 공리적인 혜택이 큰 트랜잭션들만 포함하려 하는 인센티브를 갖게 된다. - -하지만 현실에서는 이러한 가정들이 맞지 않는 몇가지 중요한 차이들이 있다. - -1. 채굴자는 다른 검증 노드들보다 트랜잭션을 처리하는데 더 많은 비용을 지불하게 되는데, 왜냐하면, 추가적인 검증시간은 블록전파를 지연시키고, 따라서 블록이 스테일되는 확률을 증가시키기 때문이다. -2. 비채굴 완전노드(full note)들이 존재한다. -3. 채굴 파워의 분포는 실제로 심각하게 불평등하게 될 수 있다. -4. 네트워크에 피해를 주는 이해관계를 가진 투기자들, 정치적 적, 그리고 일탈자들이 존재하고, 그들은 다른 검증노드가 지불하는 비용보다 훨씬 적은 비용이 들게 될 그런 컨트랙트들을 교묘하게 만들 수 있다. - - -(1)은 채굴자가 더 적은 수의 트랜잭션들을 포함하게 되는 경향을 제공하게 되고, (2)는 NC를 증가시키게 되며, 따라서 이 두가지의 효과들은 부분적으로는 서로를 상쇄한다. (3)과 (4)가 주요한 문제인데, 이것들을 해결하기 위해, 플로팅 상한값(floating cap)을 도입한다. 어떤 블록이던지 BLK_LIMIT_FACTOR 곱하기 장기 지수 이동평균(the long-term exponential moving average)보다 더 많은 오퍼레이션들을 가질 수 없다는 것이다. 정확히는: - - blk.oplimit = floor((blk.parent.oplimit * (EMAFACTOR - 1) + floor(parent.opcount * BLK_LIMIT_FACTOR)) / EMA_FACTOR) - -BLK_LIMIT_FACTOR 와 EMA_FACTOR은 상수이며 각각 잠정적으로 65536와 1.5로 정해질 것이지만, 추후 분석 후에 바뀔 가능성이 많다. - -비트코인에 있어서 큰 블록크기를 막는 또 다른 요인도 있다. 큰 블록이 전파되는데에 더 오래 걸리기 때문에, 스테일 될 가능성이 높다는 점이다. 이더리움에서도 높은 가스(GAS)사용 블록은 전파되는데 더 오래걸리는데, 그것은 크기가 물리적으로 크다는 점과, 트랜잭션 상태변환들(state transitions)을 검증 처리하는데 더 오래 걸린다는 점 때문에 그러하다. 이러한 지연 불이익(delay disincentive)은 비트코인의 경우에는 중요한 고려사항이지만, 이더리움의 경우에는 GHOST프로토콜 덕분에 중요도가 낮아진다. 따라서 조정된 블록리미트(block limit)로 인해, 보다 안정적인 기본기준(baseline)을 얻을 수 있게 된다. - -### 연산과 튜링완전성(Computation And Turing-Completeness) - -중요한 점은 이더리움 가상 머신(EVM)이 튜링-완전하다는 것이다. 즉 EVM은 무한 순환을 포함한 상상가능한 모든 계산 수행을 코딩할 수 있다. EVM코드는 순환 계산을 다음 두 가지 방법으로 수행한다. -첫번째는 JUMP 명령어로 코드의 이전 장소로 되돌아가고, JUMPI 명령어로 while x < 27: x = x * 2 같은 문장처럼 조건에 따라 건너뛰게 하는 것이다. -두번째는 한 계약이 재귀 반복을 통해 순환을 일으킬 가능성이 있는 다른 계약을 호출하는 것이다. -이것은 자연스럽게 어떤 문제를 야기한다: 악의적인 사용자가 계산을 무한 순환에 빠뜨리는 방법으로 채굴자와 풀 노드를 마비시켜버릴 수 있을까? -컴퓨터 학계에서 정지문제(halting problem)라고 알려진 유명한 문제를 통해 이런 이슈를 피할 수 없음을 알 수 있다. 일반적으로 어떤 주어진 문제가 궁극적으로 멈추는지 아닌지를 미리 판별할 방법은 없다. -상태변환 과정에서 설명했듯이, 한 거래에 최대로 계산할 수 있는 단계 수를 설정함으로써 우리는 해답을 얻을 수 있다. 만약 계산 단계가 그 최대수보다 더 많으면 계산은 원점으로 돌아가지만 수수료는 그대로 지불된다 -메시지들도 같은 방법으로 작동한다. 우리가 제시한 해답의 의미를 더 잘 이해하기 위해, 아래와 같은 몇가지 보기를 생각해보자. - -* 한 악의적 공격자가 무한 순환을 실행하는 계약을 만들어 채굴자로 하여금 무한 순환을 실행하도록 거래를 보냈다고 하자. 채굴자는 거래를 진행하고 무한 순환을 실행해 가스를 다 소모해서 실행 도중에 멈춘다고 하더라도, 거래는 여전히 유효하고 채굴자는 여전히 공격자에게 이미 실행된 각 계산 단계마다의 수수료를 요구할 수 있다. -* 한 악의적 공격자가 채굴자에게 계산을 오랫동안 계속하게 할 목적으로 아주 긴 무한 순환 프로그램을 짰다고 하자. 계산이 끝났을 때 아주 조금의 블록만이 생성되어 채굴자가 수수료를 요구하기 위해 그 거래를 포함하는게 불가능하게 만드는 게 악의적 공격자의 목적이다. 하지만, 그 공격자는 실제 실행되는 계산 단계의 상한선을 규정하는 STARTGAS 명령어에 대한 값을 제출해야만 하고, 따라서 채굴자는 해당 계산이 과도하게 많은 단계의 수를 필요로 한다는 것을 계산 전에 미리 알게 된다. -* 예를 들어send(A,contract.storage[A]); contract.storage[A] = 0, 같은 명령이 들어간 계약이 있다고 하자. 한 악의적 공격자가 이 계약을 본 후 첫번째 계산 단계만 실행시키고 두번째 단계는 실행할 수 없을 만큼의(예를 들어 예금 인출만 한 다음 장부에 기록되는 스텝은 실행되지 않게) 가스만 넣고 거래를 진행시켰다고 하자. 계약 작성자는 이런 공격에 대해 방어를 걱정할 필요가 없다. 왜냐하면 계산 실행이 도중에 멈추면, 해당 변화도 원상복구되기 때문이다. -* 어떤 금융 계약이 9개의 금융상품 자료값의 평균을 취해 위험을 최소화하도록 작동하고 있다고 하자. 그 중 DAOs 섹션에서 설명된 것 같은 가변주소요청 메커니즘을 통해 변경가능하도록 디자인 된 하나의 자료값을 악의적 공격자가 취한다고 하자. 그렇게 함으로써 이 금융 계약으로부터 펀드를 찾으려는 모든 시도에 대해 가스가 다 소모되도록 시도하게 된다. 하지만 금융 계약은 이 문제를 막기 위해 메시지 위에 가스 한도를 설정해 두는 것으로 공격을 방어할 수 있다.. - -튜링-완전에 대한 대칭적인 개념은 튜링-비완전이다. 즉 JUMP 명령어나 JUMPI 명령어가 존재하지 않으며, 그 어떤 주어진 시간에도 오직 각각의 계약의 복사본 하나만이 허용된다. 이런 시스템 아래에서는 위에 서술된 수수료 시스템이라든지 우리가 제시한 해답의 효율성을 둘러싼 불확실성에 관한 논쟁은 불필요할 것이다. 한 계약을 실행하는데 드는 비용은 프로그램의 크기에 따라 상한선이 정해질 것이기 때문이다. -나아가, 튜링-비완전성은 그리 큰 제한도 아니다. 우리가 현재까지 상상했던 계약 가운데, 순환 명령을 필요로 했던 것은 단 하나 뿐이었다. 그리고 그 순환 명령조차도 프로그램 코딩에서 한 문장을 26번 반복함으로써 없앨수 있었다. -튜링-완전이 함의하고 있는 심각성과 그 제한적인 이점을 생각해볼 때, 왜 튜링-불완전 언어를 쓰면 안되는 걸까? -하지만 현실적으로, 튜링-불완전성은 순환 문제와 악성 공격에 대한 깔끔한 해답이 아니다. -왜 그런지를 알기 위해 아래와 같은 예제 계약을 보자. - - C0: call(C1); call(C1); - C1: call(C2); call(C2); - C2: call(C3); call(C3); - ... - C49: call(C50); call(C50); - C50: (프로그램의 한 단계를 실행한 후 그 변화를 저장소에 기록한다.) - -이제 A 에게 거래를 보내자. 51번의 거래에서 우리는 2 의 50승의 계산 단계를 계속하는 계약을 보낸다..채굴자들은 각 계약에 따른 계산 단계의 최대 수와 다른 계약을 재귀적으로 호출하는 계약에 대한 계산 단계 수를 모두 확보함으로써, 이런 논리 폭탄을 사전에 감지하려고 시도할 수 있을지도 모른다. 하지만 이런 시도는 채굴자들이 다른 계약을 호출하는 계약은 다루지 못하게 만든다. (왜냐하면 위의 모든 26개 계약의 작성과 실행은 한 줄의 계약으로 쉽게 합쳐질 수 있기 때문이다.) -다른 문제적 지점은 메시지의 주소 필드는 변수라는 점이다. 그래서 일반적으로, 주어진 계약이 사전에 미리 호출하는 다른 계약이 뭔지를 판별하는 것조차 불가능할지도 모른다. -그래서,결국 우리는 놀라운 결론에 도달한다. 튜링-완전은 놀랍도록 다루기 쉬우며, 만약 튜링완전성이 없으면 정확히 같은 계약으로 대체할 수 없는 한, 마찬가지로 다루기가 놀랍도록 어렵다는 점이다. 그렇다면, 그냥 그 프로토콜을 튜링-완전하게 놔두는게 좋을 것이다. - -### 통화 그리고 발행(Currency and Issuance) - -이더리움(Ethereum) 네트워크는 그 안에서 자체적으로 통용되는, ‘이더(Ether)’라는 화폐를 가지고 있다. 이더는 여러가지 가상자산들간의 효율적인 교환을 가능케하는 매개물의 역할을 하며, 또한 트랜잭션 수수료(transaction fee)를 지불하기 위한 방법을 제공한다. 사용자의 편의와 향후 있을 지 모르는 논쟁을 예방하는 차원에서, 이더(Ether)의 각 단위에 대한 명칭은 다음과 같이 미리 정해졌다. (비트코인 명칭과 관련하여 벌어지는 논쟁 참조) - -* 1: wei -* 1012: szabo -* 1015: finney -* 1018: ether - -위 명칭들은, 미화 명칭인 “달러”와 “센트” 또는 비트코인의 “BTC”와 “사토시” 등의 확장개념으로 생각하면 이해하는데 도움이 될 것이다. 가까운 미래에, “이더(ether)”는 일반 거래(transaction)를 위해, “피니(finney)”는 소액결제를 위해, 그리고 “싸보(szabo)”와 “웨이(wei)”가 수수료나 프로토콜 도입 등과 관련된 기술적논의를 위해 사용될 것으로 기대된다. 나머지 명칭들은, 지금 당장은 클라이언트에 포함시키지 않는다. - -화페발행 모델: - -* BTC 당 1000-2000개의 가격으로 이더를 판매한다. Matercoin이나 NXT와 같은 다른 암호화화폐 플랫폼에서 성공적으로 사용했던 방법으로, 이더리움 조직을 금전적으로 지원하고 개발에 필요한 비용을 댄다. 이 시기에 이더를 구매하는 구매자들은 큰 폭의 할인을 통해 저렴하게 이더를 얻게 된다. 이렇게 모인 자금은 전액, 개발자를 위한 월급과 보상, 그리고 여러가지의 이더리움 관련 영리와 비영리프로젝트를 위한 투자금으로써 사용된다. -* 판매 된 총 이더(60,102,216 ETH)의 0.099배 만큼(5,950,110)의 이더가 신규발행 되어, 이더리움 런칭 전의 초기기여자들과 ‘이더로 이미 발생 된 비용에 대한 미지급금’을 처리하기 위해 이더리움조직(Ethereum organization)에게 분배된다. -* 또 다른 0.099배 만큼의 이더는 장기보유금으로 신규 발행하여 적립해둔다. -* 채굴시점 이후부터 영구히 매년, 총 판매수량(60,102,216 ETH)의 0.26배 만큼(15,626,576)씩을 채굴자에게 신규 발행해준다. - -| 분류 | 런칭시 | 1년후 | 5년후 | -| ------------- | ------------- |-------------| ----------- | -| 초기판매 이더총량에 대한 배수 | 1.198X | 1.458X | 2.498X | -| 구매자 | 83.5% | 68.6% | 40.0% | -| 런칭전 미지급 적립금 | 8.26% | 6.79% | 3.96% | -| 런칭후 적립급 | 8.26% | 6.79% | 3.96% | -| 채굴자 채굴량 | 0% | 17.8% | 52.0% | - -** 이더 장기 공급 성장률(%)** - -![SPV in bitcoin](https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/inflation.png) - -_매년 신규발행량이 일정함에도 불구하고, 비트코인이 그러한 것처럼, 발행된 총 이더에 대한 신규 이더의 발행률은 그 비중이 0을 향하여 계속 줄어들게 된다._ - -위 모델에서 결정되어야할 두 가지 선택이 있다. (1) 하나는, ‘재단보유금(endowment pool)’의 존재유무와 그 규모이며, (2) 둘째는 총 발행코인량이 정해져 있는 비트코인과는 달리, 신규코인을 끊임없이 발행해야 하는지의 여부이다. - -‘재단보유금(endowment pool)’의 정당성에 대해서는 다음과 같이 설명할 수 있다. 만일 이러한 보유금이 없는 상황이라면, 같은 인플레이션율을 유지하기 위해서는 연간 발행량이 26%가 아닌, 21.7%로 줄어들어야 한다. 그렇게 되면 이더의 총량은 16.5% 줄어들게 되며, 각 이더의 가치는 19.8%증가하게 된다. 이 경우 균형을 위해서는 19.8%의 이더가 더 프리세일에서 판매되어야 한다. 그렇게 되면 각 경우의 이더 가치는 서로 정확히 동일해진다. 그렇게 되면 이더리움 재단이 1.198배의 BTC를 가지게 되는데, 이를 처음 BTC 액수(1배수)와 추가된 0.198배수의 BTC로 나누어보면 결국 상황이 동일해진다는 점을 알 수 있다. 그러나 한 가지 차이점은 이 경우 조직이 가진것은 이더가 아닌 BTC이므로, 이더의 가치를 높이기 위한 인센티브를 얻지 못한다는 점이다. - -정해진 양의 이더를 영구적으로 신규발행하는 모델(permanent linear supply growth model)은 비트코인이 겪고있는 ‘부의 집중현상’을 완화시킬 수 있다. 또한 현재 또는 미래의 참여자들이 계속해서 이더를 시장이 아닌 채굴을 통해 얻을 수 있는 기회를 제공한다. 동시에, “공급성장률(Supply Growth Rate)”은 계속해서 0을 향해 줄어들게 된다. 우리측의 이론으로는 다음과 같은 현상을 예상해 볼 수 있다. 시간이 흐름에 따라 사용자들의 부주의, 죽음 등으로 인해 현실적으로 일부의 이더들이 계속해서 시장에서 사라지게 된다. 이렇게 사라지는 이더로 인해 점점 줄어드는 ‘시장유통가능 이더총량(the total currency supply in circulation)’은 매년 신규발행되는 이더에 의해 균형을 이루게 된다. (ex. 만일 총 이더량이 26배수(1,562,657,616 ETH)에 달했고, 매년 이 중 1%(0.26배수)에 해당하는 이더가 소실된다면, 이는 매년 새로이 발행되는 0.26배수의 이더와 균형을 이루게 된다) - -장래, 공급성장률을 약 ‘0에서 0.05배수 이내’가 되도록 수정을 하면서, POS로 채굴모델을 변경할 계획을 가지고 있다. 만일, ‘이더리움 재단(Ethereum organization)’이 보유금을 모두 잃거나, 또는 여타의 이유로 사라지게 되면, “사회적계약(social contract)”을 열어둘 것이다. 이를 통해, 이더 발행량을 최대 ‘60102216 * (1.198 + 0.26 * n)‘를 넘지 않도록만(n은 첫 블록 생성 이후의 총 년수) 지킨다면, 누구든지 이더리움의 ‘후속버전(a future candidate version:RC버전)’을 만들 수 있을 것이다. 이 후속버전의 창시자는 개발/관리에 필요한 비용을 충당하기 위해서, 공개판매(crowd-sell)를 하거나, ‘총 가능 이더발행량’과 ‘POS를 통한 공급량’ 간의 차액 중 일부나 전부를 이용할 수 있을 것이다. 만일 어떠한 창시자가 이러한 “사회적계약(social contract)”에 반하는 내용을 업데이트하게 된다면, 결국 대의에 의해 합당한(compliant) 버전에서 별개로 포크되어(forked)나와 탈락하게 될 것이다. - -### 채굴 중앙집중화(Mining Centralization) - -비트코인 채굴 방식은, 목표 값(현재 기준 약 2192)보다 낮은 값이 나올 때까지, 블록헤더에 대한 sha256 해싱 작업을 무한정 반복하는 것이다. 하지만 해당 방식에는 두 가지 약점이 존재한다. - -첫번째는 현재 채굴참여에 대한 장벽이 매우 높아졌다는 것이다. 현재 채굴생태계는 ASIC(특수목적을 위해 전용으로 설계된 반도체로, 범용반도체에 비해 성능이 뛰어남)에 의해 완전히 잠식되었다. 이러한 ASIC채굴기는 일반 GPU채굴기 등에 비해 수 천배 이상의 효율을 가지는데, 따라서 ASIC이 아닌 일반컴퓨터를 통한 일반사용자들의 채굴행위는 경쟁력에서 밀려 효용을 잃게 되었다. 과거의 채굴행위가 분권화되고 이타적인 참여자 중심의 ‘생태계’였다면, 현재는 수십억원의 투자가 되어야만 참여가 가능한 재력가들의 ‘사업’으로 변질되고 말았다. - -두번째는 채굴방식이다. 이전처럼 여러 지역에서 여러 참여자가 블록생성에 참여하는 것이 아니라, 중앙집중화된 채굴풀(Mining pool)이 제공하는 블록헤더(block header)에 의존하여 채굴에 참여한다는 점이다. 이로 인한 부작용이 상당한데, 현재 기준으로는, 3개 채굴풀들이 개인들의 컴퓨팅파워를 인계 받아서 무려 50%에 육박하는 해시를 간접적으로 통제하고 있다. 물론 해당 풀의 점유율이 50%를 넘어가기 전에 개인들이 다른 소규모 풀들로 이동을 할 수 있기 때문에, 풀들이 마음대로 자원을 남용할 수는 없겠지만, 이는 여전히 큰 문제이다. - -이더리움의 채굴 방식은 조금 다르다. 각 채굴자가 상태정보(the state)에서 무작위의 정보를 가져와서, 무작위로 선택 된 최근 몇개의 블록내역을 해싱 작업하고 결과값을 내놓는 것이다. 이렇게 하게 되면 두가지 이점이 있다. - -첫번째는 이더리움 계약이 모든 종류의 컴퓨터 계산방식을 포괄할 수 있다는 점이다. 따라서 자연히 ASIC도 모든 계산방식에 적합하게 설계되어야 하는데, 이렇게 되면 결국 ASIC이라기 보다는 일종의 고성능 CPU가 되는 셈이다. 즉 현실적으로 ASIC(주문형 전용반도체) 자체가 무용지물이 된다. - -두번째로, 채굴자들은 작업 시 전체 블록체인을 다운 받아 모든 이체내역을 검증해야 한다는 점이다. 이렇게 되면 중앙집중화 된 대형 풀이 필요없게 된다. 물론 대형풀 자체는 신규블록생성 보상을 균일하게 참여자들에게 배분해 주는 효과가 있긴 하지만, 그러한 효과는 P2P형식의 풀(pool)을 통해서도 충분히 구현이 가능하다. 굳이 중앙집중형 풀(centralized pool) 방식을 사용할 필요가 없다. - -물론 위의 채굴 모델이 아직 검증된 것은 아니다. 또한 ASIC장비에 대한 저항성을 높이는 작업도, 이론처럼 현실에서 적용이 될 수 있을지에 대하여는 의문의 여지가 있다. 하지만 한 가지 확실한 것은, 여러종류의 수많은 계약이 적용이 되면, 이를 모두 포괄하는 ASIC을 예전처럼 만들어 내기는 어렵다는 점이다. 또한 어떠한 종류의 작업에 특화 된 ASIC이 존재한다면, 이에 반하는 작업을 요하는 계약이 생성되는 것을 원치 않을 것이다. 그러면 해당 ASIC채굴자의 경쟁자는 그에 적대적인, 즉 비효율적인 작업을 요하는 계약들을 생성해 냄으로써 공격을 가할 것이다. 즉, 각 부분에 특화된 ASIC을 소유한 채굴자들은 서로에게 불리한 작업을 하게하는 계약들을 만들어 냄으로써 서로를 공격할 것이다. 물론 이러한 방법은 ‘기술적’인 접근이라기보다는 ‘경제학적 인간행동론’에 근거한 접근에 가깝다. - -### 확장성(Scalability) - -이더리움에 대한 한 가지 공통된 의문점은 확장성 부분이다. 비트코인과 마찬가지로 이더리움도 모든 이체작업이 네크워크 상의 전체 노드에 의해서 일일이 검증 및 작업이 되어야 한다는 약점이 있다. 비트코인의 경우, 현재 전체 블록체인의 크기가 약 15GB에 이르며, 그 크기는 매 시간 1MB씩 꾸준히 늘어나고 있다. VISA의 경우 초당 2,000여 건의 이체작업을 처리하는데, 이는 매 3초당 1MB씩의 확장(시간 당 1GB, 매 년 8TB)을 의미한다. 이더리움도 비슷한 문제를 겪을 것이고, 단순히 화폐로서의 역할 만하는 비트코인에 비한다면, 온갖 종류의 탈중앙화된 어플리케이션들(Dapps: Decentralized applications)을 포괄하는 이더리움은 이 부분에서 훨씬 더 많은 문제를 겪을 수도 있을 것이다. 하지만 한 가지 다른 점은, 이더리움은 ‘전체 블록체인 히스토리’가 아닌, 단지 ‘상태 정보(the state)’만 가지고 있으면 된다는 점이다. - -만일 개개의 모든 노드가 전체 블록체인을 보관해야 한다면, 아래와 같은 문제가 생길 수 있다. 블록체인의 크기가 점점 커져 100TB에 육박하게 되었다고 생각해보자. 이 정도 수준으로 보관해야하는 블록체인의 크기가 커지면, 오직 소수의 사업가나 기업 형태의 참여자만이 이를 감당할 수 있게 된다. 다수의 일반 사용자들은 ‘라이트 SPV(Simple Payment Verification)’ 노드만들 사용하게 될 것이다. 이렇게 되면, 전체 블록체인의 내역을 가진 소수의 참여자들이 결탁하여, 장부내역을 수정하거나 블록보상량을 바꿔치기 하는 등의 조작행위가 일어날 수 있을 것이다. 단순한 ‘라이트 노드(light node)’로서는 이러한 조작을 감지할 방법이 없다. 물론 ‘전체 블록체인를 소유한 노드(full node)’ 중에서도 선의의 참가자가 있을지 모른다. 그러나 다수의 ‘완전노드(full node)’가 작심하여 블록체인 조작을 시도한다면, 이를 발견하는 시점에서는 이미 늦었다고 봐야 할 것이다. 실제로 비트코인이 현재 이와 비슷한 문제에 처할 위험이 있다고 경고받고 있으며, 해당 문제를 완화시키는 방법에 대하여는 [Peter Todd에 의해 논의된 바](http://sourceforge.net/p/bitcoin/mailman/message/31709140/) 있다. - -위의 문제를 해결키 위해, 가까운 시일 안에 두 가지의 전략을 추가로 도입할 예정이다. 첫번째로 이더리움도 기본적으로 블록체인 기술을 바탕으로 한 채굴 알고리즘을 사용하고 있기 때문에, 모든 채굴자들은 ‘완전노드(full node)’가 되도록 의무화 될 것이며, 이는 필요한 최소한의 완전노드 숫자를 확보할 수 있도록 해줄 것이다 . 두번째로, 이체내역 검증 작업 이후 블록체인에 ‘중간상태 트리루트(an intermediate state tree root)’를 도입하는 것이다. 이렇게 되면, 아무리 블록생성 작업이 소수의 노드에 집중되더라도, 단 하나의 선의의 노드(honest node)만 존재한다면 검증 프로토콜(verification protocol)을 통해 이 문제를 해결할 수 있다. - -만일 어떠한 채굴노드가 전파한 블록이 검증오류(invalid)처리가 되었다면, 해당 블록의 ‘구성(format)’이 맞지 않거나 ‘상태내역 S [ n ]’이 틀린 경우일 것이다. ‘S [ 0 ]’ 상태가 옳은 것으로 간주되기 때문에, ‘S[ i-1 ]’이 맞다면, ‘S[ i ]’에 오류가 있는 것이다. 검증작업에 참여하는 노드는, ‘APPLY(S[i-1],TX[i]) -> S[i]’ 작업(processing)을 하는 ‘페트리샤 트리 노드의 부분집합(the subset of Patricia tree)’을 통해 ‘검증오류증명(proof of invalidity)’과 ‘인덱스 i’를 제공한다. 노드들은, 위의 노드들을 이용해 해당 작업을 수행하며, 생성한 ‘S[ i ]’가 제공받은 ‘S[ i ]’와 일치하지 않음을 발견하게 된다. - -또한 ‘불완전한 블록(incomplete block)’을 전파하려는 악의의 채굴노드들과 관련된 더욱 정교한 공격이 이루어질 수 있다. 블록을 검증하는데에 필요한 정보가 온전히 존재하지 않을 수도 있다. 이 경우, ‘질의-응답프로토콜(challenge-response protocol)’ 기법이 사용될 수 있다. 검증노드가 ‘목표 블록의 인덱스 형태(target transaction indices)’로 ‘질문(challenge)’을 생성하고, 노드를 수신하는 라이트노드(light node)는 해당 블록(challenge)을 일단 검증오류블록으로 취급한다. 이후, 다른 노드(채굴노드이든 검증노드이든)가 ‘페트리샤 트리 노드의 부분집합(the subset of Patricia tree)’을 검증증명(proof of validity)으로써 제공한다면, 그때서 위의 블록은 검증된(유효한) 것으로 취급된다. - -## 결론 - -이더리움 프로토콜은 본래 매우 범용적인 프로그래밍 언어를 통해 ‘블록체인상 에스크로나 인출한도설정, 금전계약, 도박 시장 등의 고급 기능’을 제공하는, 가상화폐의 업그레이드 버전으로 구상되었다. 이더리움 프로토콜은 이러한 어플리케이션들을 직접적으로 제공하는 것이 아니라, 튜링완전언어(Turing-complete programming language)를 통해 이론적으로 거의 모든 형태의 이체방식이나 어플리케이션을 만들어낼 수 있도록 지원한다. 더욱 흥미로운 점은, 이더리움은 단순한 ‘화폐’의 차원을 훨씬 뛰어넘는다는 점이다. 분산저장공간(DFS:decentralized file storage)이나, 분산컴퓨팅, 분산예측시장(decentralized prediction market) 프로토콜 등은 사실 수많은 응용개념들 중 일부에 불과하다. 이러한 새로운 개념들은 컴퓨팅 산업의 효율성을 폭발적으로 높일 수 있는 잠재력이 있으며, P2P프로토콜에 처음으로 ‘경제적인 차원(economic layer)’을 입힘으로써 엄청난 혁신을 가져올 수 있을 것이다. 마지막으로, 컴퓨팅이나 금융과 관련이 없는 분야들에서도 다양한 어플리케이션들이 나올 것이다. - -이더리움 프로토콜이 제공하는 ‘임의상태변환(arbitrary state transition function)’이라는 개념은 고유의 잠재력을 지닌 플랫폼을 탄생시킨다. 기존의 자료저장공간이나 도박, 금융 등의 하나의 목적에 특화된 폐쇠형 구조(close-ended)와는 달리, 이더리움은 자유롭게 조정이 가능한 구조(open-ended)이다. 우리는 이것이 몇 년 이내에, 금융부문이든 비금융부문이든 엄청나게 많은 종류의 서비스를 설계할 수 있도록 돕는 것에 특화된 기반이 될 것이라고 믿는다. - -## 주석과 추가자료 - -#### 주석 - -1. 관찰력이 좋은 독자라면, 비트코인 주소는 ‘공개키(public key)’가 아니라, ‘타원곡선공개키의 해시(the hash of the elliptic curve public key)’로 이루어져 있다는 것은 눈치챘을 것이다. 물론, 암호학적 관점에서 보자면 ‘공개키 해시(public key hash)’로 부르든 단순히 ‘공개키(public key)’로 부르든 차이는 없다. 왜냐하면, ‘비트코인 암호기법’ 자체가 ‘일종의 맞춤형 전자서명알고리즘’이고, 이 알고리즘에서는 공개키가 ‘타원곡선공개키의 해시(the hash of the Elliptic Curve public key)’를 포함하고 있고, 여기서의 ‘서명(signature)’은 ‘타원곡선서명(ECC signature)’과 연결된 ‘타원곡선공개키(ECC public key)’로 구성되어 있기 때문이다. 또한 ‘검증알고리즘’은 서명(signature) 안의 ‘타원곡선공개키(ECC public key)’를, 공개키로써 제공 된 ‘타원곡선공개키해시(the hash of the elliptic curve public key)’와 대조확인하고, 또한 ‘서명’을 ‘타원곡선공개키(ECC public key)’와 대조하여 검증하는 것이기 때문이다. - -2. 기술적으로는, 이전 11개 블록의 중간값(median)이다. - -3. 내부적으로는 2와 “CHARLIE” 모두 숫자이다. 다만 “CHARLIE”는 ‘빅 엔디언(big-endian)’ 기반의 256비트로 표시한 것이다. 숫자는 0부터 2256-1까지 사용한다. - -#### 추가자료 - -1. Intrinsic value: http://bitcoinmagazine.com/8640/an-exploration-of-intrinsic-value-what-it-is-why-bitcoin-doesnt-have-it-and-why-bitcoin-does-have-it/ -2. Smart property: https://en.bitcoin.it/wiki/Smart_Property -3. Smart contracts: https://en.bitcoin.it/wiki/Contracts -4. B-money: http://www.weidai.com/bmoney.txt -5. Reusable proofs of work: http://www.finney.org/~hal/rpow/ -6. Secure property titles with owner authority: http://szabo.best.vwh.net/securetitle.html -7. Bitcoin whitepaper: http://bitcoin.org/bitcoin.pdf -8. Namecoin: https://namecoin.org/ -9. Zooko's triangle: http://en.wikipedia.org/wiki/Zooko's_triangle -10. Colored coins whitepaper: https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit -11. Mastercoin whitepaper: https://github.com/mastercoin-MSC/spec -12. Decentralized autonomous corporations, Bitcoin Magazine: http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/ -13. Simplified payment verification: https://en.bitcoin.it/wiki/Scalability#Simplifiedpaymentverification -14. Merkle trees: http://en.wikipedia.org/wiki/Merkle_tree -15. Patricia trees: http://en.wikipedia.org/wiki/Patricia_tree -16. GHOST: http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf -17. StorJ and Autonomous Agents, Jeff Garzik: http://garzikrants.blogspot.ca/2013/01/storj-and-bitcoin-autonomous-agents.html -18. Mike Hearn on Smart Property at Turing Festival: http://www.youtube.com/watch?v=Pu4PAMFPo5Y -19. Ethereum RLP: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP -20. Ethereum Merkle Patricia trees: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree -21. Peter Todd on Merkle sum trees: http://sourceforge.net/p/bitcoin/mailman/message/31709140/ diff --git a/pages/white-paper/[persian]-white-paper.md b/pages/white-paper/[persian]-white-paper.md deleted file mode 100644 index 4588d4cae..000000000 --- a/pages/white-paper/[persian]-white-paper.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: White Paper -category: ---- - -# پلتفرم نسل بعدی قراردادهای هوشمند و نرم افزارهای غیر متمرکز -در چند ماه گذشته خیل عظیمی از علاقه مندی جهت استفاده از بلاک چین های نظیر بیت کوین وجود داشته است. - مکانیزمی که امکان توافقی جهانی را بر روی پایگاه داده ای از اطلاعات تملک افراد فراهم می آورد. - به عنوان چیزی بیش از صرفا یک پول! -این کاربردها عموما شامل دسترسی دیجیتالی مبتنی بر بلاک چین به ارزهای طراحی شده در این سیستم و ابزارهای مالی می شوند. (سکه های رنگی) «دارایی های هوشمند» ابزارهایی هستند مانند یک خودرو که یک سکه رنگی را بر روی یک بلاک چین دنبال میکنند تا مالک قانونی خود را معین کنند که به خوبی سایر نرم افزارهای مدرن نظیر صرافی غیر متمرکز، مشتقات مالی، بازی های بخت آزمایی نظیر به نظیر و هویت مبتنی بر بلاک چین و سیستم های اعتباری کار میکنند. -شاید بلند پروازانه ترین مورد در بین تمام برنامه های ذکر شده، مفهوم عوامل خودمختار یا سازمان خودمختار و غیر متمرکز (DAOs ) باشد- نهادهایی مستقل که در بلاک چین عمل میکنند و هیچ گونه کنترل مرکزی ندارند، اجتناب از هرگونه وابستگی به قراردادهای قانونی و آیین نامه های سازمانی با هدف داشتن منابع و بودجه مستقل توسط یک قرارداد هوشمند خودمختار که در بلاک چینی رمزنگاری شده اداره می شود. -با این حال، امروزه پیاده سازی بسیاری از این برنامه های کاربردی دشوار است، چرا که سیستم های برنامه نویسی بیت کوین و حتی نسل بعدی پروتکل های ارزهای رمزنگاری شده مانند بیت کوین مبتنی بر پروتکل سکه های رنگی و به اصطلاح "metacoins"، به مراتب محدودتر از آن هستند که اجازه انجام محاسبات دلخواه و پیچیده مورد نیاز DAOها را فراهم آورند. -کاری که این پروژه در صدد انجام آن است گرفتن نوآوری پروتکلهای اینچنین و ایجاد فضای کار رمزنگاری شده ای کاملا تکامل یافته و ….. (ولی با قواعد آزاد) است که به شرکت کنندگان امکان نگارش قراردادهای دلخواه پیچیده را می دهد، عوامل و روابطی که کاملا توسط بلاک چین نمایندگی خواهند شد. -کاربران بسیار بیشتر از آنکه محدود به یک سری انواع تراکنش ها باشند قادر خواهند بود از اتریوم به عنوان مجموعه ای از لگوهای ابزارهای مالی رمزنگاری شده استفاده کنند. گفته میشود که فرد قادر خواهد بود از هر قابلیتی که افراد در زبان های برنامه نویسی داخل کامپیوتر در اختیار دارند استفاده کند. -ارزهای سفارشی، مشتقات مالی، سیستم های تشخیص هویت و سازمانهای غیر متمرکز همگی به راحتی قابل اجرا خواهند بود، اما از همه مهمتر اینکه بر خلاف سیستم های قبلی امکان ایجاد آن دسته از تراکنشهایی که توسعه دهندگان ایتریوم حتی تصور آن را نمی کرده اند نیز فراهم است. امیدواریم ایتریوم به خوبی به عنوان تکمله ای بر اکوسیستم پول های رمزنگاری شده مورد توجه قرار گیرد چنانکه ظهور وب ۲ برای اینترنت غیر پویای سال ۱۹۹۹ بود. - diff --git a/pages/white-paper/[romanian]-white-paper.md b/pages/white-paper/[romanian]-white-paper.md deleted file mode 100644 index 9ad87df31..000000000 --- a/pages/white-paper/[romanian]-white-paper.md +++ /dev/null @@ -1,559 +0,0 @@ ---- -name: White Paper -category: ---- - -###Ethereum: O platforma de aplicatii descentralizata ce faciliteaza crearea de contracte inteligente de ultima generatie. - -In ultimele cateva luni s-a manifestat un interes tot mai mare fata de utilizarea blockchain-urilor de tip Bitcoin- mecanismul care da intregii lumi sansa sa ajunga la un consens in privinta unei baze de date publice- pentru mai mult decat bani.Aplicatii frecvent citate includ utilizarea bunurilor digitale on-blockchain pentru a reprezenta valute personalizate si instrumente financiare ("[colored coins](https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit)"), dispozitive ["smart property"](https://en.bitcoin.it/wiki/Smart_Property) cum ar fi masinile, care pot urmari un "colored coin" pe un blockchain pentru a determina proprietarul legitim al acestora, insa exista si aplicatii mult mai avansate cum ar fi schimburi decentralizate, derivate financiare,peer-to-peer gambling(?) si sisteme on-blockchain de identitate/reputatie. Dintre toate aceste tipuri de aplicatii, poate cel mai ambitios este conceptul de agenti autonomi sau [Organizatii Autonome Descentralizate](http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/) (DAOs) - entitati autonome care opereaza in blockchain fara nici un fel de control central, evitand orice dependenta de contracte legale si statuturi organizatorice in favoarea resurselor si fondurilor administrate autonom de un smart-contract auto-impus pe un blockchain cryptografic. - -Totusi, majoritatea acestor aplicatii sunt dificil de implementat astazi, din simplul motiv ca sistemele de scripting ale Bitcoin, si chiar ale protocoalelor cryptocurrency de ultima generatie, cum ar fi protocoalele "colored coin" si asa-numitele "metacoins", sunt mult prea limitate pentru a permite metodele arbitrare complexe de calcul pe care DAO le solicita. Ceea ce intentioneaza acest proiect sa faca este sa preia inovatia adusa de astfel de protocoale si sa le generalizeze- create a fully-fledged, Turing-complete (but heavily fee-regulated) cryptographic ledger that allows participants to encode arbitrarily complex contracts, autonomous agents and relationships that will be mediated entirely by the blockchain. In loc sa se limiteze la un tip specific de tranczactii, utilizatorii vor putea folosi Ethereum ca un fel de "Lego de crypto-finante"-altfel spus, acestia vor putea implementa orice proprietate doresc doar prin codarea in limbajul scriptic intern protocolului.Valutele personalizate, derivatele financiare, sistemele de identitate si organizatiile decentralizate vor fi usor de facut, dar, mai important,spre deosebire de sistemele anterioare, va fi posibila construirea unor tipuri de tranzactii pe care nici macar dezvoltatorii Ethereum nu le-au prevazut.Per ansamblu, credem ca acest proiect este un pas in fata spre realizarea "cryptocurrency 2.0"; speram ca Ethereum va fi la fel de important in ecosistemul cryptocurrency pe cat a fost de semnificativa aparitia Web 2.0 pentru static-content-only internet in 1999. - -### Continut - -* [De ce o noua platforma](#de-ce-o-noua-platforma) - * [Colored Coins](#colored-coins) - * [Metacoins](#metacoins) -* [Filozofie](#philosophy) -* [Constructia de blocuri de date](#basic-building-blocks) - * [Implementarea GHOST modficata](#modified-ghost-implementation) - * [Ethereum Client P2P Protocol](#ethereum-client-p2p-protocol) - * [Moneda si emitere](#currency-and-issuance) - * [Formatul datei](#data-format) - * [Algoritmul de minare](#mining-algorithm) - * [Tranzactii](#transactions) - * [Adjustarea dificultatii](#difficulty-adjustment) - * [Rasplata pentru blocuri](#block-rewards) -* [Contracte](#contracts) - * [Aplicatii](#applications) - * [Sub-monede](#sub-currencies) - * [Derivate financiare](#financial-derivatives) - * [Sisteme de reputatie si identitate](#identity-and-reputation-systems) - * [Organizatii Autonome Descentralizate](#decentralized-autonomous-organizations) - * [Aplicatii ce vor urma](#further-applications) - * [Cum functioneaza contractele?](#how-do-contracts-work) - * [Specificatii referitoare la limbajul de programare](#language-specification) -* [Taxe](#fees) -* [Concluzii](#conclusion) -* [References and Further Reading](#references-and-further-reading) - - -## De ce o noua platforma - -Cand se doreste creearea unei noi aplicatii, in special intr-un domeniu delicat ca al criptografiei sau cryptocurrency, primul si cel mai corect instinct este acela de a se folosi protocoale existente pe cat mai mult posibil. Nu este nevoie sa se creeze un nou etalon monetar, sau chiar un nou protocol atunci cand problema poate fi rezolvata prin utilizarea tehnologiilor deja existente. Intradevar, complexitatea incercarilor de rezolvare a problemelor de smart property, smart contracts si corporatii autonome descentralizate, pe langa Bitcoin, este modul in care a aparut interesul fata de protocoalele cryptocurrency de ultima generatie. In decursul cercetarii noastre, totusi, devine evident ca in timp ce protocolul Bitcoin este mai mult decat adecvat pentru valuta, basic multisignature escrow and certain simple versions of smart contracts, there are fundamental limitations that make it non-viable for anything beyond a certain very limited scope of features. - - -###Colored Coins - -Prima incercare de a implementa un sistem de administrare pentru smart property si valute personalizate si bunuri pe un blockchain a fost construita ca un fel de supra-protocol al Bitcoin-ului, pe care multi l-au comparat, in anumite privinte cu felul in care, in suita de protocoale a internetului, HTTP functioneaza ca un strat asupra TCP-ului. Colored coins protocol este definit dupa cum urmeaza: - -Un emitent al colored coin determina ca output-ul unei anumite tranzactii H:i (H being the transaction hash and i the output index)reprezinta un anumit bun si publica o "color definition" specificand output-ul acestei tranzactii alaturi de ceea de ce reprezinta(ex. 1 satoshi de la H:i = 1 gram de aur rambursabil la Stephen's Gold Company) -Others "install" the color definition file in their colored coin clients. -Cand o culoare este emisa pentru prima data, output-ul H:i este singura tranzactie output care are acea culoare. -Daca o tranzactie foloseste input-uri cu o culoare X, atunci si output-ul va avea culoarea X. De exemplu, daca posesorul lui H:i face o tranzactie imediat, pentru a imparti acest output catre cinci adrese, atunci rezultatele acestei tranzactii vor avea, de asemenea, culoarea X. Daca o tranzactie are input-uri de culori diferite, atunci o "lege a transferului culorii" sau un "nucleu al culorii" va determina ce culoare are fiecare output (ex. o implementare mai facila ar determina culoarea output-ului 0 sa fie aceeasi cu cea a input-ului 0, output-ul 1 ar avea aceeasi culoare cu input-ul 1, etc) -Cand un client colored coin observa ca primeste un nou output al tranzactiei, foloseste in algoritm back-tracing bazat pe "nucleul culorii" pentru a determina culoarea acelui output.Pentru ca regula este determinista, toti clientii vor cadea de acord pentru a stabili ce culoare (sau culori) are fiecare output. -Cu toate acestea, protocolul are cateva imperfectiuni fundamentale: - -Verficarea platilor simplificate in Bitcoin - - -Stanga: este suficient sa se prezinte doar un numar mic de noduri intr-o schema Merkel pentru a dovedi validitatea unei ramuri. -Dreapta: orice incercare de a schimba orice parte a schemei Merkel va duce in cele din urma la o inconsecventa undeva in varful latului. -Dificultatea verificarii platilor simplificate- Constructia Schemei Merkel a Bitcoin-ului permite un protocol cunoscut ca "verificarea platilor simplificate", unde un client care nu downloadeaza intregul blockchain poate determina rapid validitatea unui output al unei tranzactii prin a cere altor noduri o dovada criptografica a valabilitatii unei ramuri a schemei. Clientul tot va trebui sa downloadeze header-ele block-ului, pentru a fi sigur, dar cantitatea de date (the amount of data bandwidth ) si timpul de verificare necesar scad cu un factor de aproape o mie.Cu colored coins insa, acest proces este mult mai dificil.Motivul este acela ca nu se poate determina culoarea unui output al unei tranzactii doar prin verficarea schemei Merkel; cu atat mai mult, trebuie folosit algoritmul de scanare inversa, prelundu-se mii de tranzactii si solicitandu-se dovada schemei Merkel de valabilitate pentru fiecare in parte, inainte ca un client sa fie pe deplin satisfacut ca o tranzactie are o anumita culoare. Dupa un an de investigatii, inclunzand si ajutorul nostru, nu s-a putut gasi nici o solutie pentru aceasta problema. -Incompatibilitatea cu script-urile- dupa cum am mentionat si mai sus, Bitcoin are un sistem de scripting flexibil moderat, de exemplu permite utilizatorilor sa semneze tranzactii de forma "Eliberez output-ul acestei tranzactii oricui este dispus sa plateasca 1 BTC". Alte exemple includ contracte de asigurare, microplati eficiente si licitatii on-blockchain. Cu toate acestea, acest sistem, in mod inerent, nu tine cont de culoare, altfel spus, clientul poate face o tranzactie de forma "Eliberez output-ul acestei tranzactii oricui este dispus sa imi plateasca o gold coin definita de originea H:i",pentru ca limbajul scriptului nu stie ca exista conceputl de "culoare".O consecinta majora a acestui lucru este ca in timp ce un schimb sigur intre doua colored coins este posibil, un schimb total descentralizat devine imposibil de obtinut,in conditiile in care nu exista o modalitate de a plasa o comanda de executare pentru a vinde sau pentru a cumpara. -Aceleasi limitari ca ale Bitcoin-ului -ideal, protocoalele on-blockchain ar trebui sa suporte derivate avansate, pariuri si multe forme de transferuri conditionale.Din pacate, colored coins mostenesc limitarile Bitcoin-ului in ceea ce priveste imposibilitatea existentei atator aranjamente. -Metacoins - -Alt concept, asezat deasupra Bitcoin-ului in spiritul HTTP, care este deasupra TCP-ului, este acela de "metacoins". Conceptul unui metacoin este simplu: protocolul metacoin furnizeaza calea de codare a datelor unei tranzactii metacoin in output-ul unei tranzactii Bitcoin, iar un nod metacoin functioneaza prin procesarea tuturor tranzactiilor Bitcoin si evaluarea tranzactiilor Bitcoin care sunt tranzactii metacoin valide pentru a determina balantele contului oricand.Spre exemplu, un protocol simplu metacoin poate solicita patru output-uri unei tranzactii: MARKER, FROM, TO and VALUE. MARKER ar fi o adresa de marcaj specifica pentru a identifica o tranzactie ca o tranzactie metacoin.FROM ar fi adresa de la care sunt trimise coins;TO- adresa unde sunt trimise acestea si VALUE ar fi adresa care codeaza cantitatea trimisa. Deoarece protocolul Bitcoin nu este constientizeaza metacoins, si astfel nu va respinge tranzactii metacoin invalide, protocolul metacoin trebuie sa trateze toate tranzactiile cu primul output in MARKER ca fiind valide si sa reactioneze in consecinta. De exemplu, o punere in aplicare a partii de procesare a tranzactiilor protocolului metacoin descris mai sus s-ar putea arata astfel: - - if tx.output[0] != MARKER: - break - else if balance[tx.output[1]] < decode_value(tx.output[3]): - break - else if not tx.hasSignature(tx.output[1]): - break - else: - balance[tx.output[1]] -= decode_value(tx.output[3]); - balance[tx.output[2]] += decode_value(tx.output[3]); -Avantajul unui protocol metacoin este acela ca protocolul poate permite mai tipuri de tranzactii avansate , incluzand valute personalizate, schimburi descentralizate, etc, care sunt imposibil de implementat folosind doar protocolul care sta la baza Bitcoin. Cu toate acestea, metacoins peste Bitcoin au un mare defect: verificarea platilor simplificate, deja dificil de facut cu colored coins, devine complet imposibila cu o metacoin.Motivul este acela ca se poate folosi SPV pentru a determina daca exista o tranzactie care trimite 30 metacoins la adresa X, dar in sine nu inseamna ca adresa X are 30 metacoins.Daca emitentul tranzactiei nu are 30 metacoins de la inceput si tranzactia este invalida? In cele din urma, aflarea oricarei parti din stadiul curent necesita scanarea tuturor tranzactiilor efectuate de la lansarea metacoin-ului pentru a stabili validitatea fiecarei tranzactii in parte. Astfel, devine imposibil posesia unui client sigur, fara a se downloada intregul blockchain Bitcoin. - -In ambele cazuri, concluzia este urmatoarea: efortul de a construi protocoale mai avansate deasupra Bitcoin-ului, ca HTTP peste TCP, este admirabil, si este intradevar modul corect de a aborda punerea implementarea aplicatiilor descentralizate avansate.Cu toate acestea, incercarea de a construi colored coins si metacoins peste Bitcoin seamana mai mult cu construirea HTTP peste SMTP. Scopul SMTP a fost acela de a transfera email-uri , nu sa serveasca drept motor principal pentru comunicare generica pe internet, iar pentru a-l face eficace ar fi trebuit implementate practici ineficiente si inestetice arhitectural. - -Ethereum rezolva problemele de scalabilitate, fiind hostat pe propriul blockchain, si prin stocarea unui "state tree" distinct in fiecare block impreuna cu o lista a tranzactiilor.Fiecare "state tree" reprezinta stadiul curent al intregului sistem , incluzand balantele adreselor si starea contractelor.Contractele Ethereum pot stoca datele in memorie(contracts are allowed to store data in a persistent memory storage). Aceasta stocare, combinata cu limbajul de scripting Turing-complete,ne permite sa codam un intreg etalon monetar intr-un singur contract, alaturi de numeroase alte tipuri de bunuri criptografice.Prin urmare, intentia Ethereum nu este aceea de a inlocui protocoalele colored coin si metacoin descrise mai sus. Mai degraba, Ethereum intentioneaza sa serveasca drept un strat fundamental superior oferind un sistem unic si puternic de scripting pe baza caruia se pot construi contracte arbitrare avansate, valute si alte aplicatii descentralizate.Daca proiectele deja existente de colored coins si metacoins s-ar muta in Ethereum , ar beneficia de SPV-ul oferit de Ethereum, de optiunea de a fi compatibile cu derivatele financiare ale Ethereum si de abilitatea de a lucra impreuna intr-o singura retea.Cu Ethereum, cineva care are o idee pentru un nou tip de contract sau tranzactie care poate imbunatati in mod considerabil ceea ce se poate face cu cryptocurrency nu ar mai trebui sa isi lanseze propria moneda; isi poate implementa simplu ideea in codul script al Ethereul. Pe scurt, Ethereum este o fundatie pentru inovatie. - - -###Filozofie - -Designul care sta in spatele Ethereum este creat sa urmeze principiile enumerate mai jos: - -Simplitate - Protocolul Ethereum trebuie sa fie cat mai simplu posibil, chiar si cu riscul unor ineficiente in ceea ce ce priveste timpul sau stocarea de date. Ideal, un programator obisnuit ar trebui sa poata urmari si implementa toate specificatiile, astfel incat sa se poata realiza pe deplin potentialul de democratizare fara precedent pe care cryptocurrency il aduce si sa promoveze Ethereum ca un protocol deschis tuturor.Orice optimizare ce adauga complexitate nu ar trebui inclusa decat in cazul in care acea optimizare poate aduce un beneficiu substential. -Universalitate - o parte fundamentala a filosofiei design-ului Ethereum este aceaa ca nu are "trasaturi". In loc de acest lucru, Ethereum asigura un limbaj de scripting intern Turing-complete, pe care un programator il poate folosi pentru a realiza orice smart contract sau tip de tranzactie ce poate fi definita matematic.Vrei sa iti realizezi propriul derivat financiar? Cu Ethereum poti face asta.Vrei sa iti faci propria valuta?Seteaz-o ca un contract Ethereum. Vrei sa instalezi Daemon sau Skynet la o scara larga?Cel mai probabil vei avea nevoie de cateva mii de contracte centralizate, si ai grija sa le feed them generously,pentru a realiza acest lucru, dar nu te opreste nimic daca ai Ethereum la dispozitie. -Modularitate - Partile protocolului Ethereum ar trebui construite modular, si, pe cat posibil, astfel incat sa poata fi separate.Pe parcursul dezvoltarii noaste, scopul este acela de a crea un program unde daca cineva ar face o mica modificare a protocolului, aplicatia ar continua sa functioneze fara alte modificari.Inovatii precum Dagger, Patricia trees si RLP trebuie implementate ca librarii separate si trebuie facute cu "trasaturi complete" chiar daca Ethereum nu are nevoie de anumite "trasaturi" pentru a le face utile si in alte protocoale.Dezvoltarea Ethereum trebuie realizata la cote maxime, spre beneficiul intrecugul ecosistem cryptocurrency, nu doar pentru al lui in sine. -Agilitate - detaliile protocolului Ethereum nu sunt de neclintit.details of the Ethereum protocol are not set in stone. Desi vom fi destul de judiciosi in legatura cu efectuarea modificarilor in constructii de nivel inalt cum ar fi limbajul de tipul C si sistemul de adrese, teste computationale efectuate ulterior ne pot conduce la concluzia ca anumite modificari ale algoritmului sau al limbajului de programare pot imbunatati considerabil scalabilitatea sau securitatea. In cazul in care se ivesc astfel de oportunitati, le vom explora. -Nondiscriminare- protocolul nu trebuie sa incerce sa resctrictioneze activ sau sa previna categorii de uzabilitate specifice.Toate mecanismele de reglementare din protocol trebuie sa fie create in asa fel incat sa regleze prejudicii si sa incerce sa nu se opuna unor anumite aplicatii nedorite specifice. Un programator poate chiar sa administreze un loop script peste Ethereum atat timp cat intentioneaza sa plateasca taxa pentru fiecare pas al tranzactiei. - -Basic Building Blocks - -La origine, Ethereum este a fairly regular memory-hard proof-of-work mined cryptocurrency without many extra complications. De fapt, Ethereum este , din anumite puncte de vedere, mai simplu decat cryptocurrencies bazate pe Bitcoin folosite astazi.Conceptul conform caruia o tranzactie poate avea mai multe output-uri si input-uri, de exemplu, a fost inlocuit cu model bazat pe balante mai intuitiv( pentru a preveni replay-attacks, (to prevent transaction replay attacks, as part of each account balance we also store an incrementing nonce). Sequence numbers and lock times are also removed, and all transaction and block data is encoded in a single format. Instead of addresses being the RIPEMD160 hash of the SHA256 hash of the public key prefixed with 04, addresses are simply the last 20 bytes of the SHA3 hash of the public key. Unlike other cryptocurrencies, which aim to offer a large number of "features", Ethereum intends to take features away, and instead provide its users with near-infinite power through an all-encompassing mechanism known as "contracts". - - -La origine, Ethereum este a fairly regular memory-hard proof-of-work mined cryptocurrency without many extra complications. De fapt, Ethereum este , din anumite puncte de vedere, mai simplu decat cryptocurrencies bazate pe Bitcoin folosite astazi.Conceptul conform caruia o tranzactie poate avea mai multe output-uri si input-uri, de exemplu, a fost inlocuit cu model bazat pe balante mai intuitiv( pentru a preveni replay-attacks, (to prevent transaction replay attacks, as part of each account balance we also store an incrementing nonce). Sequence numbers and lock times are also removed, and all transaction and block data is encoded in a single format. Instead of addresses being the RIPEMD160 hash of the SHA256 hash of the public key prefixed with 04, addresses are simply the last 20 bytes of the SHA3 hash of the public key. Unlike other cryptocurrencies, which aim to offer a large number of "features", Ethereum intends to take features away, and instead provide its users with near-infinite power through an all-encompassing mechanism known as "contracts". - - -Modified GHOST Implementation - -Protocolul "Greedy Heavist Observed Subtree" (GHOST) este o inovatie introdusa de Yonatan Sompolinsky si Aviv Zohar in Decembrie 2013. Motivul din spatele GHOST este acela ca in prezent, blockchains cu rata mare de confirmare sufera de probleme de securitate datorate unui stale rate ridicat – deoarece block-urile necesita un anume timp pentru a circula in retea; daca un miner A exploateaza un block si minerul B exploateaza un alt block, inainte ca block-ul minerului A sa se propage catre minerul B, block-ul minerului B se va corupe, si nu va contribui la securitatea retelei.Mai mult de atat, exista problema centralizarii: daca minerul A reprezinta un mining pool cu un hashpower de 30% si minerul B are hashpower de 10%, A risca sa produca stale blocks 70% din timp, iar B sa produca block-uri invalide 90% din timp. Astfel, daca stale rate este ridicat, A va fi mult mai eficient, numai multumita marimii sale.Combinand aceste doua efecte, acele blockchains care produc block-uri mai rapid sunt mai probabil sa conduca la un mining pool -cu un procentaj mare din hashpower-ul retelei- care sa aiba control efectiv asupra procesului de mining. - -Asa cum descriu Sompolinsky si Zohar, GHOST rezolva prima problema a pierderilor de securitate ale retelei prin includerea stale blocks in calculul care determina care lant este mai lung: asta inseamna ca nu numai predecesorii unui block, dar si stale blocks care deriva din acesti predecesori („unchi” in jargonul Ethereus) sunt luati in calcul in a determina care block are cea mai vizibila dovada de munca ca sa il sustina. Pentru a rezolva aceasta problema secundara a centralization bias, trebuie sa mergem dincolo de protocolul descris de Sompolinsky si Zohar, si sa atribuim block rewards pentru stale blocks: un stale block primeste 87.5% din base reward, si „nepotul” care include stale block-ul primeste cei 12.5% ramasi. Taxele de tranzactie totusi, nu sunt acordate „unchilor”. - -Ethereum implementeaza o versiune simplificata a GHOST care merge in jos doar un nivel. Un stale block poate fi inclus ca „unchi” numai de catre descendentul direct al unuia din „fratii” lui, nu si al altor block-uri mai indepartate. Aceasta s-a facut pentru mai multe motive. In primul rand, un protocol GHOST nelimitat ar include prea multe complicatii in calculul numarului de „unchi” valizi pentru fiecare block. In al doilea rand, un GHOST nelimitat, cu o compensare ca aceea folosita de Ethereum nu mai constrange un miner sa actioneze pe chain-ul principal si nu pe chain-ul unui atacator public. In ultimul rand, calculele arata ca GHOST la single-level are 80% din avantajele unui GHOST nelimitat, si ofera un stale rate comparabil cu Litecoin de 2.5 minute chiar si cu un block time de 40 de secunde. Totusi, ca sa nu exageram, vom pastra un block time de 60 de secunde, specific pentru Primecoin, deoarece block-urile individuale pot necesita mai mult timp pentru a fi verificate. - - -Ethereum Client P2P Protocol - -P2P Protocol - - -Clientul P2P de protocol Ethereum este un protocol standard de cryptocurrency, si poate fi folosit la fel de usor pentru alte tipuri de cryptocurrency; singura modificare este introducerea protocolului GHOST, descris mai sus. Clientul Ethereum va fi in mare parte reactiv; daca nu e provocat, singurul lucru care il va face de unul singur este sa determine daemon-ul de retea, sa mentina conexiunile, si sa trimita periodic un mesaj prin care sa ceara block-uri derivate din block-ul curent. De asemenea, clientul va fi mai puternic. Spre deosebire de Bitcoin, care stocheaza o cantitate limitata de date despre blockchain, clientul Ethereum va opera si ca un back-end functional pentru un block explorer. - -Cand clientul citeste un mesaj, va parcurge pasii urmatori: - -Hash the data, and check if the data with that hash has already been received. If so, exit. -Stabileste tipul de date. Daca datele sunt tranzactii, daca tranzactia este valida, este adaugata la lista de tranzactii locale, e procesata pe block-ul curent, si emisa pe retea. Daca datele reprezinta un mesaj, se raspunde la acesta. Daca datele reprezinta un block, se trece la pasul 3. -Verificati daca „parintele” unui block este deja stocat in baza de date. Daca nu este, iesiti. -Verificati daca este validat lucrul pe header-ul block-urilor din lista de „unchi”. Daca nu, iesiti. -Verificati daca fiecare block header din lista de „unchi” din block are ca parinte la randul lui fiecare parinte al block-ului respectiv. Daca nu, iesiti. Tineti minte ca block headers care sunt „unchi” nu trebuie sa fie in baza de date; ei trebuie doar sa aiba parintele corect si dovada de lucru. De asemenea, asigurati-va ca „unchii” sunt unici, si separati de parinte. -Verificati daca marcajul de timp al block-ului este cu maxim 15 minute in viitor, si inaintea timpului parintelui. Verificati daca dificultatea block-ului si numarul acestuia sunt corecte. Daca vreuna din aceste verificari esueaza, iesiti. -Incepeti cu starea parintelui blocului, si aplicati succesiv pe acesta fiecare tranzactie din block. La sfarsit, adaugati reward-urile minerului. Daca root hash a state tree-ului rezultat nu se potriveste cu state root din block header, iesiti. Daca se potriveste, adaugati blocul la baza de date si avansati la pasul urmator -Determinati TD(block) ("total difficulty") pentru noul block. TD se defineste prin TD(genesis_block) = 0 si TD(B) = TD(B.parent) + sum([u.difficulty for u in B.uncles]) + B.difficulty.Daca noul block are un TD mai mare decat block-ul curent, setati noul block pentru block-ul curent, si continuati la pasul urmator. Daca nu, iesiti. -Daca noul block a fost schimbat, aplicati toate tranzactiile in lista de tranzactii, omiteti-le pe cele invalide, si retrimiteti block-ul si tranzactiile pe retea. -„Current block” este un indicator pastrat de fiecare nod care se refera la blocul considerat reprezentativ pentru starea actuala a retelei. Toate mesajele care cer informatii referitoare la sold, starea contractelor etc, au raspunsurile calculate in raport cu current block. Daca un nod este in procesul de mining, procedeul este doar putin alterat: cand se fac operatiile de mai sus, nodul mineaza continuu current block-ul, folosindu-i lista de tranzactii ca si lista de tranzactii pentru block. - - -Currency and Issuance(Moneda si emiterea ei) - -Reteaua Ethereum are o moneda inclusa, numita „ether”. Exista doua motive pentru includerea unei monede in retea. In primul rand, ca si Bitcoin, ether este acordat minerilor pentru a stimula securitatea retelei.In al doilea rand, serveste ca metoda de plata pentru servicii anti-spam. Din cele doua alternative la taxa, dovada de lucru pentru fiecare tranzactie similara cu Hashcashsi metoda laissez-faire fara taxa, prima nu este eficienta cu resursele si prea punitiva pentru calculatoare slabe si smartphone-uri, pe cand cea din urma ar cauza ca reteaua sa fie suprasolicitata imediat de contracte tip „logic bomb” repetate. Pentru convenienta, si pentru a evita viitoare dispute (vezi dezbateream BTC/uBTC/satoshi), denominatiile vor fi pre-marcate: - -Dupa 1 an Dupa 5 ani -Currency units 1.9X 3.5X -Fundraiser participants 52.6% 28.6% -Fiduciary members and early contributors 11.8% 6.42% -Alocatii pre-lansare aditionale 2.63% 1.42% -Rezerve 11.8% 6.42% -Miners 21.1% 57.1% -1: wei -103: (nespecificat) -106: (nespecificat) -109: (nespecificat) -1012: szabo -1015: finney -1018: ether -Acestea trebuie vazute ca o viziune expandata a conceptelor de ""dolari" si "centi" sau ca "BTC" si "satoshi" reprezinta viitorul.Szabo, finney si ether putin probabil vor fi folosite in viitorul apropiat, in timp ce celelalte unitati vor fi folosite in continuare la fel de mult."ether" este destinata sa fie unitatea primara in sistem, cum este spre exemplu dolarul sau bitcoin-ul.Dreptul de a numi unitati 103, 106 si 109 va fi lasat ca recompensa secundara de nivel inalt pentru obiectul strangerii de fonduri, cu pre-aprobare de la noi. - -Modelul de emitere va arata in modul urmator: - -Ether va fi lansat intr-o strangere de fonduri la pretul de 1000-2000 ether per BTC, primii investitori primind preturi mai bune pentru a compensa numarul incert de mare al participantilor intr-o faza incipienta.Suma minima de finantare va fi de 0.01 BTC. Presupunem ca X ether sunt lansati in acest mod. -0.225X ether vor fi alocati membrilor fiduciari si primilor contribuabili care s-au implicat substantial in proiect, inaintea inceperii strangerii de fonduri. Aceasta parte va fi stocata intr-un contract time-lock, aproximativ 40% va putea fi folosita dupa un an, 70% dupa doi ani, iar 100% dupa 3 ani.. -0.05X ether vor fi alocati pentru un fond folosit pentru platile cheltuielilor si premiilor in ether in perioada dintre stratul strangerii de fonduri si lansarea valutei. -0.225X ether vor fi alocati ca rezerva pe termen lung pentru a plati cheltuieli, salarii si premii dupa lansarea valutei. -0.4X ether will be mined per year forever after that point -Rata de inflatie pe termen lung(procentaje) - - -Despite the linear currency issuance, just like with Bitcoin over time the inflation rate nevertheless tends to zero -De exemplu, dupa cinci ani si presupunand ca nu s-au realizat tranzactii, 28.6% din ether va reveni primilor participanti la strangerea de fonduri, 6.42% membrilor fiduciari si primilor contribuabili, 6.42% platiti pentru rezerve si 57.1% -miners Modelul permanent linear de inflatie reduce riscul unei concentrari de resurse financiare destul de mare in Bitcoin, dupa cum ar vedea unii, si da sanse egale indivizilor care traiesc in prezent, dar si celor din viitor, sa obtina unitati valutare,in acelasi timp retinand stimulente puternice pentru a obtine si pentru a pastra ether, pentru ca "rata" de inflatie tot va tinde catre zero pe parcursul timpului(ex. pe parcursul anului 1000001 "proviziile" de bani vor creste de la 500001.5 * X la 500002 * X, cu o rata de inflatie de 0.0001%).Mai mult decat atat, o mare parte din interesul in Ethereum va fi pe termen mediu, prezicem ca daca Ethereum va fi un succes,vom vedea cea mai mare parte a cresterii sale pe un interval de timp 1-10 ani, iar aprovizionarea in aceasta perioada va fi foarte limitata. - -De asemenea, sustinem ca, deoarece monedele sunt intotdeauna pierdute in timp din cauza neglijentei, etc, si pierderea monedei poate fi modelata ca un procent din totalul ofertei pe an, ca totalul valutei aflat in circulatie se va stabiliza, in cele din urma, la o valoare echivalenta cu emiterea anuala impartita la rata de pierdere (de exemplu, la o rata de pierdere de 1%, odată ce alimentarea ajunge 40X atunci 0.4X vor fi exploatate si 0.4X pierdute in fiecare an, creand un echilibru). - - -Data Format - -Toate datele din Ethereum vor fi stocate in recursive length prefix encoding, care serializeaza matrice de siruri de caractere de lungime si dimensiuni arbitrare in siruri de caractere. De exemplu, ['caine', 'pisica'] este serializat (in byte array format) ca [ 130, 67, 100, 111, 103, 67, 99, 97, 116]; ideea generala este sa se codeze tipul de date si lungimea acestora intr-un singur byte urmat de datele efective (ex. transformata intr-o matrice byte, 'caine' devine [ 100, 111, 103 ], deci serializarea sa este[ 67, 100, 111, 103 ].Dupa cum este sugerata si de numele sau, codarea RLP este recursiva; atunci cand folosim codarea RLP pentru o matrice, de fapt codam un sir care este concatenarea codificarii RLP al fiecarui element. In plus, retineti ca numarul de bloc, marcajele de timp, dificultatea, depozitele de memorie, soldurile conturilor si toate valorile din contractul de depozitare sunt numere intregi, si Patricia tree hashes,root hashes, adresele, listele tranzactii hash si toate cheile in depozite de contract sunt siruri de caractere.Principala diferenta dintre cele doua este ca sirurile de caractere sunt stocate ca date de lungime fixa (20 bytes pentru adrese, 32 bytes pentru orice altceva), si numerele intregi ocupa atat spatiu cat au nevoie. Numerele intregi sunt stocate intr-o baza de format 256 big-endian(ex. 32767 in format de matrice byte ca [ 127, 255 ]). - -Un block intreg este stocat ca: - - [ - block_header, - transaction_list, - uncle_list - ] -Unde: - - transaction_list = [ - transaction 1, - transaction 2, - ... - ] - - uncle list = [ - uncle_block_header_1, - uncle_block_header_2, - ... - ] - - block_header = [ - parent hash, - sha3(rlp_encode(uncle_list)), - coinbase address, - state_root, - sha3(rlp_encode(transaction_list)), - difficulty, - timestamp, - extra_data, - nonce - ] -Fiecare tranzactie si header de block unchi este in sine o lista.Datele pentru dovada de functionare este codarea RLP a block-ului FARA nonce. uncle_list si transaction_list sunt listele de headere block unchi si tranzactiile din block, respectiv . nonce si extra_data sunt ambele limitate la un maxin de 32 bytes, exceptand genesis block unde parametriiextra_data vor fi mult mai mari. - -State_root este radacina unei scheme Merkle Patricia continand (cheie, valoare) perechi pentru toate conturile in care fiecare adresa este reprezentata de un sir de caractere binar de 20 bytes. La adresa fiecarui cont in parte , valoarea stocata in schema Merkel Patricia este un sir de caractere serializarea RLP a unui obiect de forma: - - [ balance, nonce, contract_root, storage_deposit ] -nonce este numarul de tranzactii facute din cont si este incrementat de fiecare data cand este realizata o tranzactie.Scopul este acela de (1) a face o tranzactie valida o singura data pentru a preveni atacurile, si (2) pentru a face imposibil (mai exact cryptografic nefezabil) construirea unui contract cu acelasi hash ca al unui contract existent. balance se refera la balanta contului, denominata in wei. contract_root este radacina unei alte scheme Patricia, continand memoria contractului, daca acel cont este controlat de un contract.Daca un cont nu este controlat de un contract, contract root va fi un sir de caractere gol. storage_deposit este un contor care stocheaza taxele de depozitare achitate; functia sa va fi discutata in detaliu mai jos. - - - - -Mining algorithm - -O proprietate de dorit in mining algorithms este rezistenta la optimizare prin hardware specializat. La inceput, Bitcoin a fost conceput ca o moneda democratica, dand oricui sansa de a participa in procesul de mining cu un CPU. In 2010 totusi, mineri mai rapizi care exploatau paralelizarea oferita de procesoare video (GPU) au preluat controlul, crescand network hashpower cu un factor de 100, si lasand CPU-urile in urma. In 2013, o alta categorie de hardware specializat, application-specific integrated circuits (ASICs) a depasit ca performante GPU-urile, atingand viteze de 100 de ori mai mari, folosind chip-uri fabricate special pentru computarea SHA256 hashes. Astazi, este practic imposibila minarea fara achizitionarea unui mining device de la una din aceste companii, si exista ingrijorari ca in 5-10 ani, mining-ul va fi dominat in intregime de de corporatii centralizate precum AMD sau Intel. - -Pana acum, calea principala de a atinge acest scop a fost "memory-hardness", construirea unor algoritmi proof of work care necesita nu numai un numar mare de calcule, dar si multa memorie pentru validare, astfel reducand eficacitatea implementarilor de hardware paralelizat si specializat. Exista cateva implementari de memory-hard proof of work, fiecare cu defectele ei: - -Scrypt - este o functie proiectata sa ocupe 128 kb de memorie pentru calcul. In esenta, algoritmul functioneaza prin ocuparea unui memory array cu hashes, si apoi calculand valori intermediare si finalmente, un rezultat bazat pe aceste valori din memory array.Totusi, parametrul de 128 kb este o limitare, si ASICs pentru Litecoin sunt deja in proces de dezvoltare. In plus, exista o limita naturala pe cantitatea de memory hardness in Scrypt care poate fi atinsa, caci procesul de verificare necesita la fel de mult calcul si memorie, ca o etapa a procesului de mining. -Birthday attacks - ideea din spatele birthday-based proofs of work este simpla: gasiti valorile xn,i,j astfel incat i < k, j < k si|H(data+xn+i) - H(data+xn+j)| < 2^256 / d^2. Parametrul d seteaza dificultatea calculului de a gasi un block, si parametrul k seteaza memory hardness. Orice birthday algorithm trebuie sa stocheze cumva toate calculele de H(data+xn+i)in memorie, astfel ca viitoarele calcule sa fie comparate cu acestea. Aici, calculul este memory-hard, dar verificarea este memory-easy, permitand extreme memory hardness fara a compromite usurinta verificarii.Totusi, algoritmul este problematic din doua motive. In primul rand, exista un time-memory tradeoff attack, unde utilizatorii cu 2x mai putina memorie pot compensa cu 2x putere de calcul, prin urmare memory hardness nu este absoluta. In al doilea rand, echipamentul hardware specializat poate fi usor de construit, in special daca se trece de traditionala arhitectura pe baza de chip si procesor, catre diverse clase de hash tables bazate pe hardware sau probabilistic analog computing. -Dagger - ideea din spatele Dagger,, un algoritm in-house dezvoltat de echipa Ethereum, este aceea de a avea un algoritm similar lui Scrypt, dar proiectat special ca fiecare nonce sa depinda numai de o mica portiune din data tree care rezulta din fiecare grup de ~10 milioane nonces. Calculul nonces la un nivel rezonabil de eficienta solicita construirea unui intreg tree, ocupand 100mb de memorie, pe cand verificarea unui nonce necesita doar 100kb. Totusi, aloritmii in genul Dagger sunt vulnerabili la dispozitive cu circuite computationale multiple care impart aceeasi memorie, si desi acest pericol poate fi diminuat, este probabil imposibil de inlaturat complet. -Ca un standard, avem in vedere un algoritm in genul Dagger cu parametri ajustati sa minimizeze atacurile de hardware specializat, probabil impreuna cu un proof of stake algorithm ca propriul nostru Slasher, pentru securitate sporita, daca este necesar. Totusi, pentru a veni cu un proof-of-work algorithm mai bun ca al competitiei, intentia noastra este sa folosim o parte din fondurile stranse pentru a organiza o competitie cu premii, similara cu cele pentru a determina algoritmul pentru Advanced Encryption Standard (AES) in 2005 si SHA3 hash algorithm in 2013, unde grupuri de cercetare din toata lumea concureaza pentru a dezvolta mining algorithms rezistenti la ASIC, si sa avem un proces de selectie cu mai multe runde de jurizare pentru a alege invingatorii. Incurajam cercetari despre memory-hard proofs of work, self-modifying proofs of work, proofs of work bazate pe instructiuni x86, multiple proofs of work cu protocoale economice ca stimulente pentru dezvoltare, si orice design care atinge scopul dorit. De asemenea vor exista oportunitati de a explora alternative precum proof of stake, proof of burn si proof of excellence. - - - - -Tranzactii - -O tranzactie este stocata astfel: - -[ nonce, receiving_address, value, [ data item 0, data item 1 ... data item n ], v, r, s ] -nonce este numarul de trnazactii deja trimise de acel cont, codate in forma binara(ex. 0 -> '', 7 -> '\x07', 1000 -> '\x03\xd8'). (v,r,s) este semnatura bruta Electrum-style a tranzactiei fara ca acea semnatura sa fie facuta cu private key corespunzatoare contului expeditor, cu 0 <= v <= 3. De la o semnatura Electrum-style (65 bytes) este posibila extractia public key, si , deci, si adresa, in mod direct.O tranzactie valida este una in care (i) semnatura este bine formata(ie. 0 <= v <= 3, 0 <= r < P, 0 <= s < N, 0 <= r < P - N if v >= 2), si (ii) contul expeditor are destule fonduri pentru a plati taxele si valoarea.Un block valid nu poate contine o tranzactie invalida; cu toate acestea, daca un contract genereaza o tranzactie invalida, acea tranzactie pur si simplu nu va avea efect.Daca cineva doreste sa plateasca voluntar o taxa mai mare, este liber sa faca asta, prin construirea unui contract care trimite mai departe tranzactia , dar care trimite automat o suma sau un procentaj minerului block-ului curent. - -Tranzactiile trimise la un sir gol , ca adresa, sunt tranzactii speciale, creand un "contract". - - -Difficulty adjustment( Adjustarea dificultatilor) - -Dificultatea este adjustata prin formula: - -D(genesis_block) = 2^36 -D(block) = - if anc(block,1).timestamp >= anc(block,501).timestamp + 60 * 500: D(block.parent) - floor(D(block.parent) / 1000) - else: D(block.parent) + floor(D(block.parent) / 1000) -anc(block,n)este generatia "n" ascendenta a block-ului; toate block-urile dinaintea block-ului geneza(original) se presupune ca au acelasi timestamp ca block-ul geneza.Acesta se stabilizeaza automat in jurul a 60 de secunde. Alegerea valorii de 500 a fost facuta pentru a balansa preocuparea ca minerii cu valori mai mici , cu hashpower suficient pentru a produce des doua block-uri la rand ,ar avea imboldul de a da un timestapt incorect pentru a-si maximiza propria rasplata si, pentru ca, odata cu valorile mari si dificultatea oscileaza prea mult, cu constanta de 500 simularile arata ca un hashpower constant produce o variatie de aproximativ +/-20%. - - -Block Rewards - -Un miner primeste trei tipuri de rasplata: o rasplata static block pentru producerea unui block, platile din tranzactii si recompense "nepot/unchi" descrise in sectiunea GHOST de mai sus.Minerul va primi 100% din recompensa block, dar plata pentru tranzactie va fi impartita, astfel 50% din ea merge la miner, iar restul de 50% este impartit in mod egal intre ultimii 64 de mineri.Motivul pentru aceasta impartire este unul de preventie impotriva creerii de catre un miner a unui block Ethereum cu un numar nelimitat de operatii, care sa plateasca taxele de tranzactii catre ei insisi, mentinand in acelasi timp un stimulent pentru ca alti mineri sa includa tranzactii.Dupa cum am descris in in sectiunea GHOST, unchii primesc doar 87.5% din rasplata block, celelalte 12.5% procente ramanand la nepotul fiecaruia in parte, platile pentru tanzactiile provenite din block-uri vechi nu merg la nimeni. - - -Contracts - -In Ethereum exista doua tipuri de entitati care pot genera si pot primi tranzactii: persoane reale(sau bots, protocoalele cryptografice nu ii pot distinge) si contracte. Un contract este, esential , un agent automat care traieste in reteaua Ethereum, are o adresa si o balanta Ethereum, si care poate primi si trimite tranzactii.Un contract este "activat" de fiecare data cand cineva trimite o tranzactie spre el, punct in care isi ruleaza codul, poate modificandu-si starea interna sau chiar trimitand anumite tranzactii, dupa care se inchide (shut down)."Codul" pentru un contract este scris special intr-un limbaj de un nivel scazut, constand intr-o stiva , care nu este persistenta, si2256 storage entries care constituie starea permanenta a contractului. Retineti ca utilizatorii Ethereum nu vor trebui sa codeze in acest limbaj, vom furniza un C-like language cu variabile, expresii, conditionale, tablouri si while loops, si ofera un compiler down to Ethereum script code. - - -Applications - -Aici sunt cateva exemple a ceea ce se poate face cu contractele Ethereum, cu toate exemplele de coduri scrise in our C-like language. Variabileletx.sender, tx.value, tx.fee, tx.data si tx.datan sunt proprietati ale tranzactiilor viitoare, contract.storage, si contract.address ale contractului in sine, si block.contract_storage, block.account_balance, block.number, block.difficulty, block.parenthash, block.basefee si block.timestamp proprietati ale block-ului. block.basefee este "taxa de baza" in care toate taxele de tranzactii din Ethereum sunt calculate ca multipli (is the "base fee" which all transaction fees in Ethereum are calculated as a multiple of; for more info see the "fees" section below). Toate variabilele exprimate prin majuscule (ex. A) sunt constante, pentru a fi inlocuite de valori adevarate de creatorul contractului, in momentul in care acel contract este eliberat. - - -Sub-currencies - -Sub-currencies (sub-valutele) au multe aplicatii, de la valute care reprezinta bunuri ca dolari sau aur la actiuni si chiar valute emise cu o singura unitate pentru a reprezenta obiecte de colectie sau proprietate intelectuala (smart property).Protocoale financiare avansate cu destinatie avansata care se afla pe Ethereum pot dori sa se organizeze cu o valuta interna.Sub-currencies sunt surprinzator de usor de implementat in Ethereum, aceasta sectiune descrie un contract destul de simplu pentru acest lucru. - -Ideea este aceea ca daca cineva doreste sa trimita x unitati de valuta contului A in valuta contractului C,vor trebui sa faca o tranzactie de format(C, 100 * block.basefee, [A, X]), iar contractul analizeaza tranzactia si adjusteaza balanta corespunzator.Pentru ca o tranzactie sa fie valabila, trebuie trimisa de 100 de ori taxa de baza in ether, pentru a alimenta contractul (and the contract parses the transaction and adjusts balances accordingly. For a transaction to be valid, it must send 100 times the base fee worth of ether to the contract in order to "feed" the contract (cu fiecare pas computational ce urmeaza dupa primii 16 contractul va fi taxat cu o mica plata si contractul va inceta sa functioneze daca balanta sa ajunge la zero). - - if tx.value < 100 * block.basefee: - stop - elif contract.storage[1000]: - from = tx.sender - to = tx.data[0] - value = tx.data[1] - if to <= 1000: - stop - if contract.storage[from] < value: - stop - contract.storage[from] = contract.storage[from] - value - contract.storage[to] = contract.storage[to] + value - else: - contract.storage[mycreator] = 10^18 - contract.storage[1000] = 1 -Programatorii sub-valutelor Ethereum pot , deasemenea, sa doreasca adaugarea unor alte trasaturi mai avansate: - -Includerea unui mecanism prin care oamenii pot cumpara unitati valutare in schimbul ether-ilor, poate licitand un numar fix de unitati zilnic. -Permiterea platii taxelor de tranzactii in valute interne, si apoi rambursarea taxei pentru tranzactiile ether expeditorului.Acest lucru rezolva una din problemele majore pe care toate celelalte protocoale "sub-valuta" le-au avut pana in momentul de fata: faptul ca utilizatorii de sub-valute trebuie sa mentina o balanta de unitati de sub-valute pentru utilizare si unitati in principala valuta pentru a plati taxele pentru tanzactii.Aici, un cont nou ar trebui sa fie "activat" o data cu ether-ul, dar de aici mai departe nu ar mai trecui reincarcat. -Permiterea unui schimb trust-free descentralizat intre valuta si ether. Retineti ca acest schimb trust-free descentralizat intre orice doua contracte este teoretic posibil in Ethereum chiar si fara un suport special, dar suportul special va permite ca procesul sa fie realizat de aproximativ zece ori mai ieftin. - -Derivate financiare - -Ingredientul-cheie care sta la baza derivatelor financiare este un data feed care furnizeaza pretul unui bun, asa cum e desemnat in alt bun (in cazul Ethereum, al doilea bun va fi de obicei ether). Sunt mai multe cai de a implementa un data feed; o metoda, implementata de creatorii Mastercoin, consta in includerea data feed in blockchain. Codul este acesta: - - if tx.sender != FEEDOWNER: - stop - contract.storage[data[0]] = data[1] -Orice alt contract va putea apoi sa interogheze index-ul I din data store D folosind block.contract_storage(D)[I]. Un mod mai avansat de a implementa un data feed este efectuarea acestei operatii off-chain – provider-ul de data feed sa semneze toate valorile, facand posibila incercarea de a declansa contractul numai prin includerea signed data, si apoi folosirea functiei de internal scripting a Ethereum pentru a verifica semnatura. In mare, orice derivat poate fi efectuat astfel, incluzand leverage trading, optiuni si operatiuni mai avansate precum collateralized debt obligations (no bailouts here though, so be mindful of black swan risks). - -Pentru a exemplifica, facem un contract de hedging. Ideea de baza este ca acel contract este creat de o persoana A, care depune 4000 ether. Contractul este apoi disponibil pentru acceptare de catre altcineva, care mai depune 1000 ether. Sa spunem ca 1000 ether valoreaza 25$ cand este facut contractul, potrivit indexului I din data store D. Daca persoana B accepta, dupa 30 de zile oricine poate trimite o tranzactie pentru a face contractul sa proceseze, trimitand acelasi echivalent de dolari in ether (in exemplul nostru, 25$) inapoi la B si restul catre A. B are avatajul de a fi protejat de currency volatility risk, fara a fi nevoit sa depinda de alti emitenti. Singurul risc pe care si-l asuma B este daca valoarea ether scade cu 80% in 30 de zile – chiar si atunci, daca B este online, se poate transfera catre un alt hedging contract. Avantajul lui Aeste taxa implicita de 0.2% din contract, si A se poate feri de pierderi daca detine valuta (USD) in alte locatii (sau Apoate fi optimist in legatura cu viitorul Ethereum, si vrea sa mentina ether la un leverage de 1.25x, caz in care taxa ar fi in favoarea lui B). - - if tx.value < 200 * block.basefee: - stop - if contract.storage[1000] == 0: - if tx.value < 1000 * 10^18: - stop - contract.storage[1000] = 0 - contract.storage[1001] = 998 * block.contract_storage(D)[I] - contract.storage[1002] = block.timestamp + 30 * 86400 - contract.storage[1003] = tx.sender - else: - ethervalue = contract.storage[1001] / block.contract_storage(D)[I] - if ethervalue >= 5000 * 10^18: - mktx(contract.storage[1003],5000 * 10^18,0,0) - else if block.timestamp > contract.storage[1002]: - mktx(contract.storage[1003],ethervalue,0,0) - mktx(A,5000 - ethervalue,0,0) -Si alte contracte financiare avansate sunt posibile; optiuni de clauze complexe (ex: “Oricine, denumit in continuare X, poate revendica acest cont prin depunerea a 2$ pana la 1 decembrie). X va avea de ales pe 4 decembrie intre a primi 1.95$ pe 29 decembrie si dreptul de a se decide pe 11 decembrie intre 2.20$ pe 29 decembrie si dreptul de a alege pe 18 decembrie intre suma de 1.89 GBP si a plati 1 EUR si a primi 3.20 EUR pe 29 decembrie) pot fi definite mai simplu prin stocarea unui state variable la fel ca in contractul mentionat, dar cu mai multe clauze in cod, cate una pentru fiecare stare posibila. Tineti minte ca orice forma de contract financiar trebuie sa fie colaterale; reteaua Ethereum nu detine o agentie de executare silita si nu poate colecta datorii. - - -Identity and Reputation Systems - -Cea mai veche alternativa cryptocurrency, Namecoin,a incercat sa foloseasca un blockchain specific Bitcoin pentru a furniza un sistem de inregistrare a numelor, unde utilizatorii isi pot inregistra numele si si alte date intr-o baza de date publica. Cel mai folosit caz este un sistem DNScare alocheaza nume de domenii precum “bitcoin.org” (sau in cazul Namecoin, “bitcoin.bit”) unei adrese IP. In alte cazuri se includ autentificarea prin e-mail si posibil alte advanced reputation systems. Aici este un contract simplu pentru un sistem de inregistrare a numelor in genul Namecoin, in Ethereum: - - if tx.value < block.basefee * 200: - stop - if contract.storage[tx.data[0]] or tx.data[0] < 100: - stop - contract.storage[tx.data[0]] = tx.data[1] -Se poate adauga mai multa complexitate, pentru a permite utilizatorilor sa schimbe mappings, sa trimita tranzactii automat catre contract, de unde sa fie retrimise, si chiar sa adauge reputatie si web-of-trust mechanics. - - -Organizatii Descentralizate Autonome - -Conceptul general din spatele Organizatiilor Descentralizate Autonome este acela ca o entitate virtuala are un anumit numar de membri sau actionari, care daca detin 67% din actiuni, sunt autorizati sa foloseasca fondurile entitatii, si sa modifice codul. Membrii ar decide impreuna cum ar trebui alocate fondurile organizatiei. Metodele de alocare pot fi diverse: de la cadouri si salarii pana la implementarea unei monede interne sau bonusuri. In esenta, aceasta imita metodele folosite de o companie traditionala sau organizatie non-profit, doar ca foloseste tehnologia cryptographic blockchain. Pana acum discutiile legate de DAO au vizat modelul “capitalist” al corporatiilor descentralizate autonome (DAC) cu actionari care primesc dividende; o alternativa ar permite tuturor actionarilor sa aiba un rol egal in luarea deciziilor, si un numar de 67% din membri pentru a decide acceptarea sau eliminarea unui membri. Pretentia de a apartine unei singure companii va fi atunci impusa de grup. - -Exemple de “skeleton code” pentru o DAO - - -Exista 3 tipuri de tranzactii: - -[0,k]pentru a inregistra un vot pentru schimbarea codului -[1,k,L,v0,v1...vn]pentru a inregistra o shimbare de cod k in favoarea setarii memoriei incepand cu locatia L pana la v0, v1 ... vn -[2,k]pentru a finaliza o schimbare de cod -Tineti minte ca acest design e bazat pe un model aleatoriu de adrese si hashes, pentru a asigura integritatea datelor; contractul va fi corupt in vreun fel dupa 2^128 utilizari, dar acest numar este acceptabil, deoarece un astfel de nivel de uzare este improbabil in viitorul apropiat.2^255 este folosit ca un numar “magic” pentru a stoca numarul total de membri, si apartenenta este denotata cu un 1 la adresa membrului. Ultimele 3 randuri din contract sunt folosite pentru a adauga C ca un prim membru; din acel moment, va fi responsabilitatea lui C sa foloseasca protocolul democratic de a schimba codul pentru activitati precum adaugarea membrilor si bootstrap. - - if tx.value < tx.basefee * 200: - stop - if contract.storage[tx.sender] == 0: - stop - k = sha3(32,tx.data[1]) - if tx.data[0] == 0: - if contract.storage[k + tx.sender] == 0: - contract.storage[k + tx.sender] = 1 - contract.storage[k] += 1 - else if tx.data[0] == 1: - if tx.value <= tx.datan * block.basefee * 200 or contract.storage[k]: - stop - i = 2 - while i < tx.datan: - contract.storage[k + i] = tx.data[i] - i = i + 1 - contract.storage[k] = 1 - contract.storage[k+1] = tx.datan - else if tx.data[0] == 2: - if contract.storage[k] >= contract.storage[2 ^ 255] * 2 / 3: - if tx.value <= tx.datan * block.basefee * 200: - stop - i = 3 - L = contract.storage[k+1] - loc = contract.storage[k+2] - while i < L: - contract.storage[loc+i-3] = tx.data[i] - i = i + 1 - if contract.storage[2 ^ 255 + 1] == 0: - contract.storage[2 ^ 255 + 1] = 1 - contract.storage[C] = 1 -Aceasta implementeaza modelul egalitar DAO unde membrii au un numar egal de actiuni. Se poate adapta la un “shareholder model” prin introducerea numarului de actiuni detinute de fiecare membru, si furnizarea unui mod simplu de transfer de actiuni. - - -DAO si DAC au fost un punct de interes pentru utilizatorii de cryptocurrency ca o viitoare forma de organizare economica, si suntem incantati de potentialul oferit de DAO. Pe termen lung, chiar fondul Ethereum intentioneaza sa faca o tranzitie, devenind un DAO autonom. - -. - - -Alte Aplicatii - -1) Savings wallets. Sa presupunem ca Alice vrea sa aiba conturile in siguranta, dar e ingrijorata ca isi va pierde (sau cineva ii va fura) codul. Depune ether intr-un contract cu Bob, o banca, dupa cum urmeaza: Alice poate retrage maxim 1% din fonduri pe zi, Alice impreuna cu Bob pot retrage totul, si Bob de unul singur poate retrage 0.05% din fonduri. In mod normal, 1% pe zi este destul pentru Alice, si daca vrea sa retraga mai mult, poate cere ajutorul lui Bob. Daca codul lui Alice este folosit ilicit de altcineva, apeleaza la Bob pentru a muta fondurile pe un nou contract. Daca ea isi pierde codul, Bob va retrage fondurile in cele din urma. Daca Bob este rau intentionat, Alice oricum poate retrage de 20 de ori mai repede decat el. - -2) Crop insurance.Se poate face usor un “financial derivatives contract” folosind date de prognoza meteo in locul unui index de preturi. Daca un fermier in Iowa cumpara derivative achitate invers proportional bazat pe precipitatiile din Iowa si vine seceta, fermierul va primi automat bani; daca precipitatiile sunt abundente, fermierul va fi fericit ca recolta va prospera. - -3) Un decentrally managed data feed, care foloseste un sistem de votare proof-of-stake pentru a furniza o medie intre opiniile tuturor asupra pretului unui produs, vremea sau alte date relevante. - -4) Smart multisignature escrow. Bitcoin accepta contracte de tranzactii multisignature unde, de exemplu, 3 din 5 keys pot folosi fondurile. Ethereum permite mai multa granularitate; de exemplu, 4 din 5 pot cheltui toate fondurile, 3 din 5 pot folosi pana la 10% pe zi si 2 din 5 pot folosi pana la 0.5% pe zi. In plus, Ethereum multisig este asincron – doi membri isi pot inregistra semnaturile pe blockchain la perioade diferite, si ultima semnatura va trimite automat tranzactia. - -5) Peer-to-peer gambling. Orice numar de protocoale de gambling, precum Cyberdice, al lui Frank Stajano si Richard Clayton, poate fi implementat pe blockchain-ul Ethereum. Cel mai simplu gambling protocol este de fapt un contract de diferenta pe urmatorul block hash. De aici, servicii de gambling precum SatoshiDice pot fi imitate pe blockchain prin crearea unui contract unic pe pariu sau prin folosirea unui contract quasi-centralizat. - -6) O piata de capital on-chain pe scara larga. Prediction markets (piete de predictie) sunt de asemenea usor de implementat ca si consecinta triviala. - -7O piata on-chain descentralizata , care foloseste un sistem bazat pe identitate si reputatie. - -8) Dropbox Decentralizat. O metoda este aceea de a cripta un fisier, a organiza o schema Merkel, a depune o radacina Merkle intr-un contract alaturi de o anume suma de ether, si a distribui fisierul pe o retea secundara. In fiecare zi, contractul va alege o ramura aleatorie din acea schema Merkel in functie de block hash, si va acorda un numar X de ether primului nod care furnizeaza ramura catre contract, astfel incurajand nodurile sa stocheze datele pe termen lung, pentru a revendica premiul. Daca cineva incearca sa download-eze o portiune a fisierului, poate folosi un contract in stilul micropayment channel pentru a downloada fisierul de la cateva noduri, cate un block pe rand. - - -Cum functioneaza contractele? - -Un contract care face tranzactii este codat dupa cum urmeaza: - - [ - nonce, - '', - value, - [ - data item 0, - data item 1, - ... - ], - v, - r, - s - ] -Itemii data vor fi, in majoritatea cazurilor, coduri script(mai mult despre acest lucru , mai jos). Validarea tranzactiei crearii contractului se desfasoara dupa cum urmeaza: - -Deserializeaza tranzactia si extrage adresa expeditoare din semnatura sa. -Calculeaza taxa de tranzactie ca NEWCONTRACTFEE plus taxe de depozitare pentru cod.Verifica daca balanta creatorului este cel putin egala cu valoarea tranzactiei plus taxa. Daca nu, iese. -Ia ultimii 20 bytes ai sha3 hash ai codarii RLP a tranzactiei, realizand contractul. Daca un cont cu aceeasi adresa exista deja, se paraseste operatiunea. Altfel, creati contractul la acea adresa. -Se copiaza itemul data i pentru a depozita slotul i in contract pentru toti i in [0 ... n-1]unde n este numarul itemilor data din tranzactie, si initializeaza contractul cu valoarea tranzactiei ca fiind valoarea contractului. Se scade valoarea si taxa din balanta creatorului. - -Specificatii de limbaj - -Limbajul de scripting al contractului este un hibrid din limbajul de asamblare si din limbajul stack-based al Bitcoin-ului, mentinand un indicator de index care de obicei creste cu unu dupa fiecare operatie si proceseaza continuu operatia gasita la indicatorul de index curent. Toate opcodes sunt numere in gama[0 ... 63]; etichete mai departe in descrierea sa ca STOP, EXTRO si BALANCE se refera la valori specifice care sunt definite mai departe. Limbajul scripting are acces la tri feluri de memorie: - -Stack - o forma temporara de depozitare care este resetata pentru a goli lista de fiecare data cand un contract este executat. Operatiile , de obicei, adauga sau elimina valori la/de la varful stack-ului, astfel lungimea totala a unui stack va creste sau va scadea pe parcursul executarii programului. -Memory - un stoc temporar de valori/keys care este resetat la continutul tuturor zerourilor de fiecare data cand un contract este executat.Keys si valori in memorie sunt numere intregi in gama [0 ... 2^256-1] -Storage - un stoc persistent de valori/keys care initial este setat sa contina toate zerourile, exceptand anumite coduri script inserate la inceput cand contractul este creat. Valorile si keys aflate in storage sunt numere integrale aflate in gama [0 ... 2^256-1] -Oricand o tranzactie este trimisa catre un contract, contractul va executa codul sau scripting.Pasii precisi care sunt facuti atunci cand un contract primeste o tranzactie sunt urmatorii: - -Interpretarea Script-ului Contractelor - - -Balanta ether a contractului creste odata cu suma trimisa. -Indicatorul de index este setat la zero, si STEPCOUNT = 0 -Repeta la nesfarsit: -daca comanda de la indicatorul de index este STOP, invalida sau mai mare de 63, iesiti din bucla -setati MINERFEE = 0, VOIDFEE = 0 -setati STEPCOUNT <- STEPCOUNT + 1 -daca STEPCOUNT > 16, set MINERFEE <- MINERFEE + STEPFEE -verificati daca comanda este LOAD sau STORE. Daca este asa, setati MINERFEE <- MINERFEE + DATAFEE -vedeti daca comanda va modifica un camp de depozitare, sa spunem KEY din OLDVALUE in NEWVALUE. Lasati F(K,V)fie 0daca V == 0 altfel (len(K) + len(V)) * STORAGEFEE in bytes. Set VOIDFEE <- VOIDFEE - F(KEY,OLDVALUE) + F(KEY,NEWVALUE). Calcularea len(K) ignora leading zero bytes. -vedeti daca comanda este EXTRO sau BALANCE. Daca este asa, setati MINERFEE <- MINERFEE + EXTROFEE -verificati daca comanda este o operatie crypto.Daca este asa, setati MINERFEE <- MINERFEE + CRYPTOFEE -daca MINERFEE + VOIDFEE > CONTRACT.BALANCE, OPRITI-VA si iesiti din bucla -scadeti MINERFEE din balanta contractului si adaugati MINERFEE la un running counter care va fi daugat la balanta minerului odata ce toate tranzactiile sunt analizate. -setati DELTA = max(-CONTRACT.STORAGE_DEPOSIT,VOIDFEE) si CONTRACT.BALANCE <- CONTRACT.BALANCE - DELTA si CONTRACT.STORAGE_DEPOSIT <- CONTRACT.STORAGE_DEPOSIT + DELTA. Retineti ca DELTA poate fi pozitiva sau negativa; singura restrictie este aceea ca depozitul contractului nu poate merge sub zero. -rulati comanda -daca comanda nu a iesit cu o eroare, updatati indicatorul de index si intoarceti-va la inceputul buclei.Daca contractul a iesit cu o eroare, iesiti din bucla. Retineti ca un contract existent cu o eroare nu face tranzactia sau block-ul invalide; pur si simplu inseamna ca execturia contractului s-a oprit la mijlocul procesului. -In urmatoarele descrieri, S[-1], S[-2], etc reprezinta cei mai importanti, descrescator, itemi ai stack-ului. Opcode-urile individuale sunt definite dupa cum urmeaza: - -(0) STOP - opreste executia -(1) ADD - pops two items and pushes S[-2] + S[-1] mod 2^256 -(2) MUL - pops two items and pushes S[-2] * S[-1] mod 2^256 -(3) SUB - pops two items and pushes S[-2] - S[-1] mod 2^256 -(4) DIV - pops two items and pushes floor(S[-2] / S[-1]). If S[-1] = 0, opreste executia. -(5) SDIV - pops two items and pushes floor(S[-2] / S[-1]), but treating values above 2^255 - 1 as negative (ie. x -> 2^256 - x). If S[-1] = 0, halts execution. -(6) MOD - pops two items and pushes S[-2] mod S[-1]. If S[-1] = 0, halts execution. -(7) SMOD - pops two items and pushes S[-2] mod S[-1], but treating values above 2^255 - 1 as negative (ie. x -> 2^256 - x). If S[-1] = 0, halts execution. -(8) EXP - pops two items and pushes S[-2] ^ S[-1] mod 2^256 -(9) NEG - pops one item and pushes 2^256 - S[-1] -(10) LT - pops two items and pushes 1 if S[-2] < S[-1] else 0 -(11) LE - pops two items and pushes 1 if S[-2] <= S[-1] else 0 -(12) GT - pops two items and pushes 1 if S[-2] > S[-1] else 0 -(13) GE - pops two items and pushes 1 if S[-2] >= S[-1] else 0 -(14) EQ - pops two items and pushes 1 if S[-2] == S[-1] else 0 -(15) NOT - pops one item and pushes 1 if S[-1] == 0 else 0 -(16) MYADDRESS - pushes the contract's address as a number -(17) TXSENDER - pushes the transaction sender's address as a number -(18) TXVALUE - pushes the transaction value -(19) TXDATAN - pushes the number of data items -(20) TXDATA - pops one item and pushes data item S[-1], or zero if index out of range -(21) BLK_PREVHASH - pushes the hash of the previous block (NOT the current one since that's impossible!) -(22) BLK_COINBASE - pushes the coinbase of the current block -(23) BLK_TIMESTAMP - pushes the timestamp of the current block -(24) BLK_NUMBER - pushes the current block number -(25) BLK_DIFFICULTY - pushes the difficulty of the current block -(26) BLK_NONCE - pushes the nonce of the current block -(27) BASEFEE - pushes the base fee (x as defined in the fee section below) -(32) SHA256 - pops two items, and then constructs a string by taking the ceil(S[-1] / 32) items in memory from index S[-2] to (S[-2] + ceil(S[-1] / 32) - 1) mod 2^256, prepending zero bytes to each one if necessary to get them to 32 bytes, and takes the last S[-1] bytes. Pushes the SHA256 hash of the string -(33) RIPEMD160 - works just like SHA256 but with the RIPEMD-160 hash -(34) ECMUL - pops three items. If (S[-2],S[-1]) are a valid point in secp256k1, including both coordinates being less than P, pushes (S[-2],S[-1]) * S[-3], using (0,0) as the point at infinity. Otherwise, pushes (2^256 - 1, 2^256 - 1). Note that there are no restrictions on S[-3] -(35) ECADD - pops four items and pushes (S[-4],S[-3]) + (S[-2],S[-1]) if both points are valid, otherwise (2^256 - 1,2^256 - 1) -(36) ECSIGN - pops two items and pushes (v,r,s) as the Electrum-style RFC6979 deterministic signature of message hash S[-1] with private key S[-2] mod N with 0 <= v <= 3 -(37) ECRECOVER - pops four items and pushes (x,y) as the public key from the signature (S[-3],S[-2],S[-1]) of message hash S[-4]. If the signature has invalid v,r,s values (ie. v not in [27,28], r not in [0,P], s not in [0,N]), return (2^256 - 1,2^256 - 1) -(38) ECVALID - pops two items and pushes 1 if (S[-2],S[-1]) is a valid secp256k1 point (including (0,0)) else 0 -(39) SHA3 - works just like SHA256 but with the SHA3 hash, 256 bit version -(48) PUSH - pushes the item in memory at the index pointer + 1, and advances the index pointer by 2. -(49) POP - pops one item. -(50) DUP - pushes S[-1] to the stack. -(51) SWAP - pops two items and pushes S[-1] then S[-2] -(52) MLOAD - pops two items and sets the item in memory at index S[-1] to S[-2] -(53) MSTORE - pops two items and sets the item in memory at index S[-1] to S[-2] -(54) SLOAD - pops two items and sets the item in storage at index S[-1] to S[-2] -(55) SSTORE - pops two items and sets the item in storage at index S[-1] to S[-2] -(56) JMP - pops one item and sets the index pointer to S[-1] -(57) JMPI - pops two items and sets the index pointer to S[-2] only if S[-1] is nonzero -(58) IND - pushes the index pointer -(59) EXTRO - pops two items and pushes memory index S[-2] of contract S[-1] -(60) BALANCE - pops one item and pushes balance of the account with that address, or zero if the address is invalid -(61) MKTX - pops four items and initializes a transaction to send S[-2] ether to S[-1] with S[-3] data items. Takes items in memory from index S[-4] to index (S[-4] + S[-3] - 1) mod 2^256 as the transaction's data items. -(63) SUICIDE - pops one item, destroys the contract and clears all storage, sending the entire balance plus the contract deposit to the account at S[-1] -Dupa cum am mentionat si mai sus, intentia nu este ca oamenii sa scrie script-uri direct in codul script al Ethereum, ci, vom pune la dispozitie compilatoare pentru a genera ES din limbaje de un nivel mai inalt.Primul limbaj suportat va fi cel mai probabil limbajul simplu C-like utilizat in descrierile de mai sus, iar al doilea va fi mai un limbaj de prima clasa mai complet cu suport pentru matrice si pentru siruri de lungimi arbitrare.Compilarea limbajului C este destul de simpla in ceea ce priveste eficienta compilatoarelor: variabilelor le pot fi repartizate in index de memorie, si formarea unei expresii aritmetice implica, esential, convertirea la reverse Polish notation (eg. (3 + 5) * (x + y) -> PUSH 3 PUSH 5 ADD PUSH 0 MLOAD PUSH 1 MLOAD ADD MUL). Limbajul de prima clasa este mai implicat datorita definirii variabile a domeniului, dar problema este cu toate acestea usor de manuit. Solutia posibila va fi mentinerea unei liste linked a frame-urilor stack in memorie, dand fiecarui stack frame N sloturi de memorie unde N este numarul total de nume de variabile distincte in program.Accesul varialilelor va consta in cautarea in lista stck frame pana cand un frame va contine un indicator spre variabila, copiind indicatorul in varful stack-ului pentru scopuri de memorare, si returnarea valorii la indicator.Totusi, acestea sunt griji pe termen lung; compilarea este separata de protocolul in sine, si, astfel, va fi pobila continuarea cercetarii strategiilor de compilare si dupa ce reteaua este in functiune. - - -Taxe - -In Bitcoin, nu exista taxe obligatorii pe tranzactie. Tranzactiile pot include taxe platite catre mineri, si acestia pot decide ce taxe vor accepta. In Bitcoin, un astfel de mecanism este imperfect; nevoia unui block size limit de 1 MB pe langa mecanismul de taxare ilustreaza acest fapt. In Ethereum, datorita Turing-completeness, un sistem de taxare voluntara ar fi catastrofal. In loc, Ethereum va avea un sistem de taxe obligatorii, care includ taxele de tranzactie si 6 taxe pentru calculele contractului. - -Taxele sunt setate astfel: - -TXFEE (100x) - taxa pentru a trimite o tranzactie -NEWCONTRACTFEE (100x) - ftaxa pentru crearea unui nou contract; nu include taxa de stocare a fiecarui item in script code -STEPFEE (1x) - taxa pentru fiecare pas computational ce urmeaza dupa primii 16 in executia contractului -STORAGEFEE (5x) - taxa per-byte pentru a adauga la stocarea contractului. Taxa de stocare este singura taxa care nu este platita catre un miner, si e inapoiata cand spatiul de stocare folosit de un contract e redus sau eliminat. -DATAFEE (20x) - taxa pentru accesarea sau setarea memoriei unui contract, in interiorul acelui contract -EXTROFEE (40x) - taxa pentru accesarea memoriei dintr-un alt contract in alt contract -CRYPTOFEE (20x) - taxa pentru folosirea oricarei operatiuni criptografice -Coeficientii vor fi revizuiti pe masura ce creste numarul datelor despre costul computational al fiecarei operatii. Partea cea mai dificila va fi setarea valoarea lui x.In prezent avem in vedere doua solutii principale: - -Faceti x proportional cu radacina patrata a dificultatii, astfel ca x = floor(10^21 / floor(difficulty ^ 0.5)). Aceasta ajusteaza automat taxele pe masura ce valoarea ether creste, si scade taxele pe masura ce calculatoarele devin mai performante, datorita legii lui Moore. -Folositi votarea proof-of-stake pentru a stabili taxele. Teoretic, partile interesate nu beneficiaza direct de cresterea sau diminuarea taxelor, deci stimulentele ar fi luarea deciziilor pentru a maximiza valoarea retelei.. -O solutie hibrida este de asemenea posibila, prin folosirea votarii proof-of-stake, dar avand mecanismul inversului radacinii patrate ca metoda initiala. - - -Concluzie - -Filosofia de baza a protocolului Ethereum este in multe feluri diferita de cea din spatele multor feluri de cryptocurrency actuale. Alte cryptocurrencies urmaresc sa creasca complexitatea si sa mareasca numarul de "functii"; Ethereum, pe de alta parte, elimina din functii. Protocolul nu "suporta" tranzactii multisignature, multiple input-uri si output-uri, hash codes, lock times sau multe alte functii oferite chiar si de Bitcoin. In schimb, complexitatea vine dintr-un scripting language Turing universal, care poate fi folosit pentru a crea orice functie care poate fi descrisa matematic prin mecanismul contractului. Ca rezultat, avem un protocol cu un potential unic; departe de a fi un protocol limitat, cu un singur scop, intentionat pentru un numar specific de aplicatii in stocarea de date, gambling sau finante, Ethereum este open-ended in esenta, si avem motive sa credem ca este foarte potrivit pentru a servi ca fundatie pentru un numar mare de protocoale financiare si non-financiare in anii ce vor urma. - - -Referinte si Documentare - -Colored coins whitepaper: https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit -Mastercoin whitepaper: https://github.com/mastercoin-MSC/spec -Decentralized autonomous corporations, Bitcoin Magazine: http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/ -Smart property: https://en.bitcoin.it/wiki/Smart_Property -Smart contracts: https://en.bitcoin.it/wiki/Contracts -Simplified payment verification: https://en.bitcoin.it/wiki/Scalability#Simplifiedpaymentverification -Merkle trees: http://en.wikipedia.org/wiki/Merkle_tree -Patricia trees: http://en.wikipedia.org/wiki/Patricia_tree -Bitcoin whitepaper: http://bitcoin.org/bitcoin.pdf -GHOST: http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf -StorJ and Autonomous Agents, Jeff Garzik: http://garzikrants.blogspot.ca/2013/01/storj-and-bitcoin-autonomous-agents.html -Mike Hearn on Smart Property at Turing Festival: http://www.youtube.com/watch?v=Pu4PAMFPo5Y -Ethereum RLP: http://wiki.ethereum.org/index.php/RLP -Ethereum Merkle Patricia trees: http://wiki.ethereum.org/index.php/Patricia_Tree -Ethereum Dagger: http://wiki.ethereum.org/index.php/Dagger -Ethereum C-like language: http://wiki.ethereum.org/index.php/CLL -Ethereum Slasher: http://blog.ethereum.org/?p=39/slasher-a-punitive-proof-of-stake-algorithm -Scrypt parameters: https://litecoin.info/User:Iddo/ComparisonbetweenLitecoinandBitcoin#SHA256miningvsscryptmining -Litecoin ASICs: https://axablends.com/merchants-accepting-bitcoin/litecoin-discussion/litecoin-scrypt-asic-miners/ \ No newline at end of file diff --git a/sendTransaction-return-value-proposal.md b/sendTransaction-return-value-proposal.md deleted file mode 100644 index 0a4b21de0..000000000 --- a/sendTransaction-return-value-proposal.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -name: SendTransaction Return Value Proposal -category: ---- - -After talking to Marek we came to the conclusion, that the current return value of `eth_sendTransaction` is not enough to be able to work with self send transactions. - -If you send a contract creation transaction, you get the contract address back, but not the transaction hash. - -Additional with the new proposal, we could even let non-constant contract functions return values, like gavin wanted to do it in https://github.com/ethereum/dapp-bin/blob/master/wallet/wallet2.sol#L237 (Currently thats impossible and that contract would be wrong) - -## Proposal - -Instead of returning the hash or a contract address lets return a object contain everything: - -```js -{ - transactionHash: '0x234567..', - contractAddress: '0x123456' // or null - returnValue: '0x342567' // or null -} -``` \ No newline at end of file diff --git a/web.js-0.9.md b/web.js-0.9.md deleted file mode 100644 index ad77e2330..000000000 --- a/web.js-0.9.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -name: Web.js 0.9 -category: ---- - -Web3.js 0.9 changes - -I would like to apply KISS principle to web3.js. I used the library recently much more and I realised that we are doing to many things implicitly. eg: - -1, newFilter it should either get all logs or poll for new logs. It shouldn't do both in the same time. In my story, I don't want to poll for filter changes, but I want to get all logs between block X and Y. Same as caktux here: https://github.com/ethereum/web3.js/issues/250 - - examples of new solution - - 1st. - - ``` -var x = web3.eth.filter(...); // sync: eth_newFilter -x.watch(function (err, log) { // async poll: eth_getFilterChanges - -}) - ``` - - - 2nd. - - - ``` -web3.eth.filter(..., function (err, x) { // async: eth_newFilter - x.watch(function (err, log) { // async poll: eth_getFilterChanges - - }) -}) - - ``` - - 3rd. - - - ``` -var x = web3.eth.filter(...) // sync: eth_newFilter -var logs = x.logs(); // sync: eth_getFilterLogs - ``` - - 4th. - ``` -var x = web3.eth.filter(...) // sync: eth_newFilter -var logs = x.logs(function (err, logs) { // sync: eth_getFilterLogs - -} - ``` diff --git "a/\303\220\316\236Vp2p-Wire-Protocol.md" "b/\303\220\316\236Vp2p-Wire-Protocol.md" deleted file mode 100644 index 4ac80109d..000000000 --- "a/\303\220\316\236Vp2p-Wire-Protocol.md" +++ /dev/null @@ -1,90 +0,0 @@ ---- -name: DEV P2P Wire Protocol -category: ---- - -Peer-to-peer communications between nodes running Ethereum/Whisper/&c. clients are designed to be governed by a simple wire-protocol making use of existing ÐΞV technologies and standards such as [RLP](https://github.com/ethereum/wiki/wiki/RLP) wherever practical. - -This document is intended to specify this protocol comprehensively. - -### Low-Level - -ÐΞVp2p nodes may connect to each other over TCP only. Peers are free to advertise and accept connections on any port(s) they wish, however, a default port on which the connection may be listened and made will be 30303. - -Though TCP provides a connection-oriented medium, ÐΞVp2p nodes communicate in terms of packets. These packets are formed as a 4-byte synchronisation token (0x22400891), a 4-byte "payload size", to be interpreted as a big-endian integer and finally an N-byte RLP-serialised data structure, where N is the aforementioned "payload size". To be clear, the payload size specifies the number of bytes in the packet ''following'' the first 8. - -### Payload Contents - -There are a number of different types of payload that may be encoded within the RLP. This ''type'' is always determined by the first entry of the RLP, interpreted as an integer. - -ÐΞVp2p is designed to support arbitrary sub-protocols (aka _capabilities_) over the basic wire protocol. Each sub-protocol is given as much of the message-ID space as it needs (all such protocols must statically specify how many message IDs they require). On connection and reception of the `Hello` message, both peers have equivalent information about what subprotocols they share (including versions) and are able to form consensus over the composition of message ID space. - -Message IDs are assumed to be compact from ID 0x10 onwards (0x00-0x10 is reserved for ÐΞVp2p messages) and given to each shared (equal-version, equal name) sub-protocol in alphabetic order. Sub-protocols that are not shared are ignored. If multiple versions are shared of the same (equal name) sub-protocol, the numerically highest wins, others are ignored. - -### P2P - -**Hello** -[`0x00`: `P`, `p2pVersion`: `P`, `clientId`: `B`, [[`cap1`: `B_3`, `capVersion1`: `P`], [`cap2`: `B_3`, `capVersion2`: `P`], `...`], `listenPort`: `P`, `nodeId`: `B_64`] First packet sent over the connection, and sent once by both sides. No other messages may be sent until a Hello is received. -* `p2pVersion` Specifies the implemented version of the P2P protocol. Now must be 1. -* `clientId` Specifies the client software identity, as a human-readable string (e.g. "Ethereum(++)/1.0.0"). -* `cap` Specifies a peer capability name as a length-3 ASCII string. Current supported capabilities are `eth`, `shh`. -* `capVersion` Specifies a peer capability version as a positive integer. Current supported versions are 34 for `eth`, and 1 for `shh`. -* `listenPort` specifies the port that the client is listening on (on the interface that the present connection traverses). If 0 it indicates the client is not listening. -* `nodeId` is the Unique Identity of the node and specifies a 512-bit hash that identifies this node. - -**Disconnect** -[`0x01`: `P`, `reason`: `P`] Inform the peer that a disconnection is imminent; if received, a peer should disconnect immediately. When sending, well-behaved hosts give their peers a fighting chance (read: wait 2 seconds) to disconnect to before disconnecting themselves. -* `reason` is an optional integer specifying one of a number of reasons for disconnect: - * `0x00` Disconnect requested; - * `0x01` TCP sub-system error; - * `0x02` Breach of protocol, e.g. a malformed message, bad RLP, incorrect magic number &c.; - * `0x03` Useless peer; - * `0x04` Too many peers; - * `0x05` Already connected; - * `0x06` Incompatible P2P protocol version; - * `0x07` Null node identity received - this is automatically invalid; - * `0x08` Client quitting; - * `0x09` Unexpected identity (i.e. a different identity to a previous connection/what a trusted peer told us). - * `0x0a` Identity is the same as this node (i.e. connected to itself); - * `0x0b` Timeout on receiving a message (i.e. nothing received since sending last ping); - * `0x10` Some other reason specific to a subprotocol. - -**Ping** -[`0x02`: `P`] Requests an immediate reply of `Pong` from the peer. - -**Pong** -[`0x03`: `P`] Reply to peer's `Ping` packet. - -**NotImplemented (was GetPeers)** -[`0x04`: `...`] - -**NotImplemented (was Peers)** -[`0x05`: `...`] - -### Node identity and reputation - -In a later version of this protocol, node ID will become the public key. Nodes will have to demonstrate ownership over their ID by interpreting a packet encrypted with their node ID (or perhaps signing a random nonce with their private key). - -A proof-of-work may be associated with the node ID through the big-endian magnitude of the public key. Nodes with a great proof-of-work (public key of lower magnitude) may be given preference since it is less likely that the node will alter its ID later or masquerade under multiple IDs. - -Nodes are free to store ratings for given IDs (how useful the node has been in the past) and give preference accordingly. Nodes may also track node IDs (and their provenance) in order to help determine potential man-in-the-middle attacks. - -Clients are free to mark down new nodes and use the node ID as a means of determining a node's reputation. In a future version of this wire protocol, n - -### Example Packets - -`0x22400891000000088400000043414243` - -A Hello packet specifying the client id is "ABC". - -Peer 1: `0x22400891000000028102` - -Peer 2: `0x22400891000000028103` - -A Ping and the returned Pong. - -### Session Management - -Upon connecting, all clients (i.e. both sides of the connection) must send a `Hello` message. Upon receiving the `Hello` message and verifying compatibility of the network and versions, a session is active and any other P2P messages may be sent. - -At any time, a Disconnect message may be sent. \ No newline at end of file diff --git "a/\320\240\321\203\320\272\320\276\320\262\320\276\320\264\321\201\321\202\320\262\320\276-\320\277\320\276-Solidity.md" "b/\320\240\321\203\320\272\320\276\320\262\320\276\320\264\321\201\321\202\320\262\320\276-\320\277\320\276-Solidity.md" deleted file mode 100644 index 1ab9395db..000000000 --- "a/\320\240\321\203\320\272\320\276\320\262\320\276\320\264\321\201\321\202\320\262\320\276-\320\277\320\276-Solidity.md" +++ /dev/null @@ -1,1256 +0,0 @@ -_исходный текст [Solidity Tutorial](https://ethereum.github.io/solidity/docs/home/), 05.10.2015_ -*** -Solidity - это высокоуровневый язык для виртуальной машины Ethereum с синтаксисом, похожим на JavaScript. Это учебное руководство обеспечивает основное введение в Solidity и предполагает некоторое знание Виртуальной машины Ethereum и программирования в целом. Оно не касается таких функций как [естественная спецификация языка](https://github.com/ethereum/wiki/wiki/Solidity-Tutorial/Ethereum-Natural-Specification-Format) или формальная верификация и не является заключительной спецификацией языка. - -Можно начать использовать [Solidity в браузере](http://chriseth.github.io/cpp-ethereum) без потребности загружать или компилировать что-либо. Это приложение только поддерживает компиляцию - если Вы хотите выполнить код или ввести его в блокчейн, необходимо использовать клиент, такой как например [Geth](https://github.com/ethereum/go-ethereum) или [AlethZero](https://github.com/ethereum/alethzero). - - -**Быстрые ссылки:** - -- [Шпаргалка](#cheatsheet) -- [Подсказки и Приемы](#tips-and-tricks) - -**Оглавление** - - -- [Некоторые примеры](#Некоторые-примеры) - - [Хранилище](#Хранилище) - - [Пример подвалюты](#Пример-подвалюты) -- [Разметка исходного файла Solidity](#Разметка-исходного-файла-solidity) -- [Структура контракта Solidity](#Структура-контракта-solidity) -- [Типы](#Типы) - - [Элементарные типы (типы значений)](#Элементарные-типы-типы-значений) - - [Операторы, включающие LValues](#Операторы-включающие-lvalue) - - [Преобразования между элементарными типами](#conversions-between-elementary-types) - - [Неявные преобразования](#implicit-conversions) - - [Явные преобразования](#explicit-conversions) - - [Тип возвращаемых значений](#type-deduction) - - [Функции на адресах](#functions-on-addresses) - - [Перечисления(Enums)](#enums) - - [Ссылочные типы](#reference-types) - - [Расположение данных](#data-location) - - [Массивы](#arrays) - - [Структуры](#structs) -- [Синтаксический сахар и глобально доступные переменные](#syntactic-sugar-and-globally-available-variables) - - [Эфир и единицы измерения времени](#ether-and-time-units) - - [Специальные переменные и функции](#special-variables-and-functions) - - [Блок и свойства транзакции](#block-and-transaction-properties) - - [Криптографические функции](#cryptographic-functions) - - [Касательно контракта](#contract-related) -- [Управляющие структуры](#control-structures) - - [Вызовы функции](#function-calls) - - [Внутренние вызовы функции](#internal-function-calls) - - [Внешние вызовы функции](#external-function-calls) - - [Названные и дополнительные параметры функции](#named-and-optional-function-parameters) - - [Порядок оценки выражений](#order-of-evaluation-of-expressions) - - [Присвоение](#assignment) - - [Исключения](#exceptions) -- [Договоры](#contracts) - - [Взаимодействие через интерфейс с другими контрактами](#interfacing-with-other-contracts) - - [Библиотеки](#libraries)_(todo)_ - - [Параметры конструктора](#constructor-arguments) - - [Наследование контракта](#contract-inheritance) - - [Параметры для конструкторов базового контракта](#arguments-for-base-constructors) - - [Множественное наследование и линеаризация](#multiple-inheritance-and-linearization) - - [Абстрактные контракты](#abstract-contracts) - - [Спецификаторы видимости](#visibility-specifiers) - - [Функции доступа](#accessor-functions) - - [Функции нейтрализации](#fallback-functions) - - [Функции модификаторов](#function-modifiers) - - [Контракты](#constants) - - [События](#events) - - [Дополнительные ресурсы для понимания событий:](#additional-resources-for-understanding-events) -- [Разное](#miscellaneous) - - [Разметка переменных состояния в хранилище](#layout-of-state-variables-in-storage) - - [Скрытые особенности](#esoteric-features) - - [Внутреннее - Оптимизатор](#internals-the-optimizer) - - [Использование компилятора командной строки](#using-the-commandline-compiler) - - [Подсказки и Приемы](#tips-and-tricks) - - [Ловушки](#pitfalls) - - [Шпаргалка](#cheatsheet) - - [Глобальные переменные](#global-variables) - - [Спецификаторы видимости для функции](#function-visibility-specifiers) - - [Модификаторы](#modifiers) - - [Типы](#types) - - -*** -# Некоторые примеры - -Давайте начнем с некоторых примеров. Позже мы рассмотрим все подробнее. - -## Хранилище - -```js -contract SimpleStorage { - uint storedData; - function set(uint x) { - storedData = x; - } - function get() constant returns (uint retVal) { - return storedData; - } -} -``` - -`uint storedData` объявляет переменную состояния, названную storedData типа uint (целое без знака 256 битов), чья позиция в хранилище автоматически решается компилятором. -Функции `set` и `get` используются для изменения и получения значения переменной. - -## Пример подвалюты - -```js -contract Coin { - address minter; - mapping (address => uint) balances; - - event Send(address from, address to, uint value); - - function Coin() { - minter = msg.sender; - } - function mint(address owner, uint amount) { - if (msg.sender != minter) return; - balances[owner] += amount; - } - function send(address receiver, uint amount) { - if (balances[msg.sender] < amount) return; - balances[msg.sender] -= amount; - balances[receiver] += amount; - Send(msg.sender, receiver, amount); - } - function queryBalance(address addr) constant returns (uint balance) { - return balances[addr]; - } -} -``` - -Настоящий контракт представляет некоторые новые понятия. Одно из них тип address-а, который является 160 битовым значением, не позволяющим арифметические операции. -Кроме того, тип переменной состояния `balances` отображает адреса на целие числа без знака. Отображения можно представить как хеш-таблицу виртуально инициализированную таким образом, чтобы каждый возможный ключ существовал и отображался в значении, байт-представление которого является нулями. Специальная функция `Coin` является конструктором, который выполняют во время создания контракта и её нельзя вызвать впоследствии. Она хранит адрес лица, создающего договор вместе с `tx` и `block`, `msg` является волшебной глобальной переменной, содержащей некоторые свойства, предоставляющие доступ к миру за пределами контракта. -Функция `queryBalance` объявлена как постоянная и таким образом не позволяется изменить состояние контракта(обратите внимание на то, что это не принудительно). -В Solidity возвращаемые параметры наименованы и по существу создают локальную переменную. Таким образом для возврата баланса мы могли бы просто использовать `balance = balances[addr];` без какого-либо `return`. Такие события, как `Send`, позволяют внешним клиентам искать в блокчейне более эффективно. -Если событие вызывается как в функция `Send`, этот факт будет сохранен и отображён в блокчейне, мы узнаем больше об этом позже. - -# Разметка исходного файла Solidity - -Исходный файл Solidity может содержать произвольное число контрактов. -На **другие исходные файлы** можно сослаться с помощью `import "filename";`, символы, определенные там, также будут доступны в текущем исходном файле. -Обратите внимание на то, что компилятор в браузере поддерживает не больше одного файла и если Вы используете компилятор командной строки, необходимо явно указать все файлы, которые Вы будете использовать в качестве параметров, компилятор не будет ничего искать в Вашей файловой системе самостоятельно. - -**Комментарии** однострочные комментарии (`//`) и многострочные комментарии (`/*...*/`)возможны, в то время как тройная наклонная черта (`///`) справа перед объявлениями функции производит комментарий -[NatSpec](Ethereum-Natural-Specification-Format) (Комментарии NatSepc не освещены здесь). - -# Структура контракта Solidity - -Контракты в Solidity - то же, что и классы в объектно-ориентированных языках. Они могут содержать так называемые переменные состояния, которые постоянно хранятся в хранилище вместе с контрактом и функциями, указателями входа для работы с этими переменными состояния. Кроме переменных состояния, существуют также локальные переменные, объявленные в функциях, содержание которых очищается как только поток управления возвращается из функции. - -# Типы - -Solidity является статически типизированным языком и это означает, что тип каждой переменной(состояния и локальных) должен быть указан(или по крайней мере известен - см. [Дедукция типа](#Дедукция-типа) ниже) во время компиляции. Solidity предоставляет несколько элементарных типов, которые могут быть объединены в составные типы. - -## Элементарные типы (типы значений) - -Следующие типы также называют типами значения, потому что переменные этих типов будут всегда передаваться по значению, т.е. они всегда копируются, когда они используются в качестве аргументов функции или в присвоениях. - -**Логический тип** -`bool`: Возможные значения константы `true`, `false` - -Операторы: -`!` (логическое отрицание) `&&` (логическая конъюнкция, "and"), `||` (логическая дизъюнкция, "or"), `==` (равенство) and `!=` (неравенство). Операторы `||` и `&&` применяют обычные правила short-circuiting. Это означает, что в выражении `f(x) || g(y)`, если `f(x)` оценивается как `true`, `g(y)` не будет рассмотрен даже если это может иметь побочные эффекты. - -**Числа** -`int•` / `uint•`: Целые числа со знаком и без знака различных размеров. Ключевые слова `uint8` до `uint256` с шагом `8` (Целые числа без знака с 8 до максимум 256 битов) и `int8` до `int256`. `uint` и `int` являются псевдонимами для `uint256` и `int256`, соответственно. - -Операторы: -Сравнения: `<=`, `<`, `==`, `!=`, `>=`, `>` (возвращают `bool`) -Битовые операции: `&`, `|`, `^` (Побитовое исключающее ИЛИ), `~` (Побитовое отрицание) -Арифметические операторы: `+`, `-`, унарный `-`, унарный `+`, `*`, `/`, `%` (Деление с остатком (деление по модулю) ), `**` (Возведение в степень) - -**Адресный тип** -`address`: Содержит 20 байтное значение (размер адреса Ethereum). Адресный тип также имеет члены(см. [Функции на адреса](#Функции-на-адреса)) и служит основой для всех контрактов. - -Операторы: -`<=`, `<`, `==`, `!=`, `>=` и `>`. - -**Массивы фиксированного размера** -`bytes1`, `bytes2`, `bytes3`, ..., `bytes32`: массивы фиксированного размера, `byte` является псевдонимом для `bytes1`. - -Операторы: -Сравнения: `<=`, `<`, `==`, `!=`, `>=`, `>` (возвращают `bool`) -Битовые операции: `&`, `|`, `^` (Побитовое исключающее ИЛИ), `~` (Побитовое отрицание) - -**Динамично измеряемые массивы** -`bytes`: динамично измеряемый массив, см. [Массивы](#массивы). Не является типом значения! -`string`: динамично измеряемая UTF8-кодированная строка, см. [Массивы](#массивы). Не является типом значения! - -**Целочисленные Литералы** -Целочисленные литералы являются целыми числами произвольной точности, пока они не используются вместе с не-литералом. В `var x = 1 - 2;`, например, `1 - 2` имеет занчение `-1`, которое присваивается `x` и таким образом `x` получает тип `int8` -- наименьший тип который может хранить `-1`, несмотря на то, что естественные типы `1` и `2` фактически `uint8`. -Возможно даже временно превысить максимум 256 битов до тех пор пока для вычисления используются целочисленные литералы: `var x = (0xffffffffffffffffffff * 0xffffffffffffffffffff) * 0;` Здесь, `x` будет иметь значение `0` и таким образом тип `uint8`. - -**Строковые Литералы** -Строковые литералы записываются с двойными кавычками(`"abc"`). Как с целочисленными литералами, тип может варьироваться, но они неявно конвертируемы в `bytes•` если помещаются, в `bytes` и в `string`. - -## Операторы, включающие LValue - -**Операторы инкремента/декремента** -Если `a` LValue (т.е. переменная или что-то, что может быть присвоено), следующие операторы доступны как сокращения: -`a += e` эквивалентен `a = a + e`. Операторы `-=`, `*=`, `/=`, `%=`, `a |=`, `&=` и `^=` определяются соответственно. `a++` и `a--` эквивалентны `a += 1` / `a -= 1`, но само выражение все еще имеет предыдущее значение `a`. Напротив, `--a` и `++a` имеют тот же эффект, но возвращяют значения после изменения. - -**delete** -`delete a` присваивает `a` начальное значения для типа. Т.е. для целых чисел это `a = 0`, но он также может использоваться в массивах, где он присваивает длине динамического массива `0`, а статическому - массив той же длины где элементы имеют начальные значения. Для структур он присваивает переменной структуру со сбрасыванием значений для всех элементов. - -`delete` не имеет никакого эффекта на соответствиях(mappings)(поскольку ключи соответствий могут быть произвольными и обычно неизвестны). Таким образом, при удалении структуры, значения всех элементов кроме соответствий будут сброшены(рекурсивно для членов кроме соодветсвий). Однако отдельные ключи и то на что они отображаются, могут быть удалены. - -Важно отметить, что `delete a`, в действительности ведет себя как присвоение на `a`, т.е. хранит новый объект в `a`. -```js -contract DeleteExample { - uint data; - uint[] dataArray; - function f() { - uint x = data; - delete x; // x = 0, не влияет на data - delete data; // data = 0, не влияет на x, каторая все еще содержит копию - uint[] y = dataArray; - delete dataArray; // обнуляет dataArray.length, но поскольку uint[] сложный объект, также - // затронут y, который является псевдонимом к объекту хронилища. - // С другой стороны: «delete y», не действительнo, так как присвоение локальным переменным - // ссылающимся на объекты хронилища может быть сделано только из существующих объектов хронилища. - } -} -``` - -## Conversions between Elementary Types - -### Implicit Conversions - -If an operator is applied to different types, the compiler tries to -implicitly convert one of the operands to the type of the other (the same is -true for assignments). In general, an implicit conversion between value-types -is possible if it -makes sense semantically and no information is lost: `uint8` is convertible to -`uint16` and `int128` to `int256`, but `int8` is not convertible to `uint256` -(because `uint256` cannot hold e.g. `-1`). -Furthermore, unsigned integers can be converted to bytes of the same or larger -size, but not vice-versa. Any type that can be converted to `uint160` can also -be converted to `address`. - -### Explicit Conversions - -If the compiler does not allow implicit conversion but you know what you are -doing, an explicit type conversion is sometimes possible: - -```js -int8 y = -3; -uint x = uint(y); -``` - -At the end of this code snippet, `x` will have the value `0xfffff..fd` (64 hex -characters), which is -3 in two's complement representation of 256 bits. - -If a type is explicitly converted to a smaller type, higher-order bits are -cut off: - -```js -uint32 a = 0x12345678; -uint16 b = uint16(a); // b will be 0x5678 now -``` - -### Type Deduction - -For convenience, it is not always necessary to explicitly specify the type of a -variable, the compiler automatically infers it from the type of the first -expression that is assigned to the variable: -```js -uint20 x = 0x123; -var y = x; -``` -Here, the type of `y` will be `uint20`. Using `var` is not possible for function -parameters or return parameters. - -Beware that currently, the type is only deduced from the first assignment, so -the loop in the following snippet is infinite, as `i` will have the type -`uint8` and any value of this type is smaller than `2000`. -```js -for (var i = 0; i < 2000; i++) -{ - // do something -} -``` - -## Functions on addresses - -It is possible to query the balance of an address using the property `balance` -and to send Ether (in units of wei) to an address using the `send` function: - -```js -address x = 0x123; -address myAddress = this; -if (x.balance < 10 && myAddress.balance >= 10) x.send(10); -``` - -Beware that if `x` is a contract address, its code (more specifically: its fallback function, if present) will be executed together with the `send` call (this is a limitation of the EVM and cannot be prevented). If that execution runs out of gas or fails in any way, the Ether transfer will be reverted. In this case, `send` returns `false`. - -Furthermore, to interface with contracts that do not adhere to the ABI (like the classic NameReg contract), -the function `call` is provided which takes an arbitrary number of arguments of any type. These arguments are ABI-serialized (i.e. also padded to 32 bytes). One exception is the case where the first argument is encoded to exactly four bytes. In this case, it is not padded to allow the use of function signatures here. - -```js -address nameReg = 0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2; -nameReg.call("register", "MyName"); -nameReg.call(bytes4(sha3("fun(uint256)")), a); -``` - -`call` returns a boolean indicating whether the invoked function terminated (`true`) or caused an EVM exception (`false`). It is not possible to access the actual data returned (for this we would need to know the encoding and size in advance). - -In a similar way, the function `callcode` can be used: The difference is that only the code of the given address is used, all other aspects (storage, balance, ...) are taken from the current contract. The purpose of `callcode` is to use library code which is stored in another contract. The user has to ensure that the layout of storage in both contracts is suitable for callcode to be used. - -Both `call` and `callcode` are very low-level functions and should only be used as a *last resort* as they break the type-safety of Solidity. - -Note that contracts inherit all members of address, so it is possible to query the balance of the -current contract using `this.balance`. - -## Enums - -Enums are one way to create a user-defined type in Solidity. They are explicitly convertible -to and from all integer types but implicit conversion is not allowed. - -```js -contract test { - enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill } - ActionChoices choice; - ActionChoices constant defaultChoice = ActionChoices.GoStraight; - function setGoStraight() - { - choice = ActionChoices.GoStraight; - } - // Since enum types are not part of the ABI, the signature of "getChoice" - // will automatically be changed to "getChoice() returns (uint8)" - // for all matters external to Solidity. The integer type used is just - // large enough to hold all enum values, i.e. if you have more values, - // `uint16` will be used and so on. - function getChoice() returns (ActionChoices) - { - return choice; - } - function getDefaultChoice() returns (uint) - { - return uint(defaultChoice); - } -} -``` - -## Reference Types - -Complex types, i.e. types which do not always fit into 256 bits have to be handled -more carefully than the value-types we have already seen. Since copying -them can be quite expensive, we have to think about whether we want them to be -stored in memory (which is not persisting) or storage (where the state -variables are held). - -### Data location - -Every complex type, i.e. *arrays* and *structs*, has an additional -annotation, the "data location", about whether it is stored in memory or in storage. Depending on the -context, there is always a default, but it can be overridden by appending -either `storage` or `memory` to the type. The default for function parameters (including return parameters) is `memory`, the default for local variables is `storage` and the location is forced -to `storage` for state variables (obviously). - -There is also a third data location, "calldata" which is a non-modifyable -non-persistent area whether function arguments are stored. Function parameters -(not return parameters) of external functions are forced to "calldata" and -it behaves mostly like memory. - -Data locations are important because they change how assignments behave: -Assignments between storage and memory and also to a state variable (even from other state variables) -always create an independent copy. -Assignments to local storage variables only assign a reference though, and -this reference always points to the state variable even if the latter is changed -in the meantime. -On the other hand, assignments from a memory stored reference type to another -memory-stored reference type does not create a copy. - -```js -contract c { - uint[] x; // the data location of x is storage - // the data location of memoryArray is memory - function f(uint[] memoryArray) { - x = memoryArray; // works, copies the whole array to storage - var y = x; // works, assigns a pointer, data location of y is storage - y[7]; // fine, returns the 8th element - y.length = 2; // fine, modifies x through y - delete x; // fine, clears the array, also modifies y - // The following does not work; it would need to create a new temporary / - // unnamed array in storage, but storage is "statically" allocated: - // y = memoryArray; - // This does not work either, since it would "reset" the pointer, but there - // is no sensible location it could point to. - // delete y; - g(x); // calls g, handing over a reference to x - h(x); // calls h and creates an independent, temporary copy in memory - } - function g(uint[] storage storageArray) internal {} - function h(uint[] memoryArray) {} -} -``` - -**Summary:** - -Forced data location: - - parameters (not return) of external functions: calldata - - state variables: storage - -Default data location: - - parameters (also return) of functions: memory - - all other local variables: storage - -### Arrays - -Arrays can have a compile-time fixed size or they can be dynamic. -For storage arrays, the element type can be arbitrary (i.e. also other -arrays, mappings or structs). For memory arrays, it cannot be a mapping and -has to be an ABI type if it is an argument of a publicly-visible function. - -An array of fixed size `k` and element type `T` is written as `T[k]`, -an array of dynamic size as `T[]`. As an example, an array of 5 dynamic -arrays of `uint` is `uint[][5]` (note that the notation is reversed when -compared to some other languages). To access the second uint in the -third dynamic array, you use `x[2][1]` (indices are zero-based and -access works in the opposite way of the declaration, i.e. `x[2]` -shaves off one level in the type from the right). - -Arrays have a `length` member to hold their number of elements. -Dynamic arrays can be resized in storage (not in memory) by changing the -`.length` member. This does not happen automatically when attempting to access elements outside the current length. The size of memory arrays is fixed (but dynamic, i.e. it can depend on runtime parameters) once they are created. - -Variables of type `bytes` and `string` are special arrays. A `bytes` is similar to `byte[]`, -but it is packed tightly in calldata. `string` is equal to `bytes` but does not allow -length or index access (for now). - -```js -contract ArrayContract { - uint[2**20] m_aLotOfIntegers; - // Note that the following is not a pair of arrays but an array of pairs. - bool[2][] m_pairsOfFlags; - // newPairs is stored in memory - the default for function arguments - function setAllFlagPairs(bool[2][] newPairs) { - // assignment to a storage array replaces the complete array - m_pairsOfFlags = newPairs; - } - function setFlagPair(uint index, bool flagA, bool flagB) { - // access to a non-existing index will throw an exception - m_pairsOfFlags[index][0] = flagA; - m_pairsOfFlags[index][1] = flagB; - } - function changeFlagArraySize(uint newSize) { - // if the new size is smaller, removed array elements will be cleared - m_pairsOfFlags.length = newSize; - } - function clear() { - // these clear the arrays completely - delete m_pairsOfFlags; - delete m_aLotOfIntegers; - // identical effect here - m_pairsOfFlags.length = 0; - } - bytes m_byteData; - function byteArrays(bytes data) { - // byte arrays ("bytes") are different as they are stored without padding, - // but can be treated identical to "uint8[]" - m_byteData = data; - m_byteData.length += 7; - m_byteData[3] = 8; - delete m_byteData[2]; - } -} -``` - -### Structs - -Solidity provides a way to define new types in the form of structs, which is -shown in the following example: - -```js -contract CrowdFunding { - // Defines a new type with two fields. - struct Funder { - address addr; - uint amount; - } - struct Campaign { - address beneficiary; - uint fundingGoal; - uint numFunders; - uint amount; - mapping (uint => Funder) funders; - } - uint numCampaigns; - mapping (uint => Campaign) campaigns; - function newCampaign(address beneficiary, uint goal) returns (uint campaignID) { - campaignID = numCampaigns++; // campaignID is return variable - // Creates new struct and saves in storage. We leave out the mapping type. - campaigns[campaignID] = Campaign(beneficiary, goal, 0, 0); - } - function contribute(uint campaignID) { - Campaign c = campaigns[campaignID]; - // Creates a new temporary memory struct, initialised with the given values - // and copies it over to storage. - // Note that you can also use Funder(msg.sender, msg.value) to initialise. - c.funders[c.numFunders++] = Funder({addr: msg.sender, amount: msg.value}); - c.amount += msg.value; - } - function checkGoalReached(uint campaignID) returns (bool reached) { - Campaign c = campaigns[campaignID]; - if (c.amount < c.fundingGoal) - return false; - c.beneficiary.send(c.amount); - c.amount = 0; - return true; - } -} -``` - -The contract does not provide the full functionality of a crowdfunding -contract, but it contains the basic concepts necessary to understand structs. -Struct types can be used inside mappings and arrays and they can itself -contain mappings and arrays. - -It is not possible for a struct to contain a member of its own type, -although the struct itself can be the value type of a mapping member. -This restriction is necessary, as the size of the struct has to be finite. - -Note how in all the functions, a struct type is assigned to a local variable -(of the default storage data location). -This does not copy the struct but only stores a reference so that assignments to -members of the local variable actually write to the state. - -Of course, you can also directly access the members of the struct without -assigning it to a local variable, as in -`campaigns[campaignID].amount = 0`. - -# Syntactic Sugar and Globally Available Variables - -## Ether and Time Units - -A literal number can take a suffix of `wei`, `finney`, `szabo` or `ether` to convert between the subdenominations of ether, where Ether currency numbers without a postfix are assumed to be "wei", e.g. `2 ether == 2000 finney` evaluates to `true`. - -Furthermore, suffixes of `seconds`, `minutes`, `hours`, `days`, `weeks` and `years` can be used to convert between units of time where seconds are the base unit and units are converted naively (i.e. a year is always exactly 365 days, etc.). - -## Special Variables and Functions - -There are special variables and functions which always exist in the global -namespace and are mainly used to provide information about the blockchain. - -### Block and Transaction Properties - - - `block.coinbase` (`address`): current block miner's address - - `block.difficulty` (`uint`): current block difficulty - - `block.gaslimit` (`uint`): current block gaslimit - - `block.number` (`uint`): current block number - - `block.blockhash` (`function(uint) returns (bytes32)`): hash of the given block - - `block.timestamp` (`uint`): current block timestamp - - `msg.data` (`bytes`): complete calldata - - `msg.gas` (`uint`): remaining gas - - `msg.sender` (`address`): sender of the message (current call) - - `msg.sig` (`bytes4`): first four bytes of the calldata (i.e. function identifier) - - `msg.value` (`uint`): number of wei sent with the message - - `now` (`uint`): current block timestamp (alias for `block.timestamp`) - - `tx.gasprice` (`uint`): gas price of the transaction - - `tx.origin` (`address`): sender of the transaction (full call chain) - -### Cryptographic Functions - - - `sha3(...) returns (bytes32)`: compute the Ethereum-SHA-3 hash of the (tightly packed) arguments - - `sha256(...) returns (bytes32)`: compute the SHA-256 hash of the (tightly packed) arguments - - `ripemd160(...) returns (bytes20)`: compute RIPEMD-160 hash of the (tightly packed) arguments - - `ecrecover(bytes32, byte, bytes32, bytes32) returns (address)`: recover public key from elliptic curve signature - arguments are (data, v, r, s) - -In the above, "tightly packed" means that the arguments are concatenated without padding, i.e. -`sha3("ab", "c") == sha3("abc") == sha3(0x616263) == sha3(6382179) = sha3(97, 98, 99)`. If padding is needed, explicit type conversions can be used. - -It might be that you run into Out-of-Gas for `sha256`, `ripemd160` or `ecrecover` on a *private blockchain*. The reason for this is that those are implemented as so-called precompiled contracts and these contracts only really exist after they received the first message (although their contract code is hardcoded). Messages to non-existing contracts are more expensive and thus the execution runs into an Out-of-Gas error. A workaround for this problem is to first send e.g. 1 Wei to each of the contracts before you use them in your actual contracts. This is not an issue on the official or test net. - -### Contract Related - - - `this` (current contract's type): the current contract, explicitly convertible to `address` - - `suicide(address)`: suicide the current contract, sending its funds to the given address - -Furthermore, all functions of the current contract are callable directly including the current function. - -# Control Structures - -Most of the control structures from C/JavaScript are available in Solidity -except for `switch` and `goto`. So -there is: `if`, `else`, `while`, `for`, `break`, `continue`, `return`, with -the usual semantics known from C / JavaScript. - -Parentheses can *not* be omitted for conditionals, but curly brances can be omitted -around single-statement bodies. - -Note that there is no type conversion from non-boolean to boolean types as -there is in C and JavaScript, so `if (1) { ... }` is _not_ valid Solidity. - -## Function Calls - -### Internal Function Calls - -Functions of the current contract can be called directly ("internally"), also recursively, as seen in -this nonsensical example: - -```js -contract c { - function g(uint a) returns (uint ret) { return f(); } - function f() returns (uint ret) { return g(7) + f(); } -} -``` - -These function calls are translated into simple jumps inside the EVM. This has -the effect that the current memory is not cleared, i.e. passing memory references -to internally-called functions is very efficient. Only functions of the same -contract can be called internally. - -### External Function Calls - -The expression `this.g(8);` is also a valid function call, but this time, the function -will be called "externally", via a message call and not directly via jumps. -Functions of other contracts have to be called externally. For an external call, -all function arguments have to be copied to memory. - -When calling functions -of other contracts, the amount of Wei sent with the call and the gas can be specified: -```js -contract InfoFeed { - function info() returns (uint ret) { return 42; } -} -contract Consumer { - InfoFeed feed; - function setFeed(address addr) { feed = InfoFeed(addr); } - function callFeed() { feed.info.value(10).gas(800)(); } -} -``` -Note that the expression `InfoFeed(addr)` performs an explicit type conversion stating -that "we know that the type of the contract at the given address is `InfoFeed`" and -this does not execute a constructor. We could also have used `function setFeed(InfoFeed _feed) { feed = _feed; }` directly. Be careful about the fact that `feed.info.value(10).gas(800)` -only (locally) sets the value and amount of gas sent with the function call and only the -parentheses at the end perform the actual call. - -### Named Calls and Anonymous Function Parameters - -Function call arguments can also be given by name, in any order, and the names -of unused parameters (especially return parameters) can be omitted. - -```js -contract c { - function f(uint key, uint value) { ... } - function g() { - // named arguments - f({value: 2, key: 3}); - } - // omitted parameters - function func(uint k, uint) returns(uint) { - return k; - } -} -``` - -## Order of Evaluation of Expressions - -The evaluation order of expressions is not specified (more formally, the order -in which the children of one node in the expression tree are evaluated is not -specified, but they are of course evaluated before the node itself). It is only -guaranteed that statements are executed in order and short-circuiting for -boolean expressions is done. - -## Assignment - -The semantics of assignment are a bit more complicated for non-value types like arrays and structs. -Assigning *to* a state variable always creates an independent copy. On the other hand, assigning to a local variable creates an independent copy only for elementary types, i.e. static types that fit into 32 bytes. If structs or arrays (including `bytes` and `string`) are assigned from a state variable to a local variable, the local variable holds a reference to the original state variable. A second assignment to the local variable does not modify the state but only changes the reference. Assignments to members (or elements) of the local variable *do* change the state. - -## Exceptions - -There are some cases where exceptions are thrown automatically (see below). You can use the `throw` instruction to throw an exception manually. The effect of an exception is that the currently executing call is stopped and reverted (i.e. all changes to the state and balances are undone) and the exception is also "bubbled up" through Solidity function calls (exceptions are `send` and the low-level functions `call` and `callcode`, those return `false` in case of an exception). - -Catching exceptions is not yet possible. - -In the following example, we show how `throw` can be used to easily revert an Ether transfer and also how to check the return value of `send`: -``` -contract Sharer { - function sendHalf(address addr) returns (uint balance) { - if (!addr.send(msg.value/2)) - throw; // also reverts the transfer to Sharer - return this.balance; - } -} -``` - -Currently, there are two situations, where exceptions happen automatically in Solidity: - -1. If you access an array beyond its length (i.e. `x[i]` where `i >= x.length`) -2. If a function called via a message call does not finish properly (i.e. it runs out of gas or throws an exception itself). - -Internally, Solidity performs an "invalid jump" when an exception is thrown and thus causes the EVM to revert all changes made to the state. The reason for this is that there is no safe way to continue execution, because an expected effect did not occur. Because we want to retain the atomicity of transactions, the safest thing to do is to revert all changes and make the whole transaction (or at least call) without effect. - -# Contracts - -## Interfacing with other Contracts - -There are two ways to interface with other contracts: Either call a method of a contract whose address is known or create a new contract. Both uses are shown in the example below. Note that (obviously) the source code of a contract to be created needs to be known, which means that it has to come before the contract that creates it (and cyclic dependencies are not possible since the bytecode of the new contract is actually contained in the bytecode of the creating contract). - -```js -contract OwnedToken { - // TokenCreator is a contract type that is defined below. It is fine to reference it - // as long as it is not used to create a new contract. - TokenCreator creator; - address owner; - bytes32 name; - function OwnedToken(bytes32 _name) { - address nameReg = 0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2; - nameReg.call("register", _name); // This is an unsafe raw call to another contract. - owner = msg.sender; - // We do an explicit type conversion from `address` to `TokenCreator` and assume that the type of - // the calling contract is TokenCreator, there is no real way to check. - creator = TokenCreator(msg.sender); - name = _name; - } - function changeName(bytes32 newName) { - // Only the creator can alter the name -- contracts are implicitly convertible to addresses. - if (msg.sender == creator) name = newName; - } - function transfer(address newOwner) { - // Only the current owner can transfer the token. - if (msg.sender != owner) return; - // We also want to ask the creator if the transfer is fine. - // Note that this calls a function of the contract defined below. - // If the call fails (e.g. due to out-of-gas), the execution here stops - // immediately (the ability to catch this will be added later). - if (creator.isTokenTransferOK(owner, newOwner)) - owner = newOwner; - } -} -contract TokenCreator { - function createToken(bytes32 name) returns (OwnedToken tokenAddress) { - // Create a new Token contract and return its address. - // From the JavaScript side, the return type is simply "address", as this is the closest - // type available in the ABI. - // To get the address, this can only be called by another contract (not eth_call). - return new OwnedToken(name); - } - function changeName(OwnedToken tokenAddress, bytes32 name) { - // Again, the external type of "tokenAddress" is simply "address". - tokenAddress.changeName(name); - } - function isTokenTransferOK(address currentOwner, address newOwner) returns (bool ok) { - // Check some arbitrary condition. - address tokenAddress = msg.sender; - return (sha3(newOwner) & 0xff) == (bytes20(tokenAddress) & 0xff); - } -} -``` - -## Libraries - -Libraries are similar to contracts, but their purpose is that they are deployed only once at a specific address and their code is reused using the `CALLCODE` feature of the EVM. This means that if library functions are called, their code is executed in the context of the calling contract, i.e. `this` points to the calling contract and especially the storage from the calling contract can be accessed (this is not yet possible from solidity). - -The following example illustrates how to use libraries. Note that the library given below is not a good example for a library, since the benefits of a library in terms of saving gas for code deployment are only visible starting from a certain size. -``` -library Math { - function max(uint a, uint b) returns (uint) { - if (a > b) return a; - else return b; - } - function min(uint a, uint b) returns (uint) { - if (a < b) return a; - else return b; - } -} -contract C { - function register(uint value) { - // The library functions can be called without a specific instance of the library, - // since the "instance" will be the current contract. - value = Math.max(10, Math.min(100, value)); // clamp value to [10, 100] - // ... - } -} -``` - -The calls to `Math.max` and `Math.min` are both compiled as calls (`CALLCODE`s) to an external contract. If you use libraries, take care that an actual external function call is performed, so `msg.sender` does not point to the original sender anymore but to the the calling contract and also `msg.value` contains the funds sent during the call to the library function. - -As the compiler cannot know where the library will be deployed at, these addresses have to be filled into the final bytecode by a linker (see [Using the Commandline Compiler](#using-the-commandline-compiler) on how to use the commandline compiler for linking). If the addresses are not given as arguments to the compiler, the compiled hex code will contain placeholders of the form `__Math______` (where `Math` is the name of the library). The address can be filled manually by replacing all those 40 symbols by the hex encoding of the address of the library contract. - -Restrictions for libraries in comparison to contracts: - - - no state variables - - cannot inherit nor be inherited - -(these might be lifted at a later point) - -## Constructor Arguments - -A Solidity contract expects constructor arguments after the end of the contract data itself. -This means that you pass the arguments to a contract by putting them after the -compiled bytes as returned by the compiler in the usual ABI format. - -If you use web3.js's `MyContract.new()`, you do not have to care about this, though. - -## Contract Inheritance - -Solidity supports multiple inheritance by copying code including polymorphism. -Details are given in the following example. - -```js -contract owned { - function owned() { owner = msg.sender; } - address owner; -} - -// Use "is" to derive from another contract. Derived contracts can access all non-private members -// including internal functions and state variables. These cannot be accessed externally via -// `this`, though. -contract mortal is owned { - function kill() { if (msg.sender == owner) suicide(owner); } -} - -// These are only provided to make the interface known to the compiler. -// Note the bodiless functions. If a contract does not implement all functions -// it can only be used as an interface. -contract Config { function lookup(uint id) returns (address adr); } -contract NameReg { function register(bytes32 name); function unregister(); } - -// Multiple inheritance is possible. Note that "owned" is also a base class of -// "mortal", yet there is only a single instance of "owned" (as for virtual -// inheritance in C++). -contract named is owned, mortal { - function named(bytes32 name) { - address ConfigAddress = 0xd5f9d8d94886e70b06e474c3fb14fd43e2f23970; - NameReg(Config(ConfigAddress).lookup(1)).register(name); - } - -// Functions can be overridden, both local and message-based function calls take -// these overrides into account. - function kill() { - if (msg.sender == owner) { - address ConfigAddress = 0xd5f9d8d94886e70b06e474c3fb14fd43e2f23970; - NameReg(Config(ConfigAddress).lookup(1)).unregister(); -// It is still possible to call a specific overridden function. - mortal.kill(); - } - } -} - -// If a constructor takes an argument, it needs to be provided in the header (or modifier-invocation-style at the constructor of the derived contract (see below)). -contract PriceFeed is owned, mortal, named("GoldFeed") { - function updateInfo(uint newInfo) { - if (msg.sender == owner) info = newInfo; - } - - function get() constant returns(uint r) { return info; } - - uint info; -} -``` - -Note that above, we call `mortal.kill()` to "forward" the destruction request. The way this is done -is problematic, as seen in the following example: -```js -contract mortal is owned { - function kill() { if (msg.sender == owner) suicide(owner); } -} -contract Base1 is mortal { - function kill() { /* do cleanup 1 */ mortal.kill(); } -} -contract Base2 is mortal { - function kill() { /* do cleanup 2 */ mortal.kill(); } -} -contract Final is Base1, Base2 { -} -``` - -A call to `Final.kill()` will call `Base2.kill` as the most derived override, but this -function will bypass `Base1.kill`, basically because it does not even know about `Base1`. -The way around this is to use `super`: -```js -contract mortal is owned { - function kill() { if (msg.sender == owner) suicide(owner); } -} -contract Base1 is mortal { - function kill() { /* do cleanup 1 */ super.kill(); } -} -contract Base2 is mortal { - function kill() { /* do cleanup 2 */ super.kill(); } -} -contract Final is Base2, Base1 { -} -``` - -If `Base1` calls a function of `super`, it does not simply call this function on one of its -base contracts, it rather calls this function on the next base contract in the final -inheritance graph, so it will call `Base2.kill()` (note that the final inheritance sequence is --- starting with the most derived contract: Final, Base1, Base2, mortal, owned). Note that the actual function that -is called when using super is not known in the context of the class where it is used, -although its type is known. This is similar for ordinary virtual method lookup. - -### Arguments for Base Constructors - -Derived contracts need to provide all arguments needed for the base constructors. This can be done at two places: - -```js -contract Base { - uint x; - function Base(uint _x) { x = _x; } -} -contract Derived is Base(7) { - function Derived(uint _y) Base(_y * _y) { - } -} -``` - -Either directly in the inheritance list (`is Base(7)`) or in the way a modifier would be invoked as part of the header of the derived constructor (`Base(_y * _y)`). The first way to do it is more convenient if the constructor argument is a constant and defines the behaviour of the contract or describes it. The second way has to be used if the constructor arguments of the base depend on those of the derived contract. If, as in this silly example, both places are used, the modifier-style argument takes precedence. - - -### Multiple Inheritance and Linearization - -Languages that allow multiple inheritance have to deal with several problems, one of them being the [Diamond Problem](https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem). Solidity follows the path of Python and uses "[C3 Linearization](https://en.wikipedia.org/wiki/C3_linearization)" to force a specific order in the DAG of base classes. This results in the desirable property of monotonicity but disallows some inheritance graphs. Especially, the order in which the base classes are given in the `is` directive is important. In the following code, Solidity will give the error "Linearization of inheritance graph impossible". -```js -contract X {} -contract A is X {} -contract C is A, X {} -``` -The reason for this is that `C` requests `X` to override `A` (by specifying `A, X` in this order), but `A` itself requests to override `X`, which is a contradiction that cannot be resolved. - -A simple rule to remember is to specify the base classes in the order from "most base-like" to "most derived". - -## Abstract Contracts - -Contract functions can lack an implementation as in the following example (note that the function declaration header is terminated by `;`). -```js -contract feline { - function utterance() returns (bytes32); -} -``` -Such contracts cannot be compiled (even if they contain implemented functions alongside non-implemented functions), but they can be used as base contracts: -```js -contract Cat is feline { - function utterance() returns (bytes32) { return "miaow"; } -} -``` -If a contract inherits from an abstract contract and does not implement all non-implemented functions by overriding, it will itself be abstract. - -## Visibility Specifiers - -Functions and state variables can be specified as being `public`, `internal` or `private`, where the default for functions is `public` and `internal` for state variables. In addition, functions can also be specified as `external`. - -`external`: External functions are part of the contract interface and they can be called from other contracts and via transactions. An external function `f` cannot be called internally (i.e. `f()` does not work, but `this.f()` works). Furthermore, all function parameters are immutable. - -`public`: Public functions are part of the contract interface and can be either called internally or via messages. For public state variables, an automatic accessor function (see below) is generated. - -`internal`: Those functions and state variables can only be accessed internally, i.e. from within the current contract or contracts deriving from it without using `this`. - -`private`: Private functions and state variables are only visible for the contract they are defined in and not in derived contracts. - -```js -contract c { - function f(uint a) private returns (uint b) { return a + 1; } - function setData(uint a) internal { data = a; } - uint public data; -} -``` - -Other contracts can call `c.data()` to retrieve the value of data in state storage, but are not able to call `f`. Contracts derived from `c` can call `setData` to alter the value of `data` (but only in their own state). - -## Accessor Functions - -The compiler automatically creates accessor functions for all public state variables. The contract given below will have a function called `data` that does not take any arguments and returns a uint, the value of the state variable `data`. The initialization of state variables can be done at declaration. - -```js -contract test { - uint public data = 42; -} -``` - -The next example is a bit more complex: - -```js -contract complex { - struct Data { uint a; bytes3 b; mapping(uint => uint) map; } - mapping(uint => mapping(bool => Data[])) public data; -} -``` - -It will generate a function of the following form: -```js -function data(uint arg1, bool arg2, uint arg3) returns (uint a, bytes3 b) -{ - a = data[arg1][arg2][arg3].a; - b = data[arg1][arg2][arg3].b; -} -``` - -Note that the mapping in the struct is omitted because there is no good way to provide the key for the mapping. - -## Fallback Functions - -A contract can have exactly one unnamed -function. This function cannot have arguments and is executed on a call to the contract if -none of the other functions matches the given function identifier (or if no data was supplied at all). - -```js -contract Test { - function() { x = 1; } - uint x; -} - -contract Caller { - function callTest(address testAddress) { - Test(testAddress).call(0xabcdef01); // hash does not exist - // results in Test(testAddress).x becoming == 1. - } -} -``` - -## Function Modifiers - -Modifiers can be used to easily change the behaviour of functions, for example to automatically check a condition prior to executing the function. They are inheritable properties of contracts and may be overridden by derived contracts. - -```js -contract owned { - function owned() { owner = msg.sender; } - address owner; - - // This contract only defines a modifier but does not use it - it will - // be used in derived contracts. - // The function body is inserted where the special symbol "_" in the - // definition of a modifier appears. - modifier onlyowner { if (msg.sender == owner) _ } -} -contract mortal is owned { - // This contract inherits the "onlyowner"-modifier from "owned" and - // applies it to the "kill"-function, which causes that calls to "kill" - // only have an effect if they are made by the stored owner. - function kill() onlyowner { - suicide(owner); - } -} -contract priced { - // Modifiers can receive arguments: - modifier costs(uint price) { if (msg.value >= price) _ } -} -contract Register is priced, owned { - mapping (address => bool) registeredAddresses; - uint price; - function Register(uint initialPrice) { price = initialPrice; } - function register() costs(price) { - registeredAddresses[msg.sender] = true; - } - function changePrice(uint _price) onlyowner { - price = _price; - } -} -``` - -Multiple modifiers can be applied to a function by specifying them in a whitespace-separated list and will be evaluated in order. Explicit returns from a modifier or function body immediately leave the whole function, while control flow reaching the end of a function or modifier body continues after the "_" in the preceding modifier. Arbitrary expressions are allowed for modifier arguments and in this context, all symbols visible from the function are visible in the modifier. Symbols introduced in the modifier are not visible in the function (as they might change by overriding). - -## Constants - -State variables of value type can be declared as constant. -```js -contract C { - uint constant x = 32; - bytes3 constant text = "abc"; -} -``` - -This has the effect that the compiler does not reserve a storage slot -for these variables and every occurrence is replaced by their constant value. - -## Events - -Events allow the convenient usage of the EVM logging facilities. Events are inheritable members of contracts. When they are called, they cause the arguments to be stored in the transaction's log. Up to three parameters can receive the attribute `indexed` which will cause the respective arguments to be treated as log topics instead of data. The hash of the signature of the event is one of the topics except if you declared the event with `anonymous` specifier. All non-indexed arguments will be stored in the data part of the log. Example: - -```js -contract ClientReceipt { - event Deposit(address indexed _from, bytes32 indexed _id, uint _value); - function deposit(bytes32 _id) { - Deposit(msg.sender, _id, msg.value); - } -} -``` -Here, the call to `Deposit` will behave identical to -`log3(msg.value, 0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20, sha3(msg.sender), _id);`. Note that the large hex number is equal to the sha3-hash of "Deposit(address,bytes32,uint256)", the event's signature. - -### Additional Resources for Understanding Events: - -- Javascript documentation: -- Example usage of events: -- How to access them in js: - -# Miscellaneous - -## Layout of State Variables in Storage - -Statically-sized variables (everything except mapping and dynamically-sized array types) are laid out contiguously in storage starting from position `0`. Multiple items that need less than 32 bytes are packed into a single storage slot if possible, according to the following rules: - -- The first item in a storage slot is stored lower-order aligned. -- Elementary types use only that many bytes that are necessary to store them. -- If an elementary type does not fit the remaining part of a storage slot, it is moved to the next storage slot. -- Structs and array data always start a new slot and occupy whole slots (but items inside a struct or array are packed tightly according to these rules). - -The elements of structs and arrays are stored after each other, just as if they were given explicitly. - -Due to their unpredictable size, mapping and dynamically-sized array types use a `sha3` -computation to find the starting position of the value or the array data. These starting positions are always full stack slots. - -The mapping or the dynamic array itself -occupies an (unfilled) slot in storage at some position `p` according to the above rule (or by -recursively applying this rule for mappings to mappings or arrays of arrays). For a dynamic array, this slot stores the number of elements in the array (byte arrays and strings are an exception here, see below). For a mapping, the slot is unused (but it is needed so that two equal mappings after each other will use a different hash distribution). -Array data is located at `sha3(p)` and the value corresponding to a mapping key -`k` is located at `sha3(k . p)` where `.` is concatenation. If the value is again a -non-elementary type, the positions are found by adding an offset of `sha3(k . p)`. - -`bytes` and `string` store their data in the same slot where also the length is stored if they are short. In particular: If the data is at most `31` bytes long, it is stored in the higher-order bytes (left aligned) and the lowest-order byte stores `length * 2`. If it is longer, the main slot stores `length * 2 + 1` and the data is stored as usual in `sha3(slot)`. - -So for the following contract snippet: -```js -contract c { - struct S { uint a; uint b; } - uint x; - mapping(uint => mapping(uint => S)) data; -} -``` -The position of `data[4][9].b` is at `sha3(uint256(9) . sha3(uint256(4) . uint(256(1))) + 1`. - -## Esoteric Features - -There are some types in Solidity's type system that have no counterpart in the syntax. One of these types are the types of functions. But still, using `var` it is possible to have local variables of these types: - -```js -contract FunctionSelector { - function select(bool useB, uint x) returns (uint z) { - var f = a; - if (useB) f = b; - return f(x); - } - function a(uint x) returns (uint z) { - return x * x; - } - function b(uint x) returns (uint z) { - return 2 * x; - } -} -``` - -Calling `select(false, x)` will compute `x * x` and `select(true, x)` will compute `2 * x`. - - -## Internals - the Optimizer - -The Solidity optimizer operates on assembly, so it can be and also is used by other languages. It splits the sequence of instructions into basic blocks at JUMPs and JUMPDESTs. Inside these blocks, the instructions are analysed and every modification to the stack, to memory or storage is recorded as an expression which consists of an instruction and a list of arguments which are essentially pointers to other expressions. The main idea is now to find expressions that are always equal (on every input) and combine them into an expression class. The optimizer first tries to find each new expression in a list of already known expressions. If this does not work, the expression is simplified according to rules like `constant` + `constant` = `sum_of_constants` or `X` * 1 = `X`. Since this is done recursively, we can also apply the latter rule if the second factor is a more complex expression where we know that it will always evaluate to one. Modifications to storage and memory locations have to erase knowledge about storage and memory locations which are not known to be different: If we first write to location x and then to location y and both are input variables, the second could overwrite the first, so we actually do not know what is stored at x after we wrote to y. On the other hand, if a simplification of the expression x - y evaluates to a non-zero constant, we know that we can keep our knowledge about what is stored at x. - -At the end of this process, we know which expressions have to be on the stack in the end and have a list of modifications to memory and storage. This information is stored together with the basic blocks and is used to link them. Furthermore, knowledge about the stack, storage and memory configuration is forwarded to the next block(s). If we know the targets of all JUMP and JUMPI instructions, we can build a complete control flow graph of the program. If there is only one target we do not know (this can happen as in principle, jump targets can be computed from inputs), we have to erase all knowledge about the input state of a block as it can be the target of the unknown JUMP. If a JUMPI is found whose condition evaluates to a constant, it is transformed to an unconditional jump. - -As the last step, the code in each block is completely re-generated. A dependency graph is created from the expressions on the stack at the end of the block and every operation that is not part of this graph is essentially dropped. Now code is generated that applies the modifications to memory and storage in the order they were made in the original code (dropping modifications which were found not to be needed) and finally, generates all values that are required to be on the stack in the correct place. - -These steps are applied to each basic block and the newly generated code is used as replacement if it is smaller. If a basic block is split at a JUMPI and during the analysis, the condition evaluates to a constant, the JUMPI is replaced depending on the value of the constant, and thus code like -```js -var x = 7; -data[7] = 9; -if (data[x] != x + 2) - return 2; -else - return 1; -``` -is simplified to code which can also be compiled from -```js -data[7] = 9; -return 1; -``` -even though the instructions contained a jump in the beginning. - -## Using the Commandline Compiler - -One of the build targets of the Solidity repository is `solc`, the solidity commandline compiler. -Using `solc --help` provides you with an explanation of all options. The compiler can produce various outputs, ranging from simple binaries and assembly over an abstract syntax tree (parse tree) to estimations of gas usage. -If you only want to compile a single file, you run it as `solc --bin sourceFile.sol` and it will print the binary. Before you deploy your contract, activate the optimizer while compiling using `solc --optimize --bin sourceFile.sol`. If you want to get some of the more advanced output variants of `solc`, it is probably better to tell it to output everything to separate files using `solc -o outputDirectory --bin --ast --asm sourceFile.sol`. - -Of course, you can also specify several source files and actually that is also required if you use the `import` statement in Solidity: The compiler will (for now) not automatically discover source files for you, so you have to provide it with all source files your project consists of. - -If your contracts use [libraries](#libraries), you will notice that the bytecode contains substrings of the form `__LibraryName______`. You can use `solc` as a linker meaning that it will insert the library addresses for you at those points: - -Either add `--libraries "Math:0x12345678901234567890 Heap:0xabcdef0123456" to your command to provide an address for each library or store the string in a file (one library per line) and run `solc` using `--libraries fileName`. - -If `solc` is called with the option `--link`, all input files are interpreted to be unlinked binaries (hex-encoded) in the `__LibraryName____`-format given above and are linked in-place (if the input is read from stdin, it is written to stdout). All options except `--libraries` are ignored (including `-o`) in this case. - -## Tips and Tricks - - * Use `delete` on arrays to delete all its elements. - * Use shorter types for struct elements and sort them such that short types are grouped together. This can lower the gas costs as multiple SSTORE operations might be combined into a single (SSTORE costs 5000 or 20000 gas, so this is what you want to optimise). Use the gas price estimator (with optimiser enabled) to check! - * Make your state variables public - the compiler will create [getters](#accessor-functions) for you for free. - * If you end up checking conditions on input or state a lot at the beginning of your functions, try using [modifiers](#function-modifiers) - * If your contract has a function called `send` but you want to use the built-in send-function, use `address(contractVariable).send(amount)`. - * If you want your contracts to receive ether when called via `send`, you have to implement the [fallback function](#fallback-functions). - * Initialise storage structs with a single assignment: `x = MyStruct({a: 1, b: 2});` - -## Pitfalls - -Unfortunately, there are some subtleties the compiler does not yet warn you about. - - - If you use `StructName x` or `uint[] x` as a local variable, it **has** to be assigned from a state variable, - otherwise it behaves like a "null pointer" to storage, so you cannot use it on its own. - Please read about [data locations](#data-location). The most common solution is to use `StructName memory x` or `uint[] memory x`. - - In `for (var i = 0; i < arrayName.length; i++) { ... }`, the type of `i` will be `uint8`, because this is the smallest type that is required to hold the value `0`. If the array has more than 255 elements, the loop will not terminate. - -## Cheatsheet - -### Global Variables - - - `block.coinbase` (`address`): current block miner's address - - `block.difficulty` (`uint`): current block difficulty - - `block.gaslimit` (`uint`): current block gaslimit - - `block.number` (`uint`): current block number - - `block.blockhash` (`function(uint) returns (bytes32)`): hash of the given block - - `block.timestamp` (`uint`): current block timestamp - - `msg.data` (`bytes`): complete calldata - - `msg.gas` (`uint`): remaining gas - - `msg.sender` (`address`): sender of the message (current call) - - `msg.value` (`uint`): number of wei sent with the message - - `now` (`uint`): current block timestamp (alias for `block.timestamp`) - - `tx.gasprice` (`uint`): gas price of the transaction - - `tx.origin` (`address`): sender of the transaction (full call chain) - - `sha3(...) returns (bytes32)`: compute the Ethereum-SHA3 hash of the (tightly packed) arguments - - `sha256(...) returns (bytes32)`: compute the SHA256 hash of the (tightly packed) arguments - - `ripemd160(...) returns (bytes20)`: compute RIPEMD of 256 the (tightly packed) arguments - - `ecrecover(bytes32, byte, bytes32, bytes32) returns (address)`: recover public key from elliptic curve signature - - `this` (current contract's type): the current contract, explicitly convertible to `address` - - `super`: the contract one level higher in the inheritance hierarchy - - `suicide(address)`: suicide the current contract, sending its funds to the given address - - `
.balance`: balance of the address in Wei - - `
.send(uint256) returns (bool)`: send given amount of Wei to address, returns `false` on failure. - -### Function Visibility Specifiers - -```js -function myFunction() returns (bool) { - return true; -} -``` - - - `public`: visible externally and internally (creates accessor function for storage/state variables) - - `private`: only visible in the current contract - - `external`: only visible externally (only for functions) - i.e. can only be message-called (via `this.fun`) - - `internal`: only visible internally - -### Modifiers - - - `constant` for state variables: Disallows assignment (except initialisation), does not occupy storage slot. - - `constant` for functions: Disallows modification of state - this is not enforced yet. - - `anonymous` for events: Does not store event signature as topic. - - `indexed` for event parameters: Stores the parameter as topic. - -### Types - -TODO - - - -*** - -_Большое спасибо General-Beck Денис Солдатову за перевод._ -_Другие переводы от Дениса на тему Ethereum можно найти [здесь](http://general-beck.info/component/tags/tag/98-ethereum)_ - -_Note: This page is under construction_ From 265bcf983e831053d7ff04e5f15ac0b5a2535b8f Mon Sep 17 00:00:00 2001 From: jamesray1 <16969914+jamesray1@users.noreply.github.com> Date: Sat, 7 Apr 2018 14:09:37 +1000 Subject: [PATCH 09/22] Rename Readme.md to README --- README | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 README diff --git a/README b/README new file mode 100644 index 000000000..6e4b622fe --- /dev/null +++ b/README @@ -0,0 +1,14 @@ +Newcomers and those seeking an introduction to Ethereum may go to https://ethereum.org or https://github.com/ethereum/wiki/wiki. + +Note that you can proofread while you read and learn about anything. + +# Contribution guidelines +Please just **edit the pages in the wiki directly** as shown in the sidebar here: https://github.com/ethereum/wiki/wiki, rather than making **pull requests**. + +Please only create an **issue** if you can't fix it by editing yourself, and only if it is related to the wiki. If it is a technical issue e.g. with [web3 or JSON.RPC](https://github.com/ethereum/web3.js/issues), [geth](https://github.com/ethereum/go-ethereum/issues), [Mist](https://github.com/ethereum/mist) (although note that Mist isn't really user-ready yet, so using alternatives like [MyEtherWallet](https://www.myetherwallet.com/) is recommended instead), etc., please post an issue in the repo for that project as well, and reference the issue that you create in this repo (by copying and pasting the link to the issue in this repo in a comment in the issue in the relevant project repo). + +If you are **translating** an article, please **create a new page** and create the translation in that. Do not edit an existing article by translating it. Someone did this with the home wiki, changing the title, and this actually caused the home page to just direct to a list of pages in the wiki, and made it hard to find the edited home page as the title was changed to Arabic. So **do not edit the title of an article**. + +If you have experience with editing on Wikipedia, then that will help with knowing how to edit this wiki, although the contribution rules are less strict. Referencing facts is a key writing and proofreading task, as well as checking that information is up-to-date (and updating it if otherwise), correcting grammar, typos, and spelling; and making the wiki comprehensive and easy to understand. + +Other rules, such as a neutral point of view and no original research are desirable, but may be hard to maintain. Notability is less relevant. From 7695cf8060ee5c98723603fbce5e6ba171b1d853 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Sat, 7 Apr 2018 14:10:18 +1000 Subject: [PATCH 10/22] Rename README to README.md --- README | 14 -------------- README.md | 15 ++++++++++++++- 2 files changed, 14 insertions(+), 15 deletions(-) delete mode 100644 README diff --git a/README b/README deleted file mode 100644 index 6e4b622fe..000000000 --- a/README +++ /dev/null @@ -1,14 +0,0 @@ -Newcomers and those seeking an introduction to Ethereum may go to https://ethereum.org or https://github.com/ethereum/wiki/wiki. - -Note that you can proofread while you read and learn about anything. - -# Contribution guidelines -Please just **edit the pages in the wiki directly** as shown in the sidebar here: https://github.com/ethereum/wiki/wiki, rather than making **pull requests**. - -Please only create an **issue** if you can't fix it by editing yourself, and only if it is related to the wiki. If it is a technical issue e.g. with [web3 or JSON.RPC](https://github.com/ethereum/web3.js/issues), [geth](https://github.com/ethereum/go-ethereum/issues), [Mist](https://github.com/ethereum/mist) (although note that Mist isn't really user-ready yet, so using alternatives like [MyEtherWallet](https://www.myetherwallet.com/) is recommended instead), etc., please post an issue in the repo for that project as well, and reference the issue that you create in this repo (by copying and pasting the link to the issue in this repo in a comment in the issue in the relevant project repo). - -If you are **translating** an article, please **create a new page** and create the translation in that. Do not edit an existing article by translating it. Someone did this with the home wiki, changing the title, and this actually caused the home page to just direct to a list of pages in the wiki, and made it hard to find the edited home page as the title was changed to Arabic. So **do not edit the title of an article**. - -If you have experience with editing on Wikipedia, then that will help with knowing how to edit this wiki, although the contribution rules are less strict. Referencing facts is a key writing and proofreading task, as well as checking that information is up-to-date (and updating it if otherwise), correcting grammar, typos, and spelling; and making the wiki comprehensive and easy to understand. - -Other rules, such as a neutral point of view and no original research are desirable, but may be hard to maintain. Notability is less relevant. diff --git a/README.md b/README.md index 88a20a570..6e4b622fe 100644 --- a/README.md +++ b/README.md @@ -1 +1,14 @@ -Please use [wiki/wiki](https://github.com/ethereum/wiki/wiki) since that is freely editable by anyone, rather than needing to maintain this repo. \ No newline at end of file +Newcomers and those seeking an introduction to Ethereum may go to https://ethereum.org or https://github.com/ethereum/wiki/wiki. + +Note that you can proofread while you read and learn about anything. + +# Contribution guidelines +Please just **edit the pages in the wiki directly** as shown in the sidebar here: https://github.com/ethereum/wiki/wiki, rather than making **pull requests**. + +Please only create an **issue** if you can't fix it by editing yourself, and only if it is related to the wiki. If it is a technical issue e.g. with [web3 or JSON.RPC](https://github.com/ethereum/web3.js/issues), [geth](https://github.com/ethereum/go-ethereum/issues), [Mist](https://github.com/ethereum/mist) (although note that Mist isn't really user-ready yet, so using alternatives like [MyEtherWallet](https://www.myetherwallet.com/) is recommended instead), etc., please post an issue in the repo for that project as well, and reference the issue that you create in this repo (by copying and pasting the link to the issue in this repo in a comment in the issue in the relevant project repo). + +If you are **translating** an article, please **create a new page** and create the translation in that. Do not edit an existing article by translating it. Someone did this with the home wiki, changing the title, and this actually caused the home page to just direct to a list of pages in the wiki, and made it hard to find the edited home page as the title was changed to Arabic. So **do not edit the title of an article**. + +If you have experience with editing on Wikipedia, then that will help with knowing how to edit this wiki, although the contribution rules are less strict. Referencing facts is a key writing and proofreading task, as well as checking that information is up-to-date (and updating it if otherwise), correcting grammar, typos, and spelling; and making the wiki comprehensive and easy to understand. + +Other rules, such as a neutral point of view and no original research are desirable, but may be hard to maintain. Notability is less relevant. From cb1a446ba3ec2b9affc8aa9df1c151140eb5563e Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Tue, 29 May 2018 18:36:52 +1000 Subject: [PATCH 11/22] Move all content to wiki/wiki and refer to wiki/wiki. --- README.md | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/README.md b/README.md index 6e4b622fe..0b158c7e3 100644 --- a/README.md +++ b/README.md @@ -1,14 +1 @@ -Newcomers and those seeking an introduction to Ethereum may go to https://ethereum.org or https://github.com/ethereum/wiki/wiki. - -Note that you can proofread while you read and learn about anything. - -# Contribution guidelines -Please just **edit the pages in the wiki directly** as shown in the sidebar here: https://github.com/ethereum/wiki/wiki, rather than making **pull requests**. - -Please only create an **issue** if you can't fix it by editing yourself, and only if it is related to the wiki. If it is a technical issue e.g. with [web3 or JSON.RPC](https://github.com/ethereum/web3.js/issues), [geth](https://github.com/ethereum/go-ethereum/issues), [Mist](https://github.com/ethereum/mist) (although note that Mist isn't really user-ready yet, so using alternatives like [MyEtherWallet](https://www.myetherwallet.com/) is recommended instead), etc., please post an issue in the repo for that project as well, and reference the issue that you create in this repo (by copying and pasting the link to the issue in this repo in a comment in the issue in the relevant project repo). - -If you are **translating** an article, please **create a new page** and create the translation in that. Do not edit an existing article by translating it. Someone did this with the home wiki, changing the title, and this actually caused the home page to just direct to a list of pages in the wiki, and made it hard to find the edited home page as the title was changed to Arabic. So **do not edit the title of an article**. - -If you have experience with editing on Wikipedia, then that will help with knowing how to edit this wiki, although the contribution rules are less strict. Referencing facts is a key writing and proofreading task, as well as checking that information is up-to-date (and updating it if otherwise), correcting grammar, typos, and spelling; and making the wiki comprehensive and easy to understand. - -Other rules, such as a neutral point of view and no original research are desirable, but may be hard to maintain. Notability is less relevant. +Please use [wiki/wiki](https://github.com/ethereum/wiki/wiki), since that is freely maintainable. From 7bc050ec6944437a643fc1707149526e12ade5a1 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 12 Oct 2018 18:50:22 +1100 Subject: [PATCH 12/22] Create ISSUE_TEMPLATE.md --- ISSUE_TEMPLATE.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 ISSUE_TEMPLATE.md diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..ce23b5bf4 --- /dev/null +++ b/ISSUE_TEMPLATE.md @@ -0,0 +1,5 @@ +If you have a technical issue with a specific client, application or tool, e.g. those listed [here](https://github.com/ethereum/wiki/wiki/Clients,-tools,-dapp-browsers,-wallets-and-other-projects), please ask in the Gitter room of that project, and if your issue is still not resolved, post an issue in the repo for that project. Please only create an issue if you can't fix it by editing yourself, it doesn't get resolved via the [Gitter documentation room](https://gitter.im/ethereum/documentation) (including pinging someone who knows how to handle the issue, or asking/finding out who knows then pinging them) and only if it is related to the wiki. + +If you had an issue that has been closed, and feel that it could be reopened after following the above steps, feel free to request to reopen it. About 180 issues and 30 PRs were closed on May 29 2018, due to deleting the codebase and referring people to this wiki, in order to reduce the burden on maintenance by following the above steps. This fits well with Ethereum's ethos of decentralization, which includes minimising bureaucracies, and gives contributors more time to build Ethereum and satisfy the long-term interests of current and future users. If you had an issue or PR that was closed without explanation, I apologize, but it is time-consuming to reply to every one; I'm hoping that people will see the updated readme and this section. + +While having good documentation is certainly important to help onboard new people including users and contributors of all kinds, there is a lot to do at the moment in terms of design and implementation, and editing documentation is something that seems best to be done when you are reading or learning about something, using something, building upon something, etc., not usually just for the sake of reading and editing for other users, although reviewing one's own writing is certainly a good practice. From d363d0f363309e8d81e131998d3c48f236ba4280 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 12 Oct 2018 18:53:10 +1100 Subject: [PATCH 13/22] Create PULL_REQUEST_TEMPLATE.md --- PULL_REQUEST_TEMPLATE.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 PULL_REQUEST_TEMPLATE.md diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..50391193b --- /dev/null +++ b/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1 @@ +Do not make a pull request; chances are that all PRs will be ignored, since any content in the codebase can be in this [wiki](https://github.com/ethereum/wiki/wiki) instead. From a082178070dc44a1ed309870e5a1d44c21da2739 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 12 Oct 2018 18:54:17 +1100 Subject: [PATCH 14/22] Create CONTRIBUTING.md --- CONTRIBUTING.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..6ca7f1dff --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,20 @@ +For an introduction to GitHub wikis, see [here](https://help.github.com/articles/about-github-wikis/). + +Users signed in with GitHub can edit and add pages using a [browser](https://help.github.com/articles/editing-wiki-pages-via-the-online-interface) or [locally](https://help.github.com/articles/adding-and-editing-wiki-pages-locally). To view the wiki locally, ~~scroll to the bottom of the sidebar, and get the link to clone the wiki, (posting here for convenience: https://github.com/ethereum/wiki.wiki.git), then~~ press CTRL+ALT+T to open a terminal, run `git clone https://github.com/ethereum/wiki.wiki.git` and then view the files from a file explorer or using `cd wiki.wiki; ls; // Enter a command to open a file from a terminal, e.g. gedit Home.md` + +### Page titles + +**Do not change the title of a page**, as the link for it will change. In particular, if you change the title for a page, any link to it will just direct to a blank page. (In the case of this page, also the Wiki tab in the header of this repo, as well as any link to the Home page, will just direct to a list of pages.) If you really want to change the title, then create a new page with the new title, move the contents of the old page to the new page, and update the old page with a redirect link to the new page. If you want to translate a page, create a new page and translate the original there. Consider previewing your changes before saving them, and if you detect any errors, fix them. If you happen to get directed to a page that doesn't exist with a prompt to create a new page, do that, without changing the title. Then check the history of the newly created page. It may be that there is a history of changes to the page that you just created, with the second most recent change (second to you creating the page) being that someone renamed the page. If so, please fix the page (restore it to the revision before the title was changed or redirect to the new page) and tag the person who renamed the page in this issue [here](https://github.com/ethereum/wiki/issues/591) or on [Gitter](https://gitter.im/ethereum/documentation). + +### Wikipedia pillars + +Wikipedia has [five pillars](https://en.wikipedia.org/wiki/Wikipedia:Five_pillars) which provide a good standard for contributing that we can adapt for our needs. If you have experience with editing on Wikipedia, then that will help with knowing how to edit this wiki, although the contribution rules are less strict. Referencing facts is a key writing and proofreading task, as well as checking that information is up-to-date (and updating it if otherwise), correcting grammar, typos, and spelling; and making the wiki comprehensive and easy to understand. Other rules, such as a neutral point of view and no original research are desirable, but may be hard to maintain. Notability is less relevant, this wiki is about all things Ethereum. + +### Translating +The title of the page should start with [Language]: title, e.g. "[German] White Paper" or "[中文] 以太坊Wiki目录". Then add a Table of Contents (ToC) page linking for the language, linking to all pages of that language, and add a link to it in the [footer](https://github.com/ethereum/wiki/wiki/_Footer/_edit). + +### License and [contributor license agreement](https://github.com/ethereum/wiki/wiki/CC0-license#list-of-contributors) + +Please permit your contributions to be under the [CC0 license](https://creativecommons.org/publicdomain/zero/1.0/legalcode) [1](https://creativecommons.org/share-your-work/public-domain/cc0/), which makes your contributions have no rights reserved, putting them in the public domain. This will help to allow for the dissemination of information about Ethereum, the Ethereum ecosystem and Web 3 to the public, in a completely permissive manner. To state that you accept your contributions to be under a CC0 license, please add yourself to the list of external contributors [here](https://github.com/ethereum/wiki/wiki/CC0-license#list-of-contributors). Otherwise, without adding yourself to the list, your contributions will be all rights reserved. Some previous contributions may have all rights reserved (by contributors that have not agreed to a CC0 license [at pull request 528](https://github.com/ethereum/wiki/pull/528)), since no copyright permission was stated explicitly. Until all previous contributors agree to a CC0 license, and to provide clarity of licensing, you may also wish to add a HTML comment to the top of pages or sections that you contribute to, like so: ``. + +For more information, see https://github.com/ethereum/wiki/wiki. From 2c78a264569783cfc4073482f2953b351cec4836 Mon Sep 17 00:00:00 2001 From: Richard Littauer Date: Wed, 17 Oct 2018 06:25:51 +0100 Subject: [PATCH 15/22] Edited README and added screenshot --- README.md | 8 +++++++- screenshot.png | Bin 0 -> 18210 bytes 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 screenshot.png diff --git a/README.md b/README.md index 0b158c7e3..9c06a2431 100644 --- a/README.md +++ b/README.md @@ -1 +1,7 @@ -Please use [wiki/wiki](https://github.com/ethereum/wiki/wiki), since that is freely maintainable. +# Wiki + +All of the content in this repository lives in the [Wiki](https://github.com/ethereum/wiki/wiki). + +[![Screenshot](screenshot.png)](https://github.com/ethereum/wiki/wiki) + +There is no longer any code or documentation stored in this repository. diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..c63ee4a75037bd9c6fcd3f458f7d058170c62143 GIT binary patch literal 18210 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 literal 0 HcmV?d00001 From 0b1815231b1870651301d58f0804743d2c36cf0b Mon Sep 17 00:00:00 2001 From: Richard Littauer Date: Wed, 17 Oct 2018 06:26:28 +0100 Subject: [PATCH 16/22] Edited Templates to make them a bit clearer --- CONTRIBUTING.md | 8 ++++++-- ISSUE_TEMPLATE.md | 12 +++++++++--- PULL_REQUEST_TEMPLATE.md | 6 +++++- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6ca7f1dff..9867a178d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,10 +11,14 @@ Users signed in with GitHub can edit and add pages using a [browser](https://hel Wikipedia has [five pillars](https://en.wikipedia.org/wiki/Wikipedia:Five_pillars) which provide a good standard for contributing that we can adapt for our needs. If you have experience with editing on Wikipedia, then that will help with knowing how to edit this wiki, although the contribution rules are less strict. Referencing facts is a key writing and proofreading task, as well as checking that information is up-to-date (and updating it if otherwise), correcting grammar, typos, and spelling; and making the wiki comprehensive and easy to understand. Other rules, such as a neutral point of view and no original research are desirable, but may be hard to maintain. Notability is less relevant, this wiki is about all things Ethereum. ### Translating -The title of the page should start with [Language]: title, e.g. "[German] White Paper" or "[中文] 以太坊Wiki目录". Then add a Table of Contents (ToC) page linking for the language, linking to all pages of that language, and add a link to it in the [footer](https://github.com/ethereum/wiki/wiki/_Footer/_edit). +The title of the page should start with [Language]: title, e.g. "[German] White Paper" or "[中文] 以太坊Wiki目录". Then add a Table of Contents (ToC) page linking for the language, linking to all pages of that language, and add a link to it in the [footer](https://github.com/ethereum/wiki/wiki/_Footer/_edit). ### License and [contributor license agreement](https://github.com/ethereum/wiki/wiki/CC0-license#list-of-contributors) -Please permit your contributions to be under the [CC0 license](https://creativecommons.org/publicdomain/zero/1.0/legalcode) [1](https://creativecommons.org/share-your-work/public-domain/cc0/), which makes your contributions have no rights reserved, putting them in the public domain. This will help to allow for the dissemination of information about Ethereum, the Ethereum ecosystem and Web 3 to the public, in a completely permissive manner. To state that you accept your contributions to be under a CC0 license, please add yourself to the list of external contributors [here](https://github.com/ethereum/wiki/wiki/CC0-license#list-of-contributors). Otherwise, without adding yourself to the list, your contributions will be all rights reserved. Some previous contributions may have all rights reserved (by contributors that have not agreed to a CC0 license [at pull request 528](https://github.com/ethereum/wiki/pull/528)), since no copyright permission was stated explicitly. Until all previous contributors agree to a CC0 license, and to provide clarity of licensing, you may also wish to add a HTML comment to the top of pages or sections that you contribute to, like so: ``. +Please permit your contributions to be under the [CC0 license](https://creativecommons.org/publicdomain/zero/1.0/legalcode) [1](https://creativecommons.org/share-your-work/public-domain/cc0/), which makes your contributions have no rights reserved, putting them in the public domain. This will help to allow for the dissemination of information about Ethereum, the Ethereum ecosystem and Web 3 to the public, in a completely permissive manner. To state that you accept your contributions to be under a CC0 license, please add yourself to the list of external contributors [here](https://github.com/ethereum/wiki/wiki/CC0-license#list-of-contributors). Otherwise, without adding yourself to the list, your contributions will be all rights reserved. Some previous contributions may have all rights reserved (by contributors that have not agreed to a CC0 license [at pull request 528](https://github.com/ethereum/wiki/pull/528)), since no copyright permission was stated explicitly. Until all previous contributors agree to a CC0 license, and to provide clarity of licensing, you may also wish to add a HTML comment to the top of pages or sections that you contribute to, like so: ``. For more information, see https://github.com/ethereum/wiki/wiki. + +## Closed Issues + +If you had an issue that has been closed, and feel that it could be reopened after following the above steps, feel free to request to reopen it. About 180 issues and 30 PRs were closed on May 29 2018, due to deleting the codebase and referring people to this wiki, in order to reduce the burden on maintenance by following the above steps. This fits well with Ethereum's ethos of decentralization, which includes minimising bureaucracies, and gives contributors more time to build Ethereum and satisfy the long-term interests of current and future users. If you had an issue or PR that was closed without explanation, I apologize, but it is time-consuming to reply to every one. diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index ce23b5bf4..609944ad4 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -1,5 +1,11 @@ -If you have a technical issue with a specific client, application or tool, e.g. those listed [here](https://github.com/ethereum/wiki/wiki/Clients,-tools,-dapp-browsers,-wallets-and-other-projects), please ask in the Gitter room of that project, and if your issue is still not resolved, post an issue in the repo for that project. Please only create an issue if you can't fix it by editing yourself, it doesn't get resolved via the [Gitter documentation room](https://gitter.im/ethereum/documentation) (including pinging someone who knows how to handle the issue, or asking/finding out who knows then pinging them) and only if it is related to the wiki. +Hello! Chances are you're in the wrong place. -If you had an issue that has been closed, and feel that it could be reopened after following the above steps, feel free to request to reopen it. About 180 issues and 30 PRs were closed on May 29 2018, due to deleting the codebase and referring people to this wiki, in order to reduce the burden on maintenance by following the above steps. This fits well with Ethereum's ethos of decentralization, which includes minimising bureaucracies, and gives contributors more time to build Ethereum and satisfy the long-term interests of current and future users. If you had an issue or PR that was closed without explanation, I apologize, but it is time-consuming to reply to every one; I'm hoping that people will see the updated readme and this section. +If you have a technical issue with a specific client, application or tool, e.g. those listed [here](https://github.com/ethereum/wiki/wiki/Clients,-tools,-dapp-browsers,-wallets-and-other-projects), please ask in the Gitter room of that project, and if your issue is still not resolved, post an issue in the repo for that project. This repository is only used for the wiki, and issues here are only relevant if they are directly about the wiki. -While having good documentation is certainly important to help onboard new people including users and contributors of all kinds, there is a lot to do at the moment in terms of design and implementation, and editing documentation is something that seems best to be done when you are reading or learning about something, using something, building upon something, etc., not usually just for the sake of reading and editing for other users, although reviewing one's own writing is certainly a good practice. +Please only create an issue here if: +- You've spotted something in the wiki that you can't fix it by editing it yourself +- Your problem hasn't been resolved on the [Gitter documentation room](https://gitter.im/ethereum/documentation). You've tried pinging someone who knows how to handle the issue, or asking who this might be, and then asking them. +- You've waited at least a couple of days for responses on Gitter. +- And **only** if it is related to the wiki. + +Thank you. If your issue was previously closed, see the [Contributing Guide](CONTRIBUTING.md) for more information on closed issues. diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index 50391193b..58411ddb0 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -1 +1,5 @@ -Do not make a pull request; chances are that all PRs will be ignored, since any content in the codebase can be in this [wiki](https://github.com/ethereum/wiki/wiki) instead. +**Please do not open a pull request.** + +This repository no longer contains any code or documentation; please edit the [wiki](https://github.com/ethereum/wiki/wiki) directly, instead. + +If you're having issues editing the wiki, you could try reading the introduction to GitHub wikis, [here](https://help.github.com/articles/about-github-wikis/). From eb10288bb346ce206f92ec81cc594b1e6539e7c3 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Wed, 17 Oct 2018 17:11:23 +1100 Subject: [PATCH 17/22] Double space --> single space --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9867a178d..739504288 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,7 +15,7 @@ The title of the page should start with [Language]: title, e.g. "[German] White ### License and [contributor license agreement](https://github.com/ethereum/wiki/wiki/CC0-license#list-of-contributors) -Please permit your contributions to be under the [CC0 license](https://creativecommons.org/publicdomain/zero/1.0/legalcode) [1](https://creativecommons.org/share-your-work/public-domain/cc0/), which makes your contributions have no rights reserved, putting them in the public domain. This will help to allow for the dissemination of information about Ethereum, the Ethereum ecosystem and Web 3 to the public, in a completely permissive manner. To state that you accept your contributions to be under a CC0 license, please add yourself to the list of external contributors [here](https://github.com/ethereum/wiki/wiki/CC0-license#list-of-contributors). Otherwise, without adding yourself to the list, your contributions will be all rights reserved. Some previous contributions may have all rights reserved (by contributors that have not agreed to a CC0 license [at pull request 528](https://github.com/ethereum/wiki/pull/528)), since no copyright permission was stated explicitly. Until all previous contributors agree to a CC0 license, and to provide clarity of licensing, you may also wish to add a HTML comment to the top of pages or sections that you contribute to, like so: ``. +Please permit your contributions to be under the [CC0 license](https://creativecommons.org/publicdomain/zero/1.0/legalcode) [1](https://creativecommons.org/share-your-work/public-domain/cc0/), which makes your contributions have no rights reserved, putting them in the public domain. This will help to allow for the dissemination of information about Ethereum, the Ethereum ecosystem and Web 3 to the public, in a completely permissive manner. To state that you accept your contributions to be under a CC0 license, please add yourself to the list of external contributors [here](https://github.com/ethereum/wiki/wiki/CC0-license#list-of-contributors). Otherwise, without adding yourself to the list, your contributions will be all rights reserved. Some previous contributions may have all rights reserved (by contributors that have not agreed to a CC0 license [at pull request 528](https://github.com/ethereum/wiki/pull/528)), since no copyright permission was stated explicitly. Until all previous contributors agree to a CC0 license, and to provide clarity of licensing, you may also wish to add a HTML comment to the top of pages or sections that you contribute to, like so: ``. For more information, see https://github.com/ethereum/wiki/wiki. From 68707dbbdaa4ef3c66682283d9f60fc09b0a0423 Mon Sep 17 00:00:00 2001 From: Sam Richards Date: Sat, 4 Sep 2021 10:01:00 -0700 Subject: [PATCH 18/22] Update README to match wiki copy --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9c06a2431..ada6d5db1 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Wiki -All of the content in this repository lives in the [Wiki](https://github.com/ethereum/wiki/wiki). +Hello 👋 -[![Screenshot](screenshot.png)](https://github.com/ethereum/wiki/wiki) +This wiki served us well for a very long time, but it's moved to a different platform that will allow for more collaboration, and hopefully better knowledge sharing over time. -There is no longer any code or documentation stored in this repository. +eth.wiki From cc7bba67dca2683d1c79f25385a4438644ea288f Mon Sep 17 00:00:00 2001 From: Sam Richards Date: Sat, 4 Sep 2021 10:02:34 -0700 Subject: [PATCH 19/22] Add link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ada6d5db1..6939beff4 100644 --- a/README.md +++ b/README.md @@ -4,4 +4,4 @@ Hello 👋 This wiki served us well for a very long time, but it's moved to a different platform that will allow for more collaboration, and hopefully better knowledge sharing over time. -eth.wiki +[eth.wiki](https://eth.wiki/) From 7e6fbd7558624e915d86e2add51343cbb9c64586 Mon Sep 17 00:00:00 2001 From: Joe Date: Wed, 18 May 2022 14:29:03 +0100 Subject: [PATCH 20/22] add deprecation notice --- README.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6939beff4..932f3c10d 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,13 @@ # Wiki -Hello 👋 +# Eth.wiki -This wiki served us well for a very long time, but it's moved to a different platform that will allow for more collaboration, and hopefully better knowledge sharing over time. +:no_entry_sign: **no longer actively maintained** :no_entry_sign: -[eth.wiki](https://eth.wiki/) +Eth.wiki is a now largely outdated collection of resources explaining the state-of-the-art in Ethereum circa 2020. + +The material in this repository has been updated and migrated to ethereum.org. + +This repository is due to be archived shortly. Please visit ethereum.org instead for current Ethereum information! + +Looking to contribute to Ethereum documentation? Check out the ethereum.org repo: https://github.com/ethereum/ethereum-org-website From 5aa95b8a01372bbcc02d91ea8ab762e57496b8cc Mon Sep 17 00:00:00 2001 From: Joseph Cook <33655003+jmcook1186@users.noreply.github.com> Date: Wed, 18 May 2022 14:30:46 +0100 Subject: [PATCH 21/22] remove redundant title --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 932f3c10d..1923c270b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Wiki -# Eth.wiki :no_entry_sign: **no longer actively maintained** :no_entry_sign: From b56339f311658b26a746948254ead2e9775783e9 Mon Sep 17 00:00:00 2001 From: Sam Richards Date: Wed, 18 May 2022 10:13:38 -0700 Subject: [PATCH 22/22] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1923c270b..b65e14f8e 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@ :no_entry_sign: **no longer actively maintained** :no_entry_sign: -Eth.wiki is a now largely outdated collection of resources explaining the state-of-the-art in Ethereum circa 2020. +This wiki is a now a largely outdated collection of resources explaining the state-of-the-art in Ethereum circa 2014-2018. -The material in this repository has been updated and migrated to ethereum.org. +Most of the material in this repository has been updated and migrated to ethereum.org. This repository is due to be archived shortly. Please visit ethereum.org instead for current Ethereum information!

kivY;dL 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 Ich*1gFErZu=>Px# diff --git a/images/natspec4.png b/images/natspec4.png deleted file mode 100644 index 0cee92a72af893086fd93baff872850ceaa43a1e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 90201 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 I6R>^=*!ill;BnC;ux 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 diff --git a/images/natspec5.png b/images/natspec5.png deleted file mode 100644 index f20770941d49933d4b11159cf73abf080483dabc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 103151 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

kivY;dL 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 Ich*1gFErZu=>Px# diff --git a/images/natspec4.png b/images/natspec4.png deleted file mode 100644 index 0cee92a72af893086fd93baff872850ceaa43a1e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 90201 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 I6R>^=*!ill;BnC;ux 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 diff --git a/images/natspec5.png b/images/natspec5.png deleted file mode 100644 index f20770941d49933d4b11159cf73abf080483dabc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 103151 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