diff --git a/ethcore/res/ethereum/eosc.json b/ethcore/res/ethereum/eosc.json new file mode 100644 index 00000000000..aef5138cdfb --- /dev/null +++ b/ethcore/res/ethereum/eosc.json @@ -0,0 +1,92 @@ +{ + "name": "EOS Classic", + "dataDir": "eosc", + "engine": { + "Ethash": { + "params": { + "minimumDifficulty": "0x020000", + "difficultyBoundDivisor": "0x0800", + "durationLimit": "0x0d", + "blockReward": { + "0": "0x16c4abbebea0100000", + "150000": "0x246ddf97976680000" + }, + "homesteadTransition": 0, + "bombDefuseTransition": "0x64", + "eoscTransition": 0, + "eoscTreasuryAddress": "0x258183b0F3F50ff55812d73cc56BF86b8b0C1618", + "eoscTreasuryReward": "0x68155a43676e00000", + "eoscStakeAddress": "0x9a283bDA5EFe121c39826616A646F4082166ed16", + "eoscStakeReward": "0x340aad21b3b700000", + "neweoscTransition": 150000, + "neweoscFundAddress": "0x258183b0F3F50ff55812d73cc56BF86b8b0C1618", + "neweoscFundReward": "0xa688906bd8b00000", + "neweoscPOSAddress": "0x9a283bDA5EFe121c39826616A646F4082166ed16", + "neweoscPOSReward": "0x53444835ec580000", + "eip100bTransition": 500000, + "ecip1017EraRounds": 2500000, + "eosc1017EraRounds": 2500000 + } + } + }, + "params": { + "gasLimitBoundDivisor": "0x0400", + "registrar": "0x0000000000000000000000000000000000000000", + "accountStartNonce": "0x00", + "maximumExtraDataSize": "0x20", + "minGasLimit": "0x1388", + "networkID": "0x14", + "chainID": "0x14", + "eip150Transition": 0, + "eip160Transition": 0, + "eip161abcTransition": 0, + "eip161dTransition": 0, + "eip155Transition": 0, + "eip98Transition": "0x7fffffffffffff", + "maxCodeSize": 24576, + "maxCodeSizeTransition": 0, + "eip140Transition": 500000, + "eip211Transition": 500000, + "eip214Transition": 500000, + "eip658Transition": 500000 + }, + "genesis": { + "seal": { + "ethereum": { + "nonce": "0x0000000000000042", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "difficulty": "0x400000000", + "author": "0x0000000000000000000000000000000000000000", + "timestamp": "0x00", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "0x3230313820454f5320436c61737369632050726f6a656374", + "gasLimit": "0x09eb100", + "stateRoot": "0x2a5c55f9828f4471f59ef743765913371659249bd0a750cabb361c6fd443819b" + }, + "nodes": [ + "enode://68141aad001d5984bdd6c935e5f7b89fb55fd6a59585658dcfa6f6ed1b020977107e2baaf0e157bc65afd63e9a6d45f636f6afc3c6208e9c9da185a0ec06f1dd@13.125.38.131:25252", + "enode://6d5b4fe7e9fc27616b3bdc272ea89c7cbe368432bf299b4597002ad9c3aff65a1bc570c032a2accb03ca3d2955074956758411d89de6ab5feef2d10a8f963a6a@13.124.177.177:25252", + "enode://b9f636ae1b9bd29b09438de87fc2bca9631bee0f35d145afd0f9fa522366a07d8ca5dd2b1ee89a0f86744b7a28e1cba1566c720238690e596d57f406bf01f0e7@13.209.67.52:25252", + "enode://1b3f420caacf4fc868befb32199560d150777054bf06e2e557444d1e9bce4b704ca012ef10d89f124f04c2152dd1ccb0ad219ff4f535bd36e18f915692801775@13.125.1.40:25252", + "enode://4ac82fd3d0ea65e339e4aac17ff7a05ffcb1a3e218523003e07d7217cb6eee4b76a7f7a091c7f6be1dbd3cf3f0b616b7b8feeab0f740dd30b14921db4a84ca88@13.209.41.126:25252", + "enode://b34facef380fde111908348207320b56a75fece06c6c1aef31b35903ec8b2195861c3833c45b6c91019c9ce35423f8e37b04db6e4419d0eea48fff42ee4ee812@13.209.75.168:25252", + "enode://14e28c54a0e37dcc53db3f69d1cee2451203f9463ff3e02441f8a3078e249601c21485f71d06422fe99574670fe09d6379a63d0bafa796bcdedb1d4822c064eb@13.209.77.72:25252", + "enode://747958fcb02c6ed0d2269d96fb02bb43e7e08b2c47545d7396b71b265845a658a274a68409e1c674d9feded17641a4788c61c7feed109e62602ea13d3121c355@54.180.8.50:30303", + "enode://a3bc90ad80c66fcdc9ee048040444261d740bdafb1aad71020ac8c3b3918819ac75628493527831feab2cddbebbfd782a538f1f889386c9524a9053ff3385ba8@13.125.38.131:30303" + ], + "accounts": { + "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, + "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, + "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, + "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, + "0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": 500000, "pricing": { "modexp": { "divisor": 20 } } } }, + "0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": 500000, "pricing": { "linear": { "base": 500, "word": 0 } } } }, + "0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": 500000, "pricing": { "linear": { "base": 40000, "word": 0 } } } }, + "0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": 500000, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }, + "0fe92aba74cb679b252c320161971341aa003e14": { + "balance": "900000000000000000000000000" + } + } +} diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 3bb56315704..1c98b534623 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -116,6 +116,28 @@ pub struct EthashParams { pub expip2_transition: u64, /// EXPIP-2 duration limit pub expip2_duration_limit: u64, + /// EOS Classic transition block + pub eosc_transition: u64, + /// EOS Classic Treasury Address + pub eosc_treasury_address: Address, + /// EOS Classic Treasury reward + pub eosc_treasury_reward: U256, + /// EOS Classic Stake Address + pub eosc_stake_address: Address, + /// EOS Classic Stake reward + pub eosc_stake_reward: U256, + /// NewEOSC transition block + pub neweosc_transition: u64, + /// NewEOSC Fund Address + pub neweosc_fund_address: Address, + /// NewEOSC Fund reward + pub neweosc_fund_reward: U256, + /// NewEOSC POS Address + pub neweosc_pos_address: Address, + /// NewEOSC POS reward + pub neweosc_pos_reward: U256, + /// Total block number for one EOSC-1017 era. + pub eosc1017_era_rounds: u64, /// Block reward contract transition block. pub block_reward_contract_transition: u64, /// Block reward contract. @@ -168,6 +190,17 @@ impl From for EthashParams { }), expip2_transition: p.expip2_transition.map_or(u64::max_value(), Into::into), expip2_duration_limit: p.expip2_duration_limit.map_or(30, Into::into), + eosc_transition: p.eosc_transition.map_or(u64::max_value(), Into::into), + eosc_treasury_address: p.eosc_treasury_address.map_or_else(Address::new, Into::into), + eosc_treasury_reward: p.eosc_treasury_reward.map_or_else(Default::default, Into::into), + eosc_stake_address: p.eosc_stake_address.map_or_else(Address::new, Into::into), + eosc_stake_reward: p.eosc_stake_reward.map_or_else(Default::default, Into::into), + neweosc_transition: p.neweosc_transition.map_or(u64::max_value(), Into::into), + neweosc_fund_address: p.neweosc_fund_address.map_or_else(Address::new, Into::into), + neweosc_fund_reward: p.neweosc_fund_reward.map_or_else(Default::default, Into::into), + neweosc_pos_address: p.neweosc_pos_address.map_or_else(Address::new, Into::into), + neweosc_pos_reward: p.neweosc_pos_reward.map_or_else(Default::default, Into::into), + eosc1017_era_rounds: p.eosc1017_era_rounds.map_or(u64::max_value(), Into::into), block_reward_contract_transition: p.block_reward_contract_transition.map_or(0, Into::into), block_reward_contract: match (p.block_reward_contract_code, p.block_reward_contract_address) { (Some(code), _) => Some(BlockRewardContract::new_from_code(Arc::new(code.into()))), @@ -299,6 +332,40 @@ impl Engine for Arc { rewards.push((ubi_contract, RewardKind::External, ubi_reward)); rewards.push((dev_contract, RewardKind::External, dev_reward)); + } else if number >= self.ethash_params.eosc1017_era_rounds { + let fund_address = self.ethash_params.neweosc_fund_address; + let fund_reward = self.ethash_params.neweosc_fund_reward; + let pos_address = self.ethash_params.neweosc_pos_address; + let pos_reward = self.ethash_params.neweosc_pos_reward; + + let eras_rounds = self.ethash_params.eosc1017_era_rounds; + let (eras, fund_reward) = eosc1017_eras_fund_reward(eras_rounds, fund_reward, number); + let (eras, pos_reward) = eosc1017_eras_pos_reward(eras_rounds, pos_reward, number); + + rewards.push((author, RewardKind::Author, result_block_reward)); + rewards.push((fund_address, RewardKind::External, fund_reward)); + rewards.push((pos_address, RewardKind::External, pos_reward)); + + } else if number >= self.ethash_params.neweosc_transition { + let fund_address = self.ethash_params.neweosc_fund_address; + let fund_reward = self.ethash_params.neweosc_fund_reward; + let pos_address = self.ethash_params.neweosc_pos_address; + let pos_reward = self.ethash_params.neweosc_pos_reward; + + rewards.push((author, RewardKind::Author, result_block_reward)); + rewards.push((fund_address, RewardKind::External, fund_reward)); + rewards.push((pos_address, RewardKind::External, pos_reward)); + + } else if number >= self.ethash_params.eosc_transition { + let treasury_address = self.ethash_params.eosc_treasury_address; + let treasury_reward = self.ethash_params.eosc_treasury_reward; + let stake_address = self.ethash_params.eosc_stake_address; + let stake_reward = self.ethash_params.eosc_stake_reward; + + rewards.push((author, RewardKind::Author, result_block_reward)); + rewards.push((treasury_address, RewardKind::External, treasury_reward)); + rewards.push((stake_address, RewardKind::External, stake_reward)); + } else { rewards.push((author, RewardKind::Author, result_block_reward)); } @@ -507,6 +574,36 @@ fn ecip1017_eras_block_reward(era_rounds: u64, mut reward: U256, block_number:u6 (eras, reward) } +fn eosc1017_eras_fund_reward(eosc_era_rounds: u64, mut fund_reward: U256, block_number:u64) -> (u64, U256) { + let eras = if block_number != 0 && block_number % eosc_era_rounds == 0 { + block_number / eosc_era_rounds - 1 + } else { + block_number / eosc_era_rounds + }; + let mut divi = U256::from(1); + for _ in 0..eras { + fund_reward = fund_reward * U256::from(4); + divi = divi * U256::from(5); + } + fund_reward = fund_reward / divi; + (eras, fund_reward) +} + +fn eosc1017_eras_pos_reward(eosc_era_rounds: u64, mut pos_reward: U256, block_number:u64) -> (u64, U256) { + let eras = if block_number != 0 && block_number % eosc_era_rounds == 0 { + block_number / eosc_era_rounds - 1 + } else { + block_number / eosc_era_rounds + }; + let mut divi = U256::from(1); + for _ in 0..eras { + pos_reward = pos_reward * U256::from(4); + divi = divi * U256::from(5); + } + pos_reward = pos_reward / divi; + (eras, pos_reward) +} + #[cfg(test)] mod tests { use std::str::FromStr; @@ -557,6 +654,17 @@ mod tests { mcip3_dev_contract: "0000000000000000000000000000000000000001".into(), expip2_transition: u64::max_value(), expip2_duration_limit: 30, + eosc_transition: u64::max_value(), + eosc_treasury_address: "0000000000000000000000000000000000000001".into(), + eosc_treasury_reward: 0.into(), + eosc_stake_address: "0000000000000000000000000000000000000001".into(), + eosc_stake_reward: 0.into(), + neweosc_transition: u64::max_value(), + neweosc_fund_address: "0000000000000000000000000000000000000001".into(), + neweosc_fund_reward: 0.into(), + neweosc_pos_address: "0000000000000000000000000000000000000001".into(), + neweosc_pos_reward: 0.into(), + eosc1017_era_rounds: u64::max_value(), block_reward_contract: None, block_reward_contract_transition: 0, difficulty_bomb_delays: BTreeMap::new(), diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs index 6d33e6d2d03..2b2df466243 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -87,6 +87,11 @@ pub fn new_social<'a, T: Into>>(params: T) -> Spec { load(params.into(), include_bytes!("../../res/ethereum/social.json")) } +/// Create a new EOS Classic mainnet chain spec. +pub fn new_eosc<'a, T: Into>>(params: T) -> Spec { + load(params.into(), include_bytes!("../../res/ethereum/eosc.json")) +} + /// Create a new Olympic testnet chain spec. pub fn new_olympic<'a, T: Into>>(params: T) -> Spec { load(params.into(), include_bytes!("../../res/ethereum/olympic.json")) diff --git a/json/src/spec/ethash.rs b/json/src/spec/ethash.rs index ee985fe1c49..c6004b5ffd9 100644 --- a/json/src/spec/ethash.rs +++ b/json/src/spec/ethash.rs @@ -134,6 +134,50 @@ pub struct EthashParams { /// EXPIP-2 duration limit #[serde(rename="expip2DurationLimit")] pub expip2_duration_limit: Option, + + /// EOS Classic transition block + #[serde(rename="eoscTransition")] + pub eosc_transition: Option, + + /// EOS Classic Treasury Address + #[serde(rename="eoscTreasuryAddress")] + pub eosc_treasury_address: Option
, + + /// EOS Classic Treasury reward + #[serde(rename="eoscTreasuryReward")] + pub eosc_treasury_reward: Option, + + /// EOS Classic Stake Address + #[serde(rename="eoscStakeAddress")] + pub eosc_stake_address: Option
, + + /// EOS Classic Stake reward + #[serde(rename="eoscStakeReward")] + pub eosc_stake_reward: Option, + + /// NewEOSC transition block + #[serde(rename="neweoscTransition")] + pub neweosc_transition: Option, + + /// NewEOSC Fund Address + #[serde(rename="neweoscFundAddress")] + pub neweosc_fund_address: Option
, + + /// NewEOSC Fund reward + #[serde(rename="neweoscFundReward")] + pub neweosc_fund_reward: Option, + + /// NewEOSC POS Address + #[serde(rename="neweoscPOSAddress")] + pub neweosc_pos_address: Option
, + + /// NewEOSC POS reward + #[serde(rename="neweoscPOSReward")] + pub neweosc_pos_reward: Option, + + /// See main EthashParams docs. + #[serde(rename="eosc1017EraRounds")] + pub eosc1017_era_rounds: Option, } /// Ethash engine deserialization. @@ -244,6 +288,17 @@ mod tests { mcip3_dev_contract: None, expip2_transition: None, expip2_duration_limit: None, + eosc_transition: None, + eosc_treasury_address: None, + eosc_treasury_reward: None, + eosc_stake_address: None, + eosc_stake_reward: None, + neweosc_transition: None, + neweosc_fund_address: None, + neweosc_fund_reward: None, + neweosc_pos_address: None, + neweosc_pos_reward: None, + eosc1017_era_rounds: None, difficulty_bomb_delays: None, } }); @@ -289,6 +344,17 @@ mod tests { mcip3_dev_contract: None, expip2_transition: None, expip2_duration_limit: None, + eosc_transition: None, + eosc_treasury_address: None, + eosc_treasury_reward: None, + eosc_stake_address: None, + eosc_stake_reward: None, + neweosc_transition: None, + neweosc_fund_address: None, + neweosc_fund_reward: None, + neweosc_pos_address: None, + neweosc_pos_reward: None, + eosc1017_era_rounds: None, difficulty_bomb_delays: None, } }); diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index 899b3932d82..b2dfe1a13f8 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -288,7 +288,7 @@ usage! { ARG arg_chain: (String) = "foundation", or |c: &Config| c.parity.as_ref()?.chain.clone(), "--chain=[CHAIN]", - "Specify the blockchain type. CHAIN may be either a JSON chain specification file or ethereum, classic, poacore, tobalaba, expanse, musicoin, ellaism, easthub, social, olympic, morden, ropsten, kovan, poasokol, testnet, or dev.", + "Specify the blockchain type. CHAIN may be either a JSON chain specification file or ethereum, classic, poacore, tobalaba, expanse, musicoin, ellaism, easthub, social, eosc, olympic, morden, ropsten, kovan, poasokol, testnet, or dev.", ARG arg_keys_path: (String) = "$BASE/keys", or |c: &Config| c.parity.as_ref()?.keys_path.clone(), "--keys-path=[PATH]", diff --git a/parity/params.rs b/parity/params.rs index df924aee39e..d40cac977fb 100644 --- a/parity/params.rs +++ b/parity/params.rs @@ -40,6 +40,7 @@ pub enum SpecType { Ellaism, Easthub, Social, + EOSC, Olympic, Morden, Ropsten, @@ -69,6 +70,7 @@ impl str::FromStr for SpecType { "ellaism" => SpecType::Ellaism, "easthub" => SpecType::Easthub, "social" => SpecType::Social, + "eosc" => SpecType::EOSC, "olympic" => SpecType::Olympic, "morden" | "classic-testnet" => SpecType::Morden, "ropsten" => SpecType::Ropsten, @@ -93,6 +95,7 @@ impl fmt::Display for SpecType { SpecType::Ellaism => "ellaism", SpecType::Easthub => "easthub", SpecType::Social => "social", + SpecType::EOSC => "eosc", SpecType::Olympic => "olympic", SpecType::Morden => "morden", SpecType::Ropsten => "ropsten", @@ -117,6 +120,7 @@ impl SpecType { SpecType::Ellaism => Ok(ethereum::new_ellaism(params)), SpecType::Easthub => Ok(ethereum::new_easthub(params)), SpecType::Social => Ok(ethereum::new_social(params)), + SpecType::EOSC => Ok(ethereum::new_eosc(params)), SpecType::Olympic => Ok(ethereum::new_olympic(params)), SpecType::Morden => Ok(ethereum::new_morden(params)), SpecType::Ropsten => Ok(ethereum::new_ropsten(params)),