# Install Rust toolchains
$ curl https://sh.rustup.rs -sSf | sh -s -- -y && \
export PATH="$PATH:$HOME/.cargo/bin"
# Build the node binrary
$ git clone -b v1.0 https://github.com/paritytech/substrate
$ cargo install --force --path subkey subkey
$ cd node-template && ./scripts/init.sh && ./scripts/build.sh
$ cargo build --release
$ cd ..
$ ./target/release/node-template \
--base-path /tmp/alice \
--chain=local \
--key //Alice \
--port 30333 \
--telemetry-url ws://telemetry.polkadot.io:1024 \
--validator \
--name AlicesNode
$ ./target/release/node-template \
--base-path /tmp/bob \
--chain=local \
--key //Bob \
--port 30334 \
--telemetry-url ws://telemetry.polkadot.io:1024 \
--validator \
--name BobsNode \
--bootnodes /ip4/<Alices IP Address>/tcp/<Alices Port>/p2p/<Alices Node ID>
- open
https://polkadot.js.org/apps/#/settings
- use custom endpoint and input
ws://localhost:9944/
- Choose
Explorer
in the left panel, and see the new blocks are generated almost every 10 seconds.
When consensus is rejected, try clear the data of the chain
- purge chain data with
./target/release/node-template purge-chain
. - delete the temp data in base path.
Create new file called poe.rs
under ./node-template/runtime/src
, now let's add some stuff in it.
use support::{decl_module, decl_storage, decl_event, ensure, StorageMap};
use rstd::vec::Vec;
use system::ensure_signed;
pub trait Trait: system::Trait {
/// The overarching event type.
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
}
decl_event!(
pub enum Event<T> where AccountId = <T as system::Trait>::AccountId {
// Event emitted when a proof has been stored into chain storage
ProofStored(AccountId, Vec<u8>),
// Event emitted when a proof has been erased from chain storage
ProofErased(AccountId, Vec<u8>),
}
);
decl_storage! {
trait Store for Module<T: Trait> as PoeStorage {
// Define a 'Proofs' storage item for a map with
// the proof digest as the key, and associated AccountId as value.
// The 'get(proofs)' is the default getter.
Proofs get(proofs): map Vec<u8> => T::AccountId;
}
}
decl_module! {
/// The module declaration.
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
// A default function for depositing events
fn deposit_event() = default;
// Allow a user to store an unclaimed proof
fn store_proof(origin, digest: Vec<u8>) {
// Verify that the incoming transaction is signed
let sender = ensure_signed(origin)?;
// Verify that the specified proof has not been claimed yet
ensure!(!Proofs::<T>::exists(&digest), "This proof has already been claimed");
// Store the proof and the claim owner
Proofs::<T>::insert(&digest, sender.clone());
// Emit an event that the claim was stored
Self::deposit_event(RawEvent::ProofStored(sender, digest));
}
// Allow the owner of a proof to erase their claim
fn erase_proof(origin, digest: Vec<u8>) {
// Determine who is calling the function
let sender = ensure_signed(origin)?;
// Verify that the specified proof has been claimed
ensure!(Proofs::<T>::exists(&digest), "This proof has not been stored yet");
// Get owner of the claim
let owner = Self::proofs(&digest);
// Verify that sender of the current call is the claim owner
ensure!(sender == owner, "You must own this proof to erase it");
// Remove claim from storage
Proofs::<T>::remove(&digest);
// Emit an event that the claim was erased
Self::deposit_event(RawEvent::ProofErased(sender, digest));
}
}
}
Edit the lib.rs
file in the same folder.
# Step 1: Add module into runtime
mod poe;
# Step 2: Add the trait implementation
impl poe::Trait for Runtime {
type Event = Event;
}
# Step 3: Update `construct_runtime`
construct_runtime!(
pub enum Runtime where
Block = Block,
NodeBlock = opaque::Block,
UncheckedExtrinsic = UncheckedExtrinsic
{
...
POEModule: poe::{Module, Call, Storage, Event<T>},
}
);
cargo build --release
For detail, check Shawn's Create your first Substrate blockchan tutorial, which maybe slightly difference from the tutorial here.
- open the blockechain explorer here
https://polkadot.js.org/apps/#/sudo
- copy the wasm file into clipboard
$ xxd -p ./node_template_runtime_wasm.compact.wasm | pbcopy
- Update it under
Sudo
and paste the code tosetCode