diff --git a/Cargo.lock b/Cargo.lock
index c49662d9772d4..ce26093f6c1ad 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -193,6 +193,11 @@ name = "bs58"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+[[package]]
+name = "byte-num"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
[[package]]
name = "byte-tools"
version = "0.2.0"
@@ -1918,7 +1923,7 @@ dependencies = [
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2777,6 +2782,8 @@ dependencies = [
name = "substrate-runtime-primitives"
version = "0.1.0"
dependencies = [
+ "byte-num 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ed25519 0.1.0",
"integer-sqrt 0.1.0 (git+https://github.com/paritytech/integer-sqrt-rs.git)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2828,6 +2835,8 @@ dependencies = [
name = "substrate-runtime-staking"
version = "0.1.0"
dependencies = [
+ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ed25519 0.1.0",
"hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3720,6 +3729,7 @@ dependencies = [
"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400"
"checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab"
"checksum bs58 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e6ea4851598d7433fbdba71fa2509d9b0df68124b9c0effe7588f5149692d9f"
+"checksum byte-num 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ac0bdba75808434f04270f3b7976ea6a662dc367d264feb54c5953258d59c66"
"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
"checksum byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "96c8b41881888cc08af32d47ac4edd52bc7fa27fef774be47a92443756451304"
"checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9"
diff --git a/substrate/runtime-support/src/dispatch.rs b/substrate/runtime-support/src/dispatch.rs
index 9b26493839bff..aab0e3b551e2c 100644
--- a/substrate/runtime-support/src/dispatch.rs
+++ b/substrate/runtime-support/src/dispatch.rs
@@ -192,6 +192,37 @@ macro_rules! decl_dispatch {
$($rest)*
}
};
+ // WITH MANY TRAIT BOUNDS
+ (
+ impl for $mod_type:ident<$trait_instance:ident: $trait_name:ident>;
+ $(#[$attr:meta])*
+ pub enum $call_type:ident where aux: $aux_type:ty,
+ $($tr:ident : $bound:ty)*
+ {
+ $(
+ fn $fn_name:ident(aux,
+ $(
+ , $param_name:ident : $param:ty
+ )*
+ ) -> $result:ty
+ = $id:expr ;
+ )*
+ }
+ $($rest:tt)*
+ ) => {
+ __decl_dispatch_module_with_aux! {
+ impl for $mod_type<$trait_instance: $trait_name>;
+ $(#[$attr])*
+ pub enum $call_type where $($tr : $bound),* ;
+ $(
+ fn $fn_name(aux $(, $param_name: $param )*) -> $result = $id;
+ )*
+ }
+ decl_dispatch! {
+ impl for $mod_type<$trait_instance: $trait_name>;
+ $($rest)*
+ }
+ };
// BASE CASE
(
impl for $mod_type:ident<$trait_instance:ident: $trait_name:ident>;
diff --git a/substrate/runtime/primitives/Cargo.toml b/substrate/runtime/primitives/Cargo.toml
index e7adc094d6789..d622094cdb9db 100644
--- a/substrate/runtime/primitives/Cargo.toml
+++ b/substrate/runtime/primitives/Cargo.toml
@@ -14,7 +14,9 @@ substrate-primitives = { path = "../../primitives", default_features = false }
substrate-runtime-std = { path = "../../runtime-std", default_features = false }
substrate-runtime-io = { path = "../../runtime-io", default_features = false }
substrate-runtime-support = { path = "../../runtime-support", default_features = false }
+ed25519 = { path = "../../ed25519", default_features = false }
log = {version = "0.3", optional = true }
+byte-num = "0.1"
[dev-dependencies]
serde_json = "1.0"
diff --git a/substrate/runtime/primitives/src/address_format.rs b/substrate/runtime/primitives/src/address_format.rs
new file mode 100644
index 0000000000000..7c62f868522f7
--- /dev/null
+++ b/substrate/runtime/primitives/src/address_format.rs
@@ -0,0 +1,79 @@
+// Copyright 2017 Parity Technologies (UK) Ltd.
+// This file is part of Substrate Demo.
+
+// Substrate Demo is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Substrate Demo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Substrate Demo. If not, see .
+
+use byte_num::convert::IntoAscii;
+use testing::Digest;
+use substrate_primitives::H256;
+use generic::Digest as GenericDigest;
+use ed25519::Public;
+
+#[derive(Clone, Debug)]
+pub struct SS58Compatible ( pub Public);
+
+pub trait SS58: Into {
+ fn encode(self) -> String {
+ self.into().0.to_ss58check()
+ }
+}
+
+impl From for SS58Compatible {
+ fn from(x: u64) -> Self {
+ SS58Compatible (Public::from_slice(&x.itoa()))
+ }
+}
+
+impl SS58 for u64 {}
+
+impl From for SS58Compatible {
+ fn from(x: Digest) -> Self {
+ SS58Compatible (Public::from_slice(&x
+ .logs
+ .iter()
+ .map(|digest| digest.itoa())
+ .flatten()
+ .collect::>()
+ ))
+ }
+}
+impl SS58 for Digest {}
+
+impl From for SS58Compatible {
+ fn from(x: H256) -> Self {
+ SS58Compatible (Public::from_slice(&x[..]))
+ }
+}
+
+impl SS58 for H256 {}
+
+impl> From> for SS58Compatible where
+ Vec : From>
+{
+ fn from(x: GenericDigest- ) -> Self {
+ SS58Compatible (Public::from_slice(Vec::from(x.logs).as_slice()))
+ }
+}
+
+impl> SS58 for GenericDigest
- where
+ Vec: From>
+{}
+
+impl> From> for Vec
+{
+ fn from(x: GenericDigest
- ) -> Self {
+ x.logs.into_iter().map(|element| Into::::into(element)).collect()
+ }
+
+}
diff --git a/substrate/runtime/primitives/src/generic.rs b/substrate/runtime/primitives/src/generic.rs
index f1a9448c8fafc..5316b9908c5ba 100644
--- a/substrate/runtime/primitives/src/generic.rs
+++ b/substrate/runtime/primitives/src/generic.rs
@@ -317,7 +317,7 @@ impl Encode for Header where
impl traits::Header for Header where
Number: Member + ::rstd::hash::Hash + Copy + Codec + MaybeDisplay + SimpleArithmetic + Codec,
Hash: HashT,
- DigestItem: Member + Default + Codec,
+ DigestItem: Member + Default + Codec + Into>,
Hash::Output: Default + ::rstd::hash::Hash + Copy + Member + MaybeDisplay + SimpleBitOps + Codec,
{
type Number = Number;
diff --git a/substrate/runtime/primitives/src/lib.rs b/substrate/runtime/primitives/src/lib.rs
index a1ff760f7608f..08d6d0a2b4d56 100644
--- a/substrate/runtime/primitives/src/lib.rs
+++ b/substrate/runtime/primitives/src/lib.rs
@@ -40,6 +40,8 @@ extern crate substrate_runtime_io as runtime_io;
extern crate substrate_runtime_support as runtime_support;
extern crate substrate_codec as codec;
extern crate substrate_primitives;
+extern crate ed25519;
+extern crate byte_num;
#[cfg(test)]
extern crate serde_json;
@@ -59,6 +61,7 @@ pub mod testing;
pub mod traits;
pub mod generic;
pub mod bft;
+pub mod address_format;
use traits::{Verify, Lazy};
diff --git a/substrate/runtime/primitives/src/testing.rs b/substrate/runtime/primitives/src/testing.rs
index eab978d3b8951..2415d819aacfb 100644
--- a/substrate/runtime/primitives/src/testing.rs
+++ b/substrate/runtime/primitives/src/testing.rs
@@ -21,6 +21,7 @@ use std::fmt::Debug;
use codec::Codec;
use runtime_support::AuxDispatchable;
use traits::{self, Checkable, Applyable, BlakeTwo256};
+use address_format::SS58;
pub use substrate_primitives::H256;
diff --git a/substrate/runtime/primitives/src/traits.rs b/substrate/runtime/primitives/src/traits.rs
index 3c89087d70dc3..4fa6fbd5399f9 100644
--- a/substrate/runtime/primitives/src/traits.rs
+++ b/substrate/runtime/primitives/src/traits.rs
@@ -27,6 +27,7 @@ pub use integer_sqrt::IntegerSquareRoot;
pub use num_traits::{Zero, One, Bounded};
pub use num_traits::ops::checked::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv};
use rstd::ops::{Add, Sub, Mul, Div, Rem, AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
+use address_format::SS58;
/// A lazy value.
pub trait Lazy {
@@ -426,4 +427,4 @@ pub trait Applyable: Sized + Send + Sync {
fn index(&self) -> &Self::Index;
fn sender(&self) -> &Self::AccountId;
fn apply(self) -> Result<(), &'static str>;
-}
+}
\ No newline at end of file
diff --git a/substrate/runtime/staking/Cargo.toml b/substrate/runtime/staking/Cargo.toml
index 4ca513a1f0c9d..fd896ca0eb389 100644
--- a/substrate/runtime/staking/Cargo.toml
+++ b/substrate/runtime/staking/Cargo.toml
@@ -5,6 +5,7 @@ authors = ["Parity Technologies "]
[dependencies]
hex-literal = "0.1.0"
+base58 = "0.1"
serde = { version = "1.0", default_features = false }
serde_derive = { version = "1.0", optional = true }
safe-mix = { version = "1.0", default_features = false}
@@ -20,6 +21,7 @@ substrate-runtime-consensus = { path = "../consensus", default_features = false
substrate-runtime-system = { path = "../system", default_features = false }
substrate-runtime-session = { path = "../session", default_features = false }
substrate-runtime-timestamp = { path = "../timestamp", default_features = false }
+ed25519 = { path = "../../ed25519", default_features = false }
[dev-dependencies]
wabt = "0.4"
diff --git a/substrate/runtime/staking/src/address.rs b/substrate/runtime/staking/src/address.rs
index 249e0b20db225..1576aa6af5a43 100644
--- a/substrate/runtime/staking/src/address.rs
+++ b/substrate/runtime/staking/src/address.rs
@@ -19,13 +19,15 @@
#[cfg(feature = "std")]
use std::fmt;
use super::{Member, Decode, Encode, As, Input, Output};
+use primitives::address_format::{SS58, SS58Compatible};
+use ed25519::Public;
/// A vetted and verified extrinsic from the external world.
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Hash))]
pub enum Address where
- AccountId: Member,
- AccountIndex: Member,
+ AccountId: Member + fmt::Display + Into,
+ AccountIndex: Member + fmt::Display + Into,
{
/// It's an account ID (pubkey).
#[cfg_attr(feature = "std", serde(deserialize_with="AccountId::deserialize"))]
@@ -37,17 +39,18 @@ pub enum Address where
#[cfg(feature = "std")]
impl fmt::Display for Address where
- AccountId: Member,
- AccountIndex: Member,
+ AccountId: Member + Sized + fmt::Display + Into + Default + fmt::Debug + Sync,
+ AccountIndex: Member + Sized + fmt::Display + Into + fmt::Debug + Sync,
+ Public: From
{
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
- write!(f, "{:?}", self)
+ write!(f, "{:?}", &self.clone().encode())
}
}
impl From for Address where
- AccountId: Member,
- AccountIndex: Member,
+ AccountId: Member + fmt::Display + Into,
+ AccountIndex: Member + fmt::Display + Into,
{
fn from(a: AccountId) -> Self {
Address::Id(a)
@@ -59,8 +62,8 @@ fn need_more_than(a: T, b: T) -> Option {
}
impl Decode for Address where
- AccountId: Member + Decode,
- AccountIndex: Member + Decode + PartialOrd + Ord + As + As + As + Copy,
+ AccountId: Member + fmt::Display + Decode,
+ AccountIndex: Member + fmt::Display + Decode + PartialOrd + Ord + As + As + As + Copy,
{
fn decode(input: &mut I) -> Option {
Some(match input.read_byte()? {
@@ -75,8 +78,8 @@ impl Decode for Address where
}
impl Encode for Address where
- AccountId: Member + Encode,
- AccountIndex: Member + Encode + PartialOrd + Ord + As + As + As + Copy,
+ AccountId: Member + fmt::Display + Encode,
+ AccountIndex: Member + fmt::Display + Encode + PartialOrd + Ord + As + As + As + Copy,
{
fn encode_to(&self, dest: &mut T) {
match *self {
@@ -102,10 +105,40 @@ impl Encode for Address where
}
impl Default for Address where
- AccountId: Member + Default,
- AccountIndex: Member,
+ AccountId: Member + fmt::Display + Into + Default,
+ AccountIndex: Member + fmt::Display + Into,
{
fn default() -> Self {
Address::Id(Default::default())
}
}
+
+impl Into for Address where
+ AccountId: Member + fmt::Display + Into + Default + fmt::Debug + Sync,
+ AccountIndex: Member + fmt::Display + Into + fmt::Debug + Sync,
+
+
+{
+ fn into(self) -> Public {
+ match self {
+ Address::Id(id) => Into::::into(id),
+ Address::Index(id) => Into::::into(id)
+ }
+ }
+}
+
+impl SS58 for Address where
+ AccountId: Member + fmt::Display + Into + Default + fmt::Debug + Sync,
+ AccountIndex: Member + fmt::Display + Into + fmt::Debug + Sync,
+ Vec: From
+{}
+
+impl Into for Address where
+ AccountId: Member + fmt::Display + Into + Default + fmt::Debug + Sync,
+ AccountIndex: Member + fmt::Display + Into + fmt::Debug + Sync,
+ Vec: From
+{
+ fn into(self) -> SS58Compatible {
+ SS58Compatible(self.into())
+ }
+}
\ No newline at end of file
diff --git a/substrate/runtime/staking/src/lib.rs b/substrate/runtime/staking/src/lib.rs
index b62b585dbbaa2..01f0d64b27164 100644
--- a/substrate/runtime/staking/src/lib.rs
+++ b/substrate/runtime/staking/src/lib.rs
@@ -28,6 +28,8 @@ extern crate serde_derive;
#[cfg(test)]
extern crate wabt;
+extern crate base58;
+
#[macro_use]
extern crate substrate_runtime_support as runtime_support;
@@ -43,6 +45,7 @@ extern crate substrate_runtime_sandbox as sandbox;
extern crate substrate_runtime_session as session;
extern crate substrate_runtime_system as system;
extern crate substrate_runtime_timestamp as timestamp;
+extern crate ed25519;
#[cfg(test)] use std::fmt::Debug;
use rstd::prelude::*;
@@ -53,7 +56,9 @@ use runtime_support::dispatch::Result;
use session::OnSessionChange;
use primitives::traits::{Zero, One, Bounded, RefInto, SimpleArithmetic, Executable, MakePayment,
As, AuxLookup, Member, CheckedAdd, CheckedSub};
+use primitives::address_format::{SS58, SS58Compatible};
use address::Address as RawAddress;
+use std::fmt;
mod mock;
@@ -103,7 +108,7 @@ pub trait Trait: system::Trait + session::Trait {
type Balance: Parameter + SimpleArithmetic + Codec + Default + Copy + As + As + As;
/// Type used for storing an account's index; implies the maximum number of accounts the system
/// can hold.
- type AccountIndex: Parameter + Member + Codec + SimpleArithmetic + As + As + As + As + As + Copy;
+ type AccountIndex: Parameter + Member + Codec + SimpleArithmetic + As + As + As + As + As + Copy + fmt::Display;
/// A function which is invoked when the given account is dead.
///
/// Gives a chance to clean up resources associated with the given account.
@@ -114,7 +119,11 @@ decl_module! {
pub struct Module;
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- pub enum Call where aux: T::PublicAux {
+ pub enum Call
+ where
+ aux: T::PublicAux,
+ SS58Compatible: From<::AccountId> + From<::AccountIndex>
+ {
fn transfer(aux, dest: RawAddress, value: T::Balance) -> Result = 0;
fn stake(aux) -> Result = 1;
fn unstake(aux, index: u32) -> Result = 2;
@@ -233,7 +242,9 @@ pub enum UpdateBalanceOutcome {
AccountKilled,
}
-impl Module {
+impl Module
+where SS58Compatible: From
+{
// PUBLIC IMMUTABLES
@@ -845,7 +856,9 @@ impl OnSessionChange for Module {
}
}
-impl AuxLookup for Module {
+impl AuxLookup for Module
+where SS58Compatible: From<::AccountId> + From<::AccountIndex>
+{
type Source = address::Address;
type Target = T::AccountId;
fn lookup(a: Self::Source) -> result::Result {
diff --git a/substrate/runtime/system/src/lib.rs b/substrate/runtime/system/src/lib.rs
index 60dd6059b4070..1e83b4130dfc0 100644
--- a/substrate/runtime/system/src/lib.rs
+++ b/substrate/runtime/system/src/lib.rs
@@ -40,6 +40,7 @@ extern crate safe_mix;
use rstd::prelude::*;
use primitives::traits::{self, CheckEqual, SimpleArithmetic, SimpleBitOps, Zero, One, Bounded,
Hash, Member, MaybeDisplay};
+use primitives::address_format::SS58Compatible;
use runtime_support::{StorageValue, StorageMap, Parameter};
use safe_mix::TripletMix;
@@ -68,7 +69,7 @@ pub trait Trait: Eq + Clone {
type Hash: Parameter + Member + MaybeDisplay + SimpleBitOps + Default + Copy + CheckEqual + rstd::hash::Hash + AsRef<[u8]>;
type Hashing: Hash