diff --git a/README.md b/README.md index 440a581..a605d5f 100644 --- a/README.md +++ b/README.md @@ -1,194 +1,3 @@ -# Draft EOS Token Sale Contract - -***DISCLAIMER: Everything contained in this repository is in draft form and subject to change at any time and provided for information purposes only. block.one does not guarantee the accuracy of the information contained in this repository and the information is provided “as is” with no representations or warranties, express or implied. This code is owned and copyrighted by block.one and cannot be used by anyone for any purpose other than testing on the Ethereum test network.*** - -This repository contains the draft source code for the EOS Token Sale. It is being released so that it may be reviewed by the community and deployed and tested by all on the Ethereum test network. - -**No information regarding the final terms and timing or properties of the sale have been released at this time.** - -## Description - -This draft contract manages the sale of a ERC-20 compatible token ("EOS") on the Ethereum (ETH) blockchain. - -The EOS Token Sale will distributed daily over about 341 days. 1,000,000,000 (one billion) EOS tokens will be minted at the start of the sale. These tokens will be split into different rolling windows of availability. The tokens available in a window will be split proportional to all contributions made during the window period. - -For example: - - 20 EOS are available during the window - Bob contributes 4 ETH - Alice contributes 1 ETH - Bob contributed 80% of the total contributions and gets 16 EOS - Alice contributed 20% of the total contributions and gets 4 EOS - -### Example Distribution Schedule - -1. 200,000,000 EOS (20%) will be available during a 5 day window from the time the contract is published. -2. 700,000,000 EOS (70%) will be split evenly into 350 consecutive 23 hour windows of 2,000,000 EOS tokens each starting after the initial window. -3. 100,000,000 EOS (10%) will be reserved for the founders and cannot be traded or transferred on the Ethereum network. - -#### 341 days after the creation of this contract the EOS ERC-20 token will be frozen and non transferrable. - - -## Rationale - -When designing the EOS distribution system, the primary goal was ensuring as fair and wide of a distribution as possible; we aim to achieve this by focusing on the following three objectives: - -### 1. Equal Opportunity -In order to ensure that everyone can participate, EOS are not sold for a fixed price; they are sold at a price determined by market demand for their acquisition. This is achieved by distributing a fixed amount of EOS (supply) proportionally toward the daily ETH proceeds (demand). Each window is 23 hours long which means that everyone in every timezone will have periodic opportunities to have favorable start and/or end times for a window regardless of their timezone. - -### 2. Broad Awareness -Distribution can only be as wide as the number of people that are aware of the ability to get involved. By stretching the distribution process out over the course of approximately 1 year, the community has the time to gather information and assess project merits before early stage windows of opportunity are closed. - -### 3. Fair and Auditable Incoming Value -An Ethereum smart contract proves the receipt of incoming value for the creation of each EOS token. This process: - - - Mimics the economics and distribution access of traditional PoW mining contributions - - Preserves the value lost to hardware and electricity for PoW - - Makes it easy for everyone to participate - - Eliminates unfair advantages associated with economies of scale - - -## Technical Risks - -This smart contract runs on the Ethereum network; therefore, you need to be aware of certain things. - -### 1. Block Production occurs at Random Times - -The block time is used to determine the window a transaction is credited to. The timing of block production is determined via proof of work so transactions submitted in the final second of a window may not get included when you think. To mitigate this, it is possible to use the interface to require the transaction to apply it to the current day or fail. - -### 2. Network Congestion - -The Ethereum network is prone to periodic congestion during which transactions can be delayed or lost. Some individuals may intentionally spam the Ethereum network in an attempt to gain an advantage. Do not assume Ethereum block producers will include your transaction when you want or that your tranasction will be included at all. This is a limitation of Ethereum and not the EOS Token Sale contract. - -### 3. Do not fund Token Sale Contract from an account you do not control - -Tokens are allocated to the account that sent them. If you send from an exchange or other account that you do not control then you may not be able to claim your EOS tokens without their help. - -### 4. Failing register a public key for your Ethereum account - -If you hold EOS tokens in an Etheruem account and fail to register a public key or lose the private key that maps to your registered public key, then your EOS tokens will not be part of the snapshot. - - -## FAQ - -### 1. How do I participate? - -The EOS Token Sale has not yet been started, but you can participate in our test sale now. - -The recommend way to participate in the EOS Token Sale contract is to use [our interface](https://eosio.github.io/eos-token-sale/) with the [Metamask Extension](https://metamask.io) in the Google Chrome browser. - -### 2. Why are tokens frozen after a year? - -The ERC-20 token is frozen so that there is not a moving target for generating a snapshot for generation of genesis block of an EOS.IO based blockchain. It also protects exchanges from people attempting to deposit or withdraw EOS ERC-20 tokens after the snapshot. - - -## Advanced Participation - -To participate in the EOS token sale, simply send ETH to the contract address during a window of your choice. - -The EOS tokens will be reserved for you to claim when the window completes. To claim the tokens, visit the [Ethereum Foundation Wallet](https://wallet.ethereum.org/) using an Ethereum-enabled browser (e.g. Metamask, Mist, Parity) or the [MyEtherWallet Contract Viewer](https://www.myetherwallet.com/#contracts) and load in your keyfile. If the user has never used Ethereum before, the [Metamask Extension](https://metamask.io) in the Google Chrome browser is the recommended Ethereum wallet. - -**Contract Address:** - - 0x123 - -**ABI / JSON Interface:** - - [{"constant":true,"inputs":[{"name":"day","type":"uint256"}],"name":"issueOnDay","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"},{"name":"","type":"address"}],"name":"claimed","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"owner_","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"issueFirstDay","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"EOS20","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"},{"name":"","type":"address"}],"name":"userBuys","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"freeze","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"keys","outputs":[{"name":"","type":"bytes"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"startTime","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"authority_","type":"address"}],"name":"setAuthority","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"dailyTotals","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"key","type":"bytes"}],"name":"register","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"issuePerDay","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"buy","outputs":[],"payable":true,"type":"function"},{"constant":true,"inputs":[],"name":"today","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"authority","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"}],"name":"dayFor","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"day","type":"uint256"},{"name":"who","type":"address"}],"name":"claim","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"collect","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"numberOfDays","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[{"name":"numberOfDays_","type":"uint256"},{"name":"issuePerDay_","type":"uint256"},{"name":"startTime_","type":"uint256"}],"payable":false,"type":"constructor"},{"payable":true,"type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"day","type":"uint256"},{"indexed":false,"name":"who","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"LogClaim","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"wad","type":"uint256"}],"name":"LogCollect","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"who","type":"address"},{"indexed":false,"name":"key","type":"bytes"}],"name":"LogRegister","type":"event"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"guy","type":"address"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":false,"name":"wad","type":"uint256"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"LogNote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"authority","type":"address"}],"name":"LogSetAuthority","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"}],"name":"LogSetOwner","type":"event"}] - -If using the Ethereum Foundation Wallet, the instructions to claim are here: - -* Click `Contracts` -* Click `Watch Contract` -* For name, enter EOSSale -* For address and JSON Interface, enter the information above and click `OK` -* Click on your new contract -* Click `ClaimAll` from the function dropdown -* Enter your address in the `who` field. -* Click `Execute` and confirm transaction - -If you are using MyEtherWallet, the instructions to claim are here: - -* For address and ABI / JSON Interface, enter the information above and click Access -* Click ClaimAll from the function dropdown and enter your address in the `who` field -* Load in your wallet file and unlock it -* Click `Write` -* set `Amount to Send` to `0` and `Gas Limit` to `3141592` -* Click Generate Transaction - -The EOS tokens should now be in your wallet. - -## To Transfer EOS to an Exchange - -Load the token details into the Ethereum Foundation Wallet or MyEtherWallet. The token details are: - -**Address:** - - 0x123 - -**Decimals:** - - 18 - -**Symbol:** - - EOS - -**Name:** - - EOS - -For Ethereum Foundation Wallet: - -* Click `Contracts` -* Click `Watch Token` -* Enter the token address from above -* The rest of the details should auto-populate. -* Click `OK` -* The Token should now be an option on the Send page of the wallet. You can now transfer it to any address. - -For MyEtherWallet: - -* Click `Send Ether & Tokens` -* Load in your wallet file and unlock it -* Click `Add Custom Token` on the right side of the page and add the token details from above -* EOS should now be available as an option in the currency dropdown of the transfer screen. You can now transfer it to any address. - -## Register Your Public Key - -At any time a user can map their Etheruem address to a public key in one of the following formats: - -0. EOS Public Keys - EOS4yfYEjUodfs.......DfavaddbvD -1. Steem Public Keys - STM4yfYEjUoey4.......UaSt2Sx9W4 -2. BitShares Public Keys - BTS5WaszCsqVN9.......Wz47B3wUqa - - -## Command Line Usage - -This README assumes you have an Ethereum blockchain client installed. If you don't have one, [Parity](https://parity.io/parity.html) is recommended. - -### Getting set up - -You will need the [Nix Package Manager](https://nixos.org/nix/) to work with the EOS contracts from the command line. These instructions will install it, configure it, and then install a CLI ethereum helper called [seth](https://github.com/dapphub/seth) - - $ curl https://nixos.org/nix/install | sh - $ nix-channel --add https://nix.dapphub.com/pkgs/dapphub - $ nix-channel --update - $ nix-env -i seth - -### Commands - -**Buying Tokens:** - - $ seth send -F -G 4600000 --value=$(seth --to-wei ETH) "buy()" - -**Claiming tokens:** - - $ seth send -F -G 4600000 "claim(address)" - -**Registering public key:** - - $ seth send -F -G 4600000 "register(bytes)" - - -Copyright © 2017 block.one. All rights reserved. +This will generate a private and public key pair for the EOS chain. The code is not mine. + It is forked from the code the EOS team built. The difference is that this works in any browser without the web3 dependency. + It will work in any browser and you don't need any plugins. \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index 287af0f..79af823 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,7 +1,7 @@ -EOS Token Sale +EOS Key Generation @@ -10,14 +10,13 @@ - - - +
-

EOS Token Sale

+

EOS Key Generation

Loading...

diff --git a/docs/index.js b/docs/index.js index b292a5d..915d7f3 100644 --- a/docs/index.js +++ b/docs/index.js @@ -1,5 +1,9 @@ +var state +let privateKeyPair = null + //var eos_sale_address_kovan = "0xda68e806918125abe379e35c46df0e71dfbfeea8" //var eos_token_address_kovan = "0x74b279820bdf69bed7e99fd1000df2e1983a5caf" +/* var eos_sale_address_kovan = "0xc75c91214a4e9c1b8f055e61d8577cd988561b47" var eos_token_address_kovan = "0xa49047938b5a3117c22dab31c1be03973b1d2bca" var eos_sale, eos_token @@ -34,23 +38,10 @@ function lament(error) { } } -function showPane(name) { - hidePanes() - show(`${name}-pane`) - hide(`${name}-link`) -} - -function hidePanes() { - for (var x of "generate transfer buy register".split(" ")) { - try { - show(`${x}-link`) - hide(`${x}-pane`) - } catch (error) {} - } -} +*/ // onload = () => setTimeout(() => { - if (!window.web3) { + /*if (!window.web3) { byId("app").innerHTML = `
@@ -83,8 +74,9 @@ function hidePanes() { } })) } -// }, 500) +// }, 500)*/ +/* function refresh() { return new Promise((resolve, reject) => { web3.eth.getBlock("latest", hopefully(block => { @@ -157,7 +149,7 @@ function refresh() { })) })) }) -} +}*/ var render = ({ time, days, unclaimed, today, @@ -165,114 +157,34 @@ var render = ({ }) =>

- The EOS Token Sale will take place over about 341 days. - 1,000,000,000 (one billion) EOS tokens will be created at the - start of the sale, 100,000,000 EOS are allocated to block.one and cannot be - transfered. - - The remaining 900,000,000 EOS will be split into different rolling windows of - availability. The EOS tokens in a given window will be split - proportionally to all ETH contributions made during that window. - 200,000,000 EOS will be sold in the first window, lasting five days. - The remaining 700,000,000 will be divided equally into 350 windows, each - lasting 23 hours and distributing 2,000,000 EOS. Contributions can be made to - any future window, but the EOS cannot be claimed until the window closes. + This will generate a private and public key pair for the EOS chain. The code is not mine. + It is forked from the code the EOS team built. The difference is that this works in any browser without the web3 dependency. + It will work in any browser and you don't need any plugins. I've also removed everything else except the key generation bits. - Once a window closes, the EOS tokens allocated to that window are - available to be claimed. - - You must generate and register an EOS Public Key or it will not be possible for - anyone to include your EOS tokens in the genesis block of any future blockchain's - based on EOS.IO software. - - By sending ETH to this contract you agree to the Terms & Conditions and Purchase Agreement.

- - For more details, please review the token sale contract source - code. - - - Last updated {moment(time * 1000).format("LTS")} - - - {web3.eth.accounts[0] ?
+ Source code can be reviewed here: https://github.com/Nadejde/eos-token-sale. +
+
+ If you found this helpful please consider making a small donation
+ ETH: 0x0bbe518debf97fb2e27d955b050cbd1e8ca90264
+ EOS: gqztenjzgege
+
- - - - - - - - - - - - - - - -
Ethereum account - {web3.eth.accounts[0]} -
EOS public key - {publicKey ? - {publicKey} - {" "} - (generate(), event.preventDefault())}> - Change your EOS key - - : - - (no EOS key registered) - + (generate(), event.preventDefault())}> Generate EOS key - } -
Token balances - {formatETH(eth_balance.div(WAD))} ETH - (event.preventDefault(), showPane('buy'))}> - Buy EOS tokens - -
- {formatEOS(unclaimed)} EOS (unclaimed) - - - - Claiming tokens... -
- {formatEOS(eos_balance.div(WAD))} EOS - (event.preventDefault(), showPane('transfer'))}> - Transfer EOS tokens - -
-
(event.preventDefault(), generateConfirm())}> +
Generating key... @@ -311,27 +223,20 @@ var render = ({ + + + Private key - - - Confirm private key - -

- - Private key does not match - -

+ + @@ -342,180 +247,77 @@ var render = ({ when the sale ends.

- - -
-
-
-

{publicKey ? "Change" : "Register"} EOS public key

- - - - - - - -
Public key -   -
- - - {publicKey ? "Changing" : "Registering"} key... - - -
-
(event.preventDefault(), buy())}> -

Buy EOS tokens

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Sale window - -
Closing - {days[buyWindow].ends.fromNow()} -
EOS for sale - {formatEOS(days[buyWindow].createOnDay)} EOS -
Total ETH - {formatETH(days[buyWindow].dailyTotal)} ETH -
Your ETH - {formatETH(days[buyWindow].userBuys)} ETH -
Effective price - {days[buyWindow].price.toFormat(9)} ETH/EOS -
Send ETH - - {" ETH"} - - - - Sending ETH... - - -
-
-
(event.preventDefault(), transfer())}> -

Transfer EOS tokens to another Ethereum account

- - - - - - - - - -
Recipient account - -
Transfer amount - - {" EOS"} - - - - Transferring tokens... - - -
-
-
- - - - - - - - - - - - - - {days.map((day, i) => - - - - - - - - - - )} - -
WindowEOS for saleTotal ETHEffective priceClosingYour ETHYour EOS
- #{day.name} - {i == Number(today) ? "" : ""} - {formatEOS(day.createOnDay)} EOS{formatETH(day.dailyTotal)} ETH{day.dailyTotal == 0 ? "n/a" : ( - `${day.price.toFormat(9)} ETH/EOS` - )}{day.ends.fromNow()}{formatETH(day.userBuys)} ETH - {formatEOS(day.received)} EOS - {i >= Number(today) - && *} -
-
:
-

Ethereum account not found

+
+
- It looks like an Ethereum client is available in your - browser, but I couldn’t find any accounts. - If you’re using MetaMask, you may need to unlock - your account. You can also try disabling and re-enabling - the MetaMask plugin by going to chrome://extensions. +state = Object.assign({}, state, 0) +ReactDOM.render(render(state), byId("app")) -
} -
+function generate() { + showPane('generate') + + setTimeout(() => { + privateKeyPair = genKeyPair() + hide("generate-progress") + byId("generate-pubkey").innerHTML = privateKeyPair.pubkey + byId("generate-pubkey-error").innerHTML = privateKeyPair.pubkeyError + byId("generate-privkey").innerHTML = privateKeyPair.privkey + byId("generate-privkey-error").innerHTML = privateKeyPair.privkeyError + show("generate-confirm") + }) +} +function genKeyPair() { + var {PrivateKey, PublicKey} = eos_ecc + var d = PrivateKey.randomKey() + var privkey = d.toWif() + var pubkey = d.toPublic().toString() + + var pubkeyError = null + try { + PublicKey.fromStringOrThrow(pubkey) + } catch(error) { + console.log('pubkeyError', error, pubkey) + pubkeyError = error.message + ' => ' + pubkey + } + + var privkeyError = null + try { + var pub2 = PrivateKey.fromWif(privkey).toPublic().toString() + if(pubkey !== pub2) { + throw {message: 'public key miss-match: ' + pubkey + ' !== ' + pub2} + } + } catch(error) { + console.log('privkeyError', error, privkey) + privkeyError = error.message + ' => ' + privkey + } + + if(privkeyError || pubkeyError) { + privkey = 'DO NOT USE' + pubkey = 'DO NOT USE' + } + + return {pubkey, privkey, pubkeyError, privkeyError} +} + +function showPane(name) { + hidePanes() + show(`${name}-pane`) + hide(`${name}-link`) +} + +function hidePanes() { + for (var x of "generate transfer buy register".split(" ")) { + try { + show(`${x}-link`) + hide(`${x}-pane`) + } catch (error) {} + } +} + +/* function buy() { byId("buy-button").classList.add("hidden") byId("buy-progress").classList.remove("hidden") @@ -563,29 +365,11 @@ function entropyEvent(e) { console.log('onEntropyEvent Unknown', e.type, e) } -function generate() { - showPane('generate') - show("generate-progress") - hide("generate-confirm") - setTimeout(() => { - privateKeyPair = genKeyPair() - hide("generate-progress") - byId("generate-pubkey").innerHTML = privateKeyPair.pubkey - byId("generate-privkey").innerHTML = privateKeyPair.privkey - byId("generate-confirm-input").value = "" - show("generate-confirm") - }) -} -let privateKeyPair = null -function genKeyPair() { - var {PrivateKey} = eos_ecc - var d = PrivateKey.randomKey() - var privkey = d.toWif() - var pubkey = d.toPublic().toString() - return {pubkey, privkey} -} + + + function generateConfirm() { const confirmPriv = getValue("generate-confirm-input") @@ -656,3 +440,4 @@ function update(x) { state = Object.assign({}, state, x) ReactDOM.render(render(state), byId("app")) } +*/