doc: duplicated documentation removed (#603)
29
.github/workflows/build-docs.yml
vendored
@ -1,29 +0,0 @@
|
||||
name: Docs build
|
||||
# This workflow runs when a PR is labeled with `docs`
|
||||
# This will check if the docs build successfully by running `npm run build`
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- release/*
|
||||
|
||||
jobs:
|
||||
check-docs-build:
|
||||
name: Check docs build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.4
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-depth: 0
|
||||
- uses: technote-space/get-diff-action@v5
|
||||
id: git_diff
|
||||
with:
|
||||
PATTERNS: |
|
||||
docs/*
|
||||
SUFFIX_FILTER: |
|
||||
.md
|
||||
- name: Install dependencies and build docs 🧱
|
||||
run: |
|
||||
make build-docs
|
@ -106,16 +106,6 @@ items. In addition, use the following review explanations:
|
||||
- If you sat down with the PR submitter and did a pairing review, add this information in the `Approval` or your PR comments.
|
||||
- If you are only making "surface level" reviews, submit any notes as `Comments` without adding a review.
|
||||
|
||||
### Updating Documentation
|
||||
|
||||
If you open a PR on Ethermint, it is mandatory to update the relevant documentation in `/docs`.
|
||||
|
||||
- If your change relates to the core SDK (baseapp, store, ...), be sure to update the content in `docs/basics/`, `docs/core/` and/or `docs/building-modules/` folders.
|
||||
- If your changes relate to the core of the CLI (not specifically to module's CLI/Rest), then modify the content in the `docs/run-node/` folder.
|
||||
- If your changes relate to a module, then be sure to update the module's spec in `x/moduleName/docs/spec/`.
|
||||
|
||||
When writing documentation, follow the [Documentation Writing Guidelines](./docs/DOC_WRITING_GUIDELINES.md).
|
||||
|
||||
## Forking
|
||||
|
||||
Go requires code to live under absolute paths, and this requirement complicates forking.
|
||||
|
46
Makefile
@ -215,16 +215,8 @@ else
|
||||
@echo "solcjs already installed; skipping..."
|
||||
endif
|
||||
|
||||
docs-tools:
|
||||
ifeq (, $(shell which yarn))
|
||||
@echo "Installing yarn..."
|
||||
@npm install -g yarn
|
||||
else
|
||||
@echo "yarn already installed; skipping..."
|
||||
endif
|
||||
|
||||
tools: tools-stamp
|
||||
tools-stamp: contract-tools docs-tools proto-tools statik runsim
|
||||
tools-stamp: contract-tools proto-tools statik runsim
|
||||
# Create dummy file to satisfy dependency and avoid
|
||||
# rebuilding when this Makefile target is hit twice
|
||||
# in a row.
|
||||
@ -234,13 +226,7 @@ tools-clean:
|
||||
rm -f $(RUNSIM)
|
||||
rm -f tools-stamp
|
||||
|
||||
docs-tools-stamp: docs-tools
|
||||
# Create dummy file to satisfy dependency and avoid
|
||||
# rebuilding when this Makefile target is hit twice
|
||||
# in a row.
|
||||
touch $@
|
||||
|
||||
.PHONY: runsim statik tools contract-tools docs-tools proto-tools tools-stamp tools-clean docs-tools-stamp
|
||||
.PHONY: runsim statik tools contract-tools proto-tools tools-stamp tools-clean
|
||||
|
||||
go.sum: go.mod
|
||||
echo "Ensure dependencies have not been modified ..." >&2
|
||||
@ -265,34 +251,6 @@ godocs:
|
||||
@echo "--> Wait a few seconds and visit http://localhost:6060/pkg/github.com/tharsis/ethermint/types"
|
||||
godoc -http=:6060
|
||||
|
||||
# Start docs site at localhost:8080
|
||||
docs-serve:
|
||||
@cd docs && \
|
||||
yarn && \
|
||||
yarn run serve
|
||||
|
||||
# Build the site into docs/.vuepress/dist
|
||||
build-docs:
|
||||
@$(MAKE) docs-tools-stamp && \
|
||||
cd docs && \
|
||||
yarn && \
|
||||
yarn run build
|
||||
|
||||
# This builds a docs site for each branch/tag in `./docs/versions`
|
||||
# and copies each site to a version prefixed path. The last entry inside
|
||||
# the `versions` file will be the default root index.html.
|
||||
build-docs-versioned:
|
||||
@$(MAKE) docs-tools-stamp && \
|
||||
cd docs && \
|
||||
while read -r branch path_prefix; do \
|
||||
(git checkout $${branch} && npm install && VUEPRESS_BASE="/$${path_prefix}/" npm run build) ; \
|
||||
mkdir -p ~/output/$${path_prefix} ; \
|
||||
cp -r .vuepress/dist/* ~/output/$${path_prefix}/ ; \
|
||||
cp ~/output/$${path_prefix}/index.html ~/output ; \
|
||||
done < versions ;
|
||||
|
||||
.PHONY: docs-serve build-docs build-docs-versioned
|
||||
|
||||
###############################################################################
|
||||
### Tests & Simulation ###
|
||||
###############################################################################
|
||||
|
@ -63,7 +63,7 @@ Or check out the latest [release](https://github.com/tharsis/ethermint/releases)
|
||||
|
||||
To learn how the Ethermint works from a high-level perspective, go to the [Introduction](https://ethermint.dev/intro/overview.html) section from the documentation. You can also check the instructions to [Run a Node](https://ethermint.dev/quickstart/run_node.html).
|
||||
|
||||
For more, please refer to the [Ethermint Docs](./docs/), which are also hosted on [ethermint.dev](https://ethermint.dev/).
|
||||
For an example on how Ethermint can be used on any cosmos chain, please refer to [Evmos](https://www.github.com/tharsis/evmos)
|
||||
|
||||
## Community
|
||||
|
||||
|
@ -1,512 +0,0 @@
|
||||
<template lang="pug">
|
||||
div
|
||||
.search__container
|
||||
.search(@click="$emit('search', true)")
|
||||
.search__icon
|
||||
icon-search
|
||||
.search__text Search
|
||||
.h1 {{$frontmatter.title}}
|
||||
.intro
|
||||
.p {{$frontmatter.description}}
|
||||
.h2 Getting Started
|
||||
.p__alt Read all about Ethermint or dive straight into the code with guides.
|
||||
.features
|
||||
router-link(to="/quickstart").features__item.features__item__light
|
||||
.features__item__image
|
||||
icon-rocket.features__item__image__img
|
||||
.features__item__text
|
||||
.features__item__text__h2 read
|
||||
.features__item__text__h1 Quick start
|
||||
.features__item__text__p Deploy your own node, setup your testnet and more.
|
||||
router-link(to="/guides").features__item.features__item__dark
|
||||
.features__item__image
|
||||
icon-code.features__item__image__img
|
||||
.features__item__text
|
||||
.features__item__text__h2 use
|
||||
.features__item__text__h1 Guides
|
||||
.features__item__text__p Follow guides to using polular Ethereum tools with Ethermint.
|
||||
.sections__wrapper
|
||||
.h2 Explore Ethermint
|
||||
.p__alt Get familiar with Ethermint and explore its main concepts.
|
||||
.sections
|
||||
router-link.sections__item(tag="a" :to="section.url" v-for="section in $frontmatter.sections")
|
||||
component(:is="`tm-icon-${section.icon}`").sections__item__icon
|
||||
.sections__item__wrapper
|
||||
.sections__item__title {{section.title}}
|
||||
.sections__item__desc {{section.desc}}
|
||||
.h2 Explore the stack
|
||||
.p__alt Check out the docs for the various parts of the Ethermint stack.
|
||||
.stack
|
||||
a.stack__item(:href="item.url" v-for="item in $frontmatter.stack" :style="{'--accent': item.color, '--opacity': '5%'}")
|
||||
.stack__item__wrapper
|
||||
component(:is="`tm-logo-${item.label}`" :color="item.color" height="100px").stack__item__logo
|
||||
svg(width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg").stack__item__icon
|
||||
path(d="M1.07239 14.4697C0.779499 14.7626 0.779499 15.2374 1.07239 15.5303C1.36529 15.8232 1.84016 15.8232 2.13305 15.5303L1.07239 14.4697ZM15.7088 1.95457C16.0017 1.66168 16.0017 1.18681 15.7088 0.893912C15.4159 0.601019 14.941 0.601019 14.6482 0.893912L15.7088 1.95457ZM15.6027 1H16.3527C16.3527 0.585786 16.0169 0.25 15.6027 0.25V1ZM5.4209 0.25C5.00669 0.25 4.6709 0.585786 4.6709 1C4.6709 1.41421 5.00669 1.75 5.4209 1.75V0.25ZM14.8527 11.1818C14.8527 11.596 15.1885 11.9318 15.6027 11.9318C16.0169 11.9318 16.3527 11.596 16.3527 11.1818H14.8527ZM2.13305 15.5303L15.7088 1.95457L14.6482 0.893912L1.07239 14.4697L2.13305 15.5303ZM15.6027 0.25H5.4209V1.75H15.6027V0.25ZM16.3527 11.1818V1H14.8527V11.1818H16.3527Z" fill="#DADCE6")
|
||||
div
|
||||
.stack__item__h1 {{item.title}}
|
||||
.stack__item__p {{item.desc}}
|
||||
tm-help-support
|
||||
</template>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
/deep/ {
|
||||
.container h1 {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.search {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: rgba(22, 25, 49, 0.65);
|
||||
padding-top: 1rem;
|
||||
width: calc(var(--aside-width) - 6rem);
|
||||
cursor: pointer;
|
||||
transition: color 0.15s ease-out;
|
||||
|
||||
&:hover {
|
||||
color: var(--color-text, black);
|
||||
}
|
||||
|
||||
&__container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
&__icon {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
fill: #aaa;
|
||||
margin-right: 0.5rem;
|
||||
transition: fill 0.15s ease-out;
|
||||
}
|
||||
|
||||
&:hover &__icon {
|
||||
fill: var(--color-text, black);
|
||||
}
|
||||
}
|
||||
|
||||
.intro {
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
.h1 {
|
||||
font-size: 3rem;
|
||||
font-weight: 700;
|
||||
margin-bottom: 1.5rem;
|
||||
line-height: 3.25rem;
|
||||
letter-spacing: -0.02em;
|
||||
padding-top: 2.5rem;
|
||||
}
|
||||
|
||||
.h2 {
|
||||
font-size: 2rem;
|
||||
font-weight: 700;
|
||||
margin-top: 4.5rem;
|
||||
margin-bottom: 1rem;
|
||||
line-height: 2.25rem;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
.p {
|
||||
font-size: 1.5rem;
|
||||
line-height: 2.25rem;
|
||||
|
||||
&__alt {
|
||||
margin-top: 0.75rem;
|
||||
margin-bottom: 2rem;
|
||||
font-size: 1.25rem;
|
||||
line-height: 1.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
.features {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 1.5rem;
|
||||
margin-bottom: 5rem;
|
||||
margin-top: 2.25rem;
|
||||
|
||||
&__item {
|
||||
cursor: pointer;
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
grid-template-columns: minmax(6rem, 1fr) 2fr;
|
||||
box-shadow: 0px 2px 4px rgba(22, 25, 49, 0.05), 0px 0px 1px rgba(22, 25, 49, 0.2), 0px 0.5px 0px rgba(22, 25, 49, 0.05);
|
||||
position: relative;
|
||||
border-radius: 0.5rem;
|
||||
background: linear-gradient(281.08deg, #FFFFFF 48.96%, #E8F3FF 100%);
|
||||
outline: none;
|
||||
transition: box-shadow 0.25s ease-out, transform 0.25s ease-out, opacity 0.4s ease-out;
|
||||
|
||||
&:hover:not(:active), &:focus {
|
||||
box-shadow: 0px 12px 24px rgba(22, 25, 49, 0.07), 0px 4px 8px rgba(22, 25, 49, 0.05), 0px 1px 0px rgba(22, 25, 49, 0.05);
|
||||
transform: translateY(-2px);
|
||||
transition-duration: 0.1s;
|
||||
}
|
||||
|
||||
&:active {
|
||||
opacity: 0.7;
|
||||
transition-duration: 0s;
|
||||
}
|
||||
|
||||
&__dark {
|
||||
background: linear-gradient(112.22deg, #161831 0%, #2E3148 100%);
|
||||
}
|
||||
|
||||
&__dark &__text__h2 {
|
||||
color: white;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
&__dark &__text__h1 {
|
||||
color: white;
|
||||
}
|
||||
|
||||
&__dark &__text__p {
|
||||
color: white;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
&__icon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: 0.75rem;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
fill: white;
|
||||
opacity: 0.35;
|
||||
}
|
||||
|
||||
&:hover &__icon {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
&__image {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
align-self: center;
|
||||
max-height: 10rem;
|
||||
transition: transform 0.2s ease-out;
|
||||
|
||||
&__img {
|
||||
max-height: 14rem;
|
||||
max-width: 10rem;
|
||||
min-width: 8rem;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover:not(:active) &__image {
|
||||
transform: translateY(-0.25rem) scale(1.02);
|
||||
transition-duration: 0.1s;
|
||||
}
|
||||
|
||||
&__text {
|
||||
padding: 1.75rem 2rem 2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
&__h2 {
|
||||
font-size: 0.75rem;
|
||||
letter-spacing: 0.2em;
|
||||
text-transform: uppercase;
|
||||
color: var(--color-text-dim, inherit);
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
&__h1 {
|
||||
font-size: 1.25rem;
|
||||
color: var(--color-text, black);
|
||||
line-height: 1.75rem;
|
||||
letter-spacing: 0.01em;
|
||||
font-weight: 600;
|
||||
margin-top: 0.25rem;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
&__p {
|
||||
color: var(--color-text-dim, inherit);
|
||||
font-size: 0.875rem;
|
||||
letter-spacing: 0.03em;
|
||||
line-height: 1.25rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sections {
|
||||
display: grid;
|
||||
margin-top: 3rem;
|
||||
margin-bottom: 5rem;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 1.5rem;
|
||||
|
||||
&__item {
|
||||
position: relative;
|
||||
color: initial;
|
||||
border-radius: 0.5rem;
|
||||
padding: 1.5rem 1.5rem 1.5rem 5.5rem;
|
||||
box-shadow: 0px 2px 4px rgba(22, 25, 49, 0.05), 0px 0px 1px rgba(22, 25, 49, 0.2), 0px 0.5px 0px rgba(22, 25, 49, 0.05);
|
||||
transition: box-shadow 0.25s ease-out, transform 0.25s ease-out, opacity 0.4s ease-out;
|
||||
|
||||
&:hover:not(:active) {
|
||||
box-shadow: 0px 12px 24px rgba(22, 25, 49, 0.07), 0px 4px 8px rgba(22, 25, 49, 0.05), 0px 1px 0px rgba(22, 25, 49, 0.05);
|
||||
transform: translateY(-2px);
|
||||
transition-duration: 0.1s;
|
||||
}
|
||||
|
||||
&:active {
|
||||
transition-duration: 0s;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
&__icon {
|
||||
position: absolute;
|
||||
left: 1.25rem;
|
||||
font-size: 1.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
&__desc {
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem;
|
||||
color: var(--color-text-dim, inherit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.stack {
|
||||
display: grid;
|
||||
gap: 1.5rem;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
margin-bottom: 4rem;
|
||||
|
||||
&__item {
|
||||
position: relative;
|
||||
min-height: 120px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 2rem 1.25rem;
|
||||
border-radius: 0.5rem;
|
||||
box-shadow: 0px 2px 4px rgba(22, 25, 49, 0.05), 0px 0px 1px rgba(22, 25, 49, 0.2), 0px 0.5px 0px rgba(22, 25, 49, 0.05);
|
||||
color: var(--color-text, black);
|
||||
background: white;
|
||||
transition: box-shadow 0.25s ease-out, transform 0.25s ease-out, opacity 0.4s ease-out;
|
||||
|
||||
&:hover:not(:active) {
|
||||
box-shadow: 0px 12px 24px rgba(22, 25, 49, 0.07), 0px 4px 8px rgba(22, 25, 49, 0.05), 0px 1px 0px rgba(22, 25, 49, 0.05);
|
||||
transform: translateY(-2px);
|
||||
transition-duration: 0.1s;
|
||||
}
|
||||
|
||||
&:active {
|
||||
opacity: 0.7;
|
||||
transition-duration: 0s;
|
||||
}
|
||||
|
||||
&__icon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: 1rem;
|
||||
opacity: 0.35;
|
||||
}
|
||||
|
||||
&:hover &__icon {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
&__h1 {
|
||||
font-size: 1.25rem;
|
||||
line-height: 1.5rem;
|
||||
margin-bottom: 0.75rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&__p {
|
||||
font-size: 0.875rem;
|
||||
color: rgba(22, 25, 49, 0.65);
|
||||
line-height: 1.25rem;
|
||||
}
|
||||
|
||||
&__wrapper {
|
||||
display: grid;
|
||||
grid-auto-flow: row;
|
||||
gap: 1.25rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&:before {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
content: '';
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
background: linear-gradient(to right, var(--accent), rgba(255, 255, 255, 0));
|
||||
border-radius: 0.5rem;
|
||||
opacity: 0.1;
|
||||
}
|
||||
|
||||
&__logo {
|
||||
height: 72px;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1136px) {
|
||||
.p {
|
||||
font-size: 1.25rem;
|
||||
line-height: 1.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 832px) {
|
||||
.h1 {
|
||||
padding-top: 3.5rem;
|
||||
}
|
||||
|
||||
.search__container {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 752px) {
|
||||
.search {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 500px) {
|
||||
.h1 {
|
||||
font-size: 2rem;
|
||||
line-height: 2.25rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.h2 {
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
margin-top: 3rem;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.p__alt {
|
||||
font-size: 1rem;
|
||||
line-height: 1.5rem;
|
||||
}
|
||||
|
||||
.features {
|
||||
margin-bottom: 1.5rem;
|
||||
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
||||
|
||||
&__item {
|
||||
display: block;
|
||||
|
||||
&:not(:active) {
|
||||
box-shadow: 0px 24px 40px rgba(0, 0, 0, 0.1), 0px 10px 16px rgba(0, 0, 0, 0.08), 0px 1px 0px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
&__image {
|
||||
max-height: 9rem;
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
&__text {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sections {
|
||||
gap: 0;
|
||||
margin-bottom: 0;
|
||||
margin-top: 2rem;
|
||||
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
||||
margin-left: -1rem;
|
||||
margin-right: -1rem;
|
||||
|
||||
&__item {
|
||||
margin-bottom: 0;
|
||||
padding: 1.25rem 1rem 0 5.5rem;
|
||||
|
||||
&, &:hover:not(:active) {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
&__icon {
|
||||
top: 1rem;
|
||||
left: 1.25rem;
|
||||
}
|
||||
|
||||
&__wrapper {
|
||||
padding-bottom: 1.25rem;
|
||||
border-bottom: 1px solid rgba(140, 145, 177, 0.32);
|
||||
}
|
||||
|
||||
&:last-child .sections__item__wrapper {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
&__wrapper {
|
||||
position: relative;
|
||||
padding: 0.1px 1rem 1rem;
|
||||
background: white;
|
||||
border-radius: 0.5rem;
|
||||
|
||||
&:before {
|
||||
position: absolute;
|
||||
content: '';
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border-radius: 0.5rem;
|
||||
box-shadow: 0px 24px 40px rgba(0, 0, 0, 0.1), 0px 10px 16px rgba(0, 0, 0, 0.08), 0px 1px 0px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.stack {
|
||||
gap: 0.75rem;
|
||||
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
|
||||
margin-bottom: 3rem;
|
||||
|
||||
&__item {
|
||||
padding: 1.25rem;
|
||||
|
||||
&:not(:active) {
|
||||
box-shadow: 0px 24px 40px rgba(22, 25, 49, 0.1), 0px 10px 16px rgba(22, 25, 49, 0.08), 0px 1px 0px rgba(22, 25, 49, 0.05);
|
||||
}
|
||||
|
||||
&__wrapper {
|
||||
grid-template-columns: 3rem 1fr;
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
&__h1 {
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,31 +0,0 @@
|
||||
<template>
|
||||
<svg width="100%" height="100%" viewBox="0 0 165 140" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="15.2" y="0.399879" width="135.6" height="115.2" rx="4.8" stroke="url(#paint0_linear)" stroke-width="0.6"/>
|
||||
<rect x="0.199982" y="46.5999" width="145.2" height="94.8" transform="rotate(-15 0.199982 46.5999)" fill="url(#paint1_linear)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M87.4269 40.4409C88.0849 40.5195 88.5547 41.1167 88.4761 41.7747L81.1977 102.735C81.1192 103.393 80.522 103.863 79.8639 103.784C79.2059 103.706 78.7361 103.109 78.8147 102.451L86.0931 41.4902C86.1716 40.8321 86.7688 40.3624 87.4269 40.4409ZM60.8853 56.9452C61.4443 57.3012 61.6089 58.0429 61.253 58.6019L46.1657 82.2944L71.0008 95.0057C71.5907 95.3076 71.8242 96.0307 71.5223 96.6206C71.2203 97.2106 70.4973 97.4441 69.9073 97.1421L43.8986 83.8301L42.7249 83.2294L43.4331 82.1173L59.2286 57.3128C59.5846 56.7538 60.3263 56.5892 60.8853 56.9452ZM94.2871 47.9121C93.6966 47.6112 92.9739 47.8459 92.673 48.4364C92.3721 49.0269 92.6068 49.7495 93.1973 50.0504L118.014 62.6977L102.942 86.455C102.587 87.0146 102.753 87.7561 103.313 88.1111C103.872 88.4661 104.614 88.3003 104.969 87.7406L120.747 62.8701L121.453 61.7568L120.278 61.1581L94.2871 47.9121Z" fill="#8CA9C6"/>
|
||||
<path d="M34.1 14.7999C34.1 17.2852 32.0853 19.2999 29.6 19.2999V19.8999C32.4167 19.8999 34.7 17.6165 34.7 14.7999H34.1ZM29.6 10.2999C32.0853 10.2999 34.1 12.3146 34.1 14.7999H34.7C34.7 11.9832 32.4167 9.69988 29.6 9.69988V10.2999ZM25.1 14.7999C25.1 12.3146 27.1147 10.2999 29.6 10.2999V9.69988C26.7834 9.69988 24.5 11.9832 24.5 14.7999H25.1ZM29.6 19.2999C27.1147 19.2999 25.1 17.2852 25.1 14.7999H24.5C24.5 17.6165 26.7834 19.8999 29.6 19.8999V19.2999ZM48.4999 14.7999C48.4999 17.2852 46.4852 19.2999 43.9999 19.2999V19.8999C46.8166 19.8999 49.0999 17.6165 49.0999 14.7999H48.4999ZM43.9999 10.2999C46.4852 10.2999 48.4999 12.3146 48.4999 14.7999H49.0999C49.0999 11.9832 46.8166 9.69988 43.9999 9.69988V10.2999ZM39.4999 14.7999C39.4999 12.3146 41.5147 10.2999 43.9999 10.2999V9.69988C41.1833 9.69988 38.8999 11.9832 38.8999 14.7999H39.4999ZM43.9999 19.2999C41.5147 19.2999 39.4999 17.2852 39.4999 14.7999H38.8999C38.8999 17.6165 41.1833 19.8999 43.9999 19.8999V19.2999ZM58.4 19.8999C61.2167 19.8999 63.5 17.6165 63.5 14.7999H62.9C62.9 17.2852 60.8853 19.2999 58.4 19.2999V19.8999ZM53.3 14.7999C53.3 17.6165 55.5834 19.8999 58.4 19.8999V19.2999C55.9147 19.2999 53.9 17.2852 53.9 14.7999H53.3ZM58.4 9.69988C55.5834 9.69988 53.3 11.9832 53.3 14.7999H53.9C53.9 12.3146 55.9147 10.2999 58.4 10.2999V9.69988ZM63.5 14.7999C63.5 11.9832 61.2167 9.69988 58.4 9.69988V10.2999C60.8853 10.2999 62.9 12.3146 62.9 14.7999H63.5Z" fill="url(#paint3_linear)"/>
|
||||
<path d="M15.2 29.1999H150.8" stroke="url(#paint4_linear)" stroke-width="0.6"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear" x1="120.998" y1="62.4" x2="120.998" y2="177.6" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#8CA9C6"/>
|
||||
<stop offset="1" stop-color="#336699"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear" x1="127.715" y1="148.887" x2="147.74" y2="281.816" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#336699"/>
|
||||
<stop offset="1" stop-color="#8CA9C6"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear" x1="125.577" y1="107.749" x2="125.258" y2="229.399" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#8CA9C6"/>
|
||||
<stop offset="1" stop-color="#336699"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear" x1="81.9981" y1="72" x2="81.9981" y2="97.2" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#8CA9C6"/>
|
||||
<stop offset="1" stop-color="#336699"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint4_linear" x1="120.998" y1="67.2" x2="120.998" y2="163.2" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#8CA9C6"/>
|
||||
<stop offset="1" stop-color="#336699"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
</template>
|
@ -1,41 +0,0 @@
|
||||
<template>
|
||||
<svg width="100%" height="100%" viewBox="0 0 150 230" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M129.04 81.9366L135.681 58.78L125.153 20.3152L95.8426 47.3566L89.2025 70.5132L105.801 87.8034L129.04 81.9366Z" fill="url(#paint0_linear)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M122.412 105.051L129.028 81.9786L112.418 64.7302L89.1905 70.5552L82.5745 93.6277L99.1854 110.876L122.412 105.051Z" fill="url(#paint1_linear)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M96.9404 193.882L115.64 128.671L98.9611 111.437L75.6844 117.214L56.5251 182.294L76.9628 188.154L96.9404 193.882Z" fill="url(#paint2_linear)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M42.0642 201.869L93.0233 133.456L51.5928 127.542L12.0095 178.467L42.0642 201.869Z" fill="url(#paint3_linear)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M98.6275 218.088L92.8579 134.032L131.018 150.902L135.385 214.524L98.6275 218.088Z" fill="url(#paint4_linear)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M35.4626 196.23L99.4743 110.96L58.1472 105.081L5.50019 172.841L35.4626 196.23Z" stroke="url(#paint5_linear)" stroke-width="0.7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M106.575 217.245L99.4741 110.959L137.392 127.801L143.167 213.533L106.575 217.245Z" stroke="url(#paint6_linear)" stroke-width="0.7"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear" x1="171.808" y1="70.3402" x2="210.702" y2="119.532" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#336699" stop-opacity="0.91"/>
|
||||
<stop offset="1" stop-color="#8CAAC6"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear" x1="161.105" y1="107.665" x2="185.783" y2="154.845" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#336699" stop-opacity="0.91"/>
|
||||
<stop offset="1" stop-color="#8CAAC6"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear" x1="144.638" y1="164.499" x2="188.211" y2="213.994" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#336699" stop-opacity="0.91"/>
|
||||
<stop offset="1" stop-color="#8CAAC6"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear" x1="112.6" y1="179.034" x2="154.555" y2="254.491" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#336699" stop-opacity="0.91"/>
|
||||
<stop offset="1" stop-color="#8CAAC6"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint4_linear" x1="173.74" y1="196.982" x2="215.848" y2="270.124" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#336699" stop-opacity="0.91"/>
|
||||
<stop offset="1" stop-color="#8CAAC6"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint5_linear" x1="108.253" y1="125.86" x2="80.7963" y2="221.613" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#8CA9C6"/>
|
||||
<stop offset="1" stop-color="#336699"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint6_linear" x1="177.248" y1="145.644" x2="149.626" y2="241.973" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#8CA9C6"/>
|
||||
<stop offset="1" stop-color="#336699"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
</template>
|
@ -1,6 +0,0 @@
|
||||
<template>
|
||||
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="48" height="48" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.2612 1.52098L45.3579 24.8028L24.2611 47.4575L2.62622 24.8029L24.2612 1.52098ZM5.63765 24.5003L23.2519 33.396V5.54515L5.63765 24.5003ZM25.2519 5.59283V33.3772L42.3871 24.5028L25.2519 5.59283ZM39.3349 28.3358L25.2519 35.6295V43.4588L39.3349 28.3358ZM23.2519 43.5049V35.6365L8.73749 28.3064L23.2519 43.5049Z" fill="#7499BF"/>
|
||||
</svg>
|
||||
</template>
|
@ -1,11 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<svg width="100%" height="100%" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path opacity="0.6" d="M39.9917 30.4542L17.5 40.6792L39.9917 53.975L62.4875 40.6792L39.9917 30.4542Z" fill="black"/>
|
||||
<path opacity="0.45" d="M17.5083 40.6791L40 53.975V30.4541V3.35828L17.5083 40.6791Z" fill="black"/>
|
||||
<path opacity="0.8" d="M40 3.35828V30.4541V53.975L62.4917 40.6791L40 3.35828Z" fill="black"/>
|
||||
<path opacity="0.45" d="M17.5 44.9458L39.9917 76.6416V58.2333L17.5 44.9458Z" fill="black"/>
|
||||
<path opacity="0.8" d="M39.9917 58.2333V76.6416L62.5 44.9458L39.9917 58.2333Z" fill="black"/>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
@ -1,7 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<svg width="100%" height="100%" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M63.3188 38.6786L40.0002 52.4512L16.6724 38.6786L40.0002 0L63.3188 38.6786ZM40.0001 75.9369L16.6724 43.0953L40.0001 56.8679L63.3371 43.0953L40.0001 75.9369ZM40.0106 22.5689C41.8663 22.5689 43.7036 22.9206 45.4097 23.5941C45.495 24.2572 45.5265 24.9236 45.5046 25.5884C43.8027 24.7855 41.9183 24.3629 40.0106 24.3629C33.1513 24.3629 27.5045 29.8641 27.1843 36.7318C30.4764 38.4276 34.3665 38.5945 37.7989 37.2405C38.3645 37.6723 38.9596 38.064 39.5805 38.4118C37.6113 39.3875 35.4391 39.9162 33.2435 39.9478C33.1741 39.9489 33.1043 39.9494 33.035 39.9494C30.5163 39.9494 28.0306 39.2905 25.8327 38.0383L25.3766 37.7786L25.3799 37.253C25.4044 33.3394 26.9318 29.6577 29.6808 26.886C32.4418 24.1021 36.1104 22.5689 40.0106 22.5689ZM54.6886 37.139C54.6364 32.2612 52.2708 27.8109 48.3276 25.1C48.3305 25.8137 48.283 26.5271 48.1854 27.2362C50.9873 29.5334 52.6955 32.916 52.8824 36.622C46.8383 39.7491 39.3006 37.5591 35.8671 31.5834C34.9397 29.9693 34.3711 28.1645 34.204 26.3205C33.6206 26.6399 33.0635 27.0074 32.5375 27.4194C32.8149 29.194 33.4176 30.9174 34.317 32.4827C36.2701 35.8819 39.4102 38.319 43.1585 39.3447C44.4302 39.6928 45.7232 39.865 47.0091 39.865C49.5145 39.865 51.9931 39.2113 54.2359 37.9305L54.6941 37.6687L54.6886 37.139ZM40.0878 12.1068L40.5393 12.3722C47.4822 16.4532 49.8515 25.4683 45.8206 32.4686C44.9135 34.0439 43.7216 35.4371 42.3214 36.5745C41.7042 36.3236 41.1102 36.0235 40.5445 35.6779C42.0591 34.6 43.3375 33.1961 44.2724 31.5723C47.7249 25.5767 45.8347 17.8993 40.0869 14.1965C36.9575 16.2106 34.8408 19.5066 34.274 23.1534C33.6161 23.4268 32.9798 23.7466 32.369 24.1104C32.5218 21.8982 33.1735 19.7309 34.2753 17.7961C35.5512 15.5558 37.4049 13.6801 39.6361 12.3718L40.0878 12.1068Z" fill="white"/>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
@ -1,278 +0,0 @@
|
||||
module.exports = {
|
||||
theme: 'cosmos',
|
||||
title: 'Ethermint Documentation',
|
||||
locales: {
|
||||
'/': {
|
||||
lang: 'en-US'
|
||||
},
|
||||
},
|
||||
markdown: {
|
||||
extendMarkdown: (md) => {
|
||||
md.use(require("markdown-it-katex"));
|
||||
},
|
||||
},
|
||||
head: [
|
||||
[
|
||||
"link",
|
||||
{
|
||||
rel: "stylesheet",
|
||||
href:
|
||||
"https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css",
|
||||
},
|
||||
],
|
||||
[
|
||||
"link",
|
||||
{
|
||||
rel: "stylesheet",
|
||||
href:
|
||||
"https://cdn.jsdelivr.net/github-markdown-css/2.2.1/github-markdown.css",
|
||||
},
|
||||
],
|
||||
],
|
||||
base: process.env.VUEPRESS_BASE || '/',
|
||||
plugins: [
|
||||
'vuepress-plugin-element-tabs'
|
||||
],
|
||||
themeConfig: {
|
||||
repo: 'tharsis/ethermint',
|
||||
docsRepo: 'tharsis/ethermint',
|
||||
docsBranch: 'main',
|
||||
docsDir: 'docs',
|
||||
editLinks: true,
|
||||
custom: true,
|
||||
project: {
|
||||
name: 'Ethermint',
|
||||
denom: 'PHOTON',
|
||||
ticker: 'ETHM',
|
||||
rpc_url: '',
|
||||
rpc_url_local: 'http://localhost:8545/',
|
||||
chain_id: '9000',
|
||||
block_explorer_url: '',
|
||||
},
|
||||
logo: {
|
||||
src: '/ethermint-logo-horizontal-alpha.svg',
|
||||
},
|
||||
algolia: {
|
||||
id: 'BH4D9OD16A',
|
||||
key: 'c5da4dd3636828292e3c908a0db39688',
|
||||
index: 'ethermint'
|
||||
},
|
||||
topbar: {
|
||||
banner: false
|
||||
},
|
||||
sidebar: {
|
||||
auto: false,
|
||||
nav: [
|
||||
{
|
||||
title: 'Reference',
|
||||
children: [
|
||||
{
|
||||
title: 'Introduction',
|
||||
directory: true,
|
||||
path: '/intro'
|
||||
},
|
||||
{
|
||||
title: 'Quick Start',
|
||||
directory: true,
|
||||
path: '/quickstart'
|
||||
},
|
||||
{
|
||||
title: 'Basics',
|
||||
directory: true,
|
||||
path: '/basics'
|
||||
},
|
||||
{
|
||||
title: 'Core Concepts',
|
||||
directory: true,
|
||||
path: '/core'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Guides',
|
||||
children: [
|
||||
{
|
||||
title: 'Localnet',
|
||||
directory: true,
|
||||
path: '/guides/localnet'
|
||||
},
|
||||
{
|
||||
title: 'Keys and Wallets',
|
||||
directory: true,
|
||||
path: '/guides/keys-wallets'
|
||||
},
|
||||
{
|
||||
title: 'Ethereum Tooling',
|
||||
directory: true,
|
||||
path: '/guides/tools'
|
||||
},
|
||||
{
|
||||
title: 'Validators',
|
||||
directory: true,
|
||||
path: '/guides/validators'
|
||||
},
|
||||
{
|
||||
title: 'Key Management System',
|
||||
directory: true,
|
||||
path: '/guides/kms'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'APIs',
|
||||
children: [
|
||||
{
|
||||
title: 'JSON-RPC',
|
||||
directory: true,
|
||||
path: '/api/json-rpc'
|
||||
},
|
||||
{
|
||||
title: 'Protobuf Reference',
|
||||
directory: false,
|
||||
path: '/api/proto-docs'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Testnet',
|
||||
children: [
|
||||
{
|
||||
title: 'Join Testnet',
|
||||
directory: false,
|
||||
path: '/testnet/join'
|
||||
},
|
||||
{
|
||||
title: 'Token Faucet',
|
||||
directory: false,
|
||||
path: '/testnet/faucet'
|
||||
},
|
||||
{
|
||||
title: 'Deploy Node on Cloud',
|
||||
directory: false,
|
||||
path: '/testnet/cloud_providers'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Specifications',
|
||||
children: [{
|
||||
title: 'Modules',
|
||||
directory: true,
|
||||
path: '/modules'
|
||||
}]
|
||||
}, {
|
||||
title: 'Resources',
|
||||
children: [
|
||||
{
|
||||
title: 'Ethermint API Reference',
|
||||
path: 'https://pkg.go.dev/github.com/tharsis/ethermint'
|
||||
},
|
||||
{
|
||||
title: 'Cosmos REST API Spec',
|
||||
path: 'https://cosmos.network/rpc/'
|
||||
},
|
||||
{
|
||||
title: 'JSON-RPC API Reference',
|
||||
path: '/api/json-rpc/endpoints'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
gutter: {
|
||||
title: 'Help & Support',
|
||||
chat: {
|
||||
title: 'Developer Chat',
|
||||
text: 'Chat with Ethermint developers on Discord.',
|
||||
url: 'https://discord.gg/trje9XuAmy',
|
||||
bg: 'linear-gradient(103.75deg, #1B1E36 0%, #22253F 100%)'
|
||||
},
|
||||
forum: {
|
||||
title: 'Ethermint Developer Forum',
|
||||
text: 'Join the Ethermint Developer Forum to learn more.',
|
||||
url: 'https://forum.cosmos.network/c/ethermint',
|
||||
bg: 'linear-gradient(221.79deg, #3D6B99 -1.08%, #336699 95.88%)',
|
||||
logo: 'ethereum-white'
|
||||
},
|
||||
github: {
|
||||
title: 'Found an Issue?',
|
||||
text: 'Help us improve this page by suggesting edits on GitHub.',
|
||||
bg: '#F8F9FC'
|
||||
}
|
||||
},
|
||||
footer: {
|
||||
logo: '/logo-bw.svg',
|
||||
textLink: {
|
||||
text: 'ethermint.dev',
|
||||
url: 'https://ethermint.dev'
|
||||
},
|
||||
services: [
|
||||
{
|
||||
service: 'github',
|
||||
url: 'https://github.com/tharsis/ethermint'
|
||||
},
|
||||
{
|
||||
service: "twitter",
|
||||
url: "https://twitter.com/ethermint",
|
||||
},
|
||||
{
|
||||
service: "linkedin",
|
||||
url: "https://www.linkedin.com/company/tharsis-finance/",
|
||||
},
|
||||
{
|
||||
service: "medium",
|
||||
url: "https://medium.com/@tharsis_labs",
|
||||
},
|
||||
],
|
||||
smallprint: 'This website is maintained by Tharsis Labs Ltd.',
|
||||
links: [{
|
||||
title: 'Documentation',
|
||||
children: [{
|
||||
title: 'Cosmos SDK Docs',
|
||||
url: 'https://docs.cosmos.network/master/'
|
||||
},
|
||||
{
|
||||
title: 'Ethereum Docs',
|
||||
url: 'https://ethereum.org/developers'
|
||||
},
|
||||
{
|
||||
title: 'Tendermint Core Docs',
|
||||
url: 'https://docs.tendermint.com'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Community',
|
||||
children: [{
|
||||
title: 'Ethermint Community',
|
||||
url: 'https://discord.gg/trje9XuAmy'
|
||||
},
|
||||
{
|
||||
title: 'Ethermint Forum',
|
||||
url: 'https://forum.cosmos.network/c/ethermint'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Tharsis',
|
||||
children: [
|
||||
{
|
||||
title: 'Jobs at Tharsis',
|
||||
url: 'https://tharsis.notion.site/Jobs-at-Tharsis-5a1642eb89b34747ae6f2db2d356fc0d'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
versions: [
|
||||
{
|
||||
"label": "main",
|
||||
"key": "main"
|
||||
},
|
||||
{
|
||||
"label": "v0.5",
|
||||
"key": "v0.5"
|
||||
}
|
||||
],
|
||||
}
|
||||
};
|
@ -1,84 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 526 192" style="enable-background:new 0 0 526 192;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:url(#SVGID_1_);}
|
||||
.st1{fill:url(#SVGID_2_);}
|
||||
.st2{fill:url(#SVGID_3_);}
|
||||
.st3{fill:url(#SVGID_4_);}
|
||||
.st4{fill:#B3C9F4;}
|
||||
.st5{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
|
||||
.st6{fill:#717BBF;}
|
||||
.st7{opacity:0.5;fill:url(#SVGID_5_);enable-background:new ;}
|
||||
.st8{opacity:0.5;fill:url(#SVGID_6_);enable-background:new ;}
|
||||
.st9{fill:#131516;}
|
||||
</style>
|
||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="96.4904" y1="115.7662" x2="80.8316" y2="187.581" gradientTransform="matrix(1 0 0 -1 0 194)">
|
||||
<stop offset="0" style="stop-color:#8D8DE4"/>
|
||||
<stop offset="1" style="stop-color:#89A2E5;stop-opacity:0"/>
|
||||
<stop offset="1" style="stop-color:#BBD9FF;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
<path class="st0" d="M76.9,7v123.2l54.8-32.3L76.9,7z"/>
|
||||
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="85.6408" y1="131.291" x2="28.6749" y2="93.2238" gradientTransform="matrix(1 0 0 -1 0 194)">
|
||||
<stop offset="0" style="stop-color:#8D8DE4"/>
|
||||
<stop offset="1" style="stop-color:#89A2E5;stop-opacity:0"/>
|
||||
<stop offset="1" style="stop-color:#BBD9FF;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
<path class="st1" d="M22.1,97.8l54.8,32.3V7L22.1,97.8z"/>
|
||||
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="22.1" y1="47.25" x2="76.9" y2="47.25" gradientTransform="matrix(1 0 0 -1 0 194)">
|
||||
<stop offset="0" style="stop-color:#E3FFFF"/>
|
||||
<stop offset="1" style="stop-color:#89A2E5"/>
|
||||
<stop offset="1" style="stop-color:#BBF9FF;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
<path class="st2" d="M22.1,108.2l54.8,77.1v-44.8L22.1,108.2z"/>
|
||||
<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="-52.6532" y1="253.8875" x2="422.5458" y2="-79.853">
|
||||
<stop offset="6.489749e-03" style="stop-color:#DC614D"/>
|
||||
<stop offset="0.3603" style="stop-color:#8D8DE4"/>
|
||||
<stop offset="1" style="stop-color:#89A2E5"/>
|
||||
</linearGradient>
|
||||
<path class="st3" d="M76.9,140.5v44.8l54.8-77.1L76.9,140.5z"/>
|
||||
<g>
|
||||
<path class="st4" d="M76.9,72.9L22.1,97.8l54.8,32.3l54.8-32.3L76.9,72.9z"/>
|
||||
</g>
|
||||
<path class="st5" d="M89.6,62.4c-4-1.6-8.3-2.4-12.7-2.4c-9.2,0-17.8,3.6-24.3,10.1s-10,15.2-10.1,24.3v1.2l1.1,0.6
|
||||
c5.2,2.9,11,4.5,16.9,4.5c0.2,0,0.3,0,0.5,0c5.2-0.1,10.3-1.3,14.9-3.6c-1.5-0.8-2.9-1.7-4.2-2.8c-8.1,3.2-17.2,2.8-24.9-1.2
|
||||
c0.8-16.1,14-29,30.1-29c4.5,0,8.9,1,12.9,2.9C89.8,65.5,89.8,64,89.6,62.4"/>
|
||||
<path class="st5" d="M111.3,94.2c-0.1-11.5-5.7-21.9-14.9-28.3c0,1.7-0.1,3.4-0.3,5c6.6,5.4,10.6,13.3,11,22
|
||||
c-14.2,7.3-31.9,2.2-40-11.8c-2.2-3.8-3.5-8-3.9-12.4c-1.4,0.8-2.7,1.6-3.9,2.6c0.7,4.2,2.1,8.2,4.2,11.9c4.6,8,12,13.7,20.8,16.1
|
||||
c3,0.8,6,1.2,9,1.2c5.9,0,11.7-1.5,17-4.5l1.1-0.6L111.3,94.2z"/>
|
||||
<path class="st5" d="M78.1,36L77,35.4L76,36c-5.2,3.1-9.6,7.5-12.6,12.7c-2.6,4.5-4.1,9.6-4.5,14.8c1.4-0.9,2.9-1.6,4.5-2.2
|
||||
c1.3-8.6,6.3-16.3,13.7-21C90.6,49,95,67.1,86.9,81.1c-2.2,3.8-5.2,7.1-8.8,9.6c1.3,0.8,2.7,1.5,4.2,2.1c3.3-2.7,6.1-5.9,8.2-9.6
|
||||
C100,66.8,94.4,45.6,78.1,36"/>
|
||||
<polygon class="st6" points="76.9,146.5 131.7,108.2 131.7,108.2 76.9,140.5 22.1,108.2 22.1,108.2 "/>
|
||||
<linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="75.5332" y1="186.2992" x2="42.3256" y2="50.7691" gradientTransform="matrix(1 0 0 -1 0 194)">
|
||||
<stop offset="0" style="stop-color:#E3FFFF"/>
|
||||
<stop offset="1" style="stop-color:#BBF9FF;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
<path class="st7" d="M22.1,97.8l54.8,32.3V7L22.1,97.8z"/>
|
||||
<linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="117.958" y1="89.2972" x2="55.3226" y2="144.3732" gradientTransform="matrix(1 0 0 -1 0 194)">
|
||||
<stop offset="1.975860e-02" style="stop-color:#DD5C47"/>
|
||||
<stop offset="1" style="stop-color:#BBF9FF;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
<path class="st8" d="M76.9,7v123.2l54.8-32.3L76.9,7z"/>
|
||||
<g>
|
||||
<path class="st9" d="M182.2,76.1h34.4v8.4h-24.7V97h19.8v8.4h-19.8v13.8h25.5v8.5h-35.2L182.2,76.1L182.2,76.1z"/>
|
||||
<path class="st9" d="M235.6,79.3v11.2h10.3v7.6h-10.3v16.2c0,3.8,2,5.7,5.4,5.7h4.9v7.7h-6c-8.1,0-13.4-4.7-13.4-13V98.2h-7.3v-7.6
|
||||
h7.3V79.3H235.6z"/>
|
||||
<path class="st9" d="M252.8,74.6h9v21.7c2.1-4.1,6.4-6.4,11.7-6.4c8.3,0,13.8,6.1,13.8,14.8v23h-9v-21.1c0-5.1-3.2-8.6-7.8-8.6
|
||||
c-5,0-8.6,4-8.6,9.5v20.3h-9L252.8,74.6L252.8,74.6z"/>
|
||||
<path class="st9" d="M328.9,115.4c-1.4,7.9-8.3,13-17.5,13c-12.2,0-19-9.6-19-19.4s6.1-19.1,18.2-19.1c12.5,0,18.1,9.1,18.1,17.9
|
||||
c0,1.3-0.1,2.4-0.1,3.1h-27.5c0.7,6,4.5,9.8,10.3,9.8c4.7,0,7.7-1.9,8.6-5.5h8.9V115.4z M301.4,105h18.3c-0.4-4.7-3.6-8.3-9-8.3
|
||||
C305.6,96.7,302.3,99.4,301.4,105z"/>
|
||||
<path class="st9" d="M351.2,98.2c-5.8,0-8.1,4.9-8.1,12v17.6H334V90.5h9.1v6.6c1.8-4.7,4.7-6.6,9.5-6.6h4.4v7.6L351.2,98.2
|
||||
L351.2,98.2z"/>
|
||||
<path class="st9" d="M361.2,90.5h9.1v5.8c1.8-3.8,5.5-6.4,10.8-6.4c5.9,0,10,2.5,11.6,7.1c1.7-3.8,6.4-7.1,12.3-7.1
|
||||
c8.1,0,13.2,5.8,13.2,13.7v24.1h-9v-21.3c0-5.2-2.7-8.7-7.1-8.7c-4.9,0-7.9,3.5-7.9,8.7v21.3h-9v-21.3c0-5.2-2.7-8.7-7.1-8.7
|
||||
c-4.8,0-7.8,3.5-7.8,8.7v21.3h-9.1V90.5z"/>
|
||||
<path class="st9" d="M434.7,74.6v10.1h-9.8V74.6H434.7z M425.3,90.5h9.1v37.2h-9.1V90.5z"/>
|
||||
<path class="st9" d="M441.5,90.5h9.1v5.8c2.1-4.1,6.3-6.4,11.6-6.4c8.4,0,13.9,6.1,13.9,14.8v23H467v-21.1c0-5.1-3.1-8.6-7.8-8.6
|
||||
c-5.1,0-8.6,4-8.6,9.5v20.3h-9.1V90.5z"/>
|
||||
<path class="st9" d="M495.6,79.3v11.2h10.3v7.6h-10.3v16.2c0,3.8,2,5.7,5.4,5.7h4.9v7.7h-6c-8.1,0-13.4-4.7-13.4-13V98.2h-7.3v-7.6
|
||||
h7.3V79.3H495.6z"/>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 5.5 KiB |
@ -1,94 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg width="240" height="96" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 526 192" style="enable-background:new 0 0 526 192;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#131516;}
|
||||
.st1{fill:url(#SVGID_1_);}
|
||||
.st2{fill:url(#SVGID_2_);}
|
||||
.st3{fill:url(#SVGID_3_);}
|
||||
.st4{fill:url(#SVGID_4_);}
|
||||
.st5{fill:#B3C9F4;}
|
||||
.st6{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
|
||||
.st7{fill:#717BBF;}
|
||||
.st8{opacity:0.5;fill:url(#SVGID_5_);enable-background:new ;}
|
||||
.st9{opacity:0.5;fill:url(#SVGID_6_);enable-background:new ;}
|
||||
</style>
|
||||
<g>
|
||||
<path class="st0" d="M180.9,75.3l35,0v8.6l-25.1,0v12.8l20.1,0v8.6l-20.1,0v14l25.9,0l0,8.6l-35.8,0L180.9,75.3z"/>
|
||||
<path class="st0" d="M247.7,73.8l9.2,0v22.1c2.1-4.1,6.5-6.5,11.9-6.5c8.5,0,14,6.2,14,15v23.4l-9.2,0l0-21.5c0-5.2-3.2-8.8-8-8.8
|
||||
c-5.1,0-8.8,4.1-8.8,9.6l0,20.6l-9.2,0L247.7,73.8z"/>
|
||||
<path class="st0" d="M324.3,115.2c-1.4,8-8.5,13.2-17.8,13.2c-12.4,0-19.3-9.8-19.3-19.7c0-10,6.2-19.4,18.5-19.4
|
||||
c12.7,0,18.4,9.2,18.4,18.2c0,1.3-0.1,2.4-0.1,3.2l-27.9,0c0.7,6.1,4.6,10,10.4,10c4.7,0,7.8-2,8.8-5.6L324.3,115.2z M296.3,104.7
|
||||
l18.6,0c-0.4-4.8-3.7-8.4-9.2-8.4C300.6,96.3,297.2,99,296.3,104.7z"/>
|
||||
<path class="st0" d="M345.3,97.7c-5.9,0-8.2,5-8.2,12.2v17.9l-9.2,0l0-37.8l9.2,0v6.7c1.9-4.8,4.8-6.7,9.7-6.7h4.4v7.7L345.3,97.7z
|
||||
"/>
|
||||
<path class="st0" d="M355.9,90l9.2,0v5.9c1.9-3.8,5.6-6.5,11-6.5c6,0,10.1,2.6,11.8,7.2c1.7-3.9,6.5-7.2,12.5-7.2
|
||||
c8.2,0,13.4,5.9,13.4,14l0,24.5l-9.2,0l0-21.7c0-5.3-2.8-8.9-7.2-8.9c-5,0-8,3.5-8,8.9v21.7l-9.2,0v-21.7c0-5.3-2.8-8.9-7.2-8.9
|
||||
c-4.9,0-8,3.5-8,8.9l0,21.7l-9.2,0L355.9,90z"/>
|
||||
<path class="st0" d="M429.1,73.8v10.3l-9.9,0l0-10.3L429.1,73.8z M419.5,90l9.2,0l0,37.8l-9.2,0L419.5,90z"/>
|
||||
<path class="st0" d="M435,90l9.2,0v5.9c2.1-4.1,6.4-6.5,11.8-6.5c8.6,0,14.1,6.2,14.1,15v23.4l-9.2,0v-21.5c0-5.2-3.2-8.8-7.9-8.8
|
||||
c-5.2,0-8.8,4.1-8.8,9.6l0,20.6l-9.2,0L435,90z"/>
|
||||
<path class="st0" d="M489.4,78.4v11.5h10.6v7.8h-10.6v16.6c0,3.8,2,5.8,5.5,5.8h5.1v7.8h-6.1c-8.3,0-13.7-4.8-13.7-13.3v-17h-7.5
|
||||
v-7.8h7.5V78.4H489.4z"/>
|
||||
<path class="st0" d="M233.4,78.4v11.5h10.6v7.8h-10.6v16.6c0,3.8,2,5.8,5.5,5.8h5.1v7.8h-6.1c-8.3,0-13.7-4.8-13.7-13.3v-17h-7.5
|
||||
v-7.8h7.5V78.4H233.4z"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
|
||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="-624.5055" y1="-406.1891" x2="-639.7977" y2="-476.3224" gradientTransform="matrix(1 0 0 1 720.2893 484.6111)">
|
||||
<stop offset="0" style="stop-color:#8D8DE4"/>
|
||||
<stop offset="1" style="stop-color:#89A2E5;stop-opacity:0"/>
|
||||
<stop offset="1" style="stop-color:#BBD9FF;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
<path class="st1" d="M76.7,8.8v120.3l53.5-31.6L76.7,8.8z"/>
|
||||
|
||||
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="-635.0693" y1="-421.3597" x2="-690.7014" y2="-384.1838" gradientTransform="matrix(1 0 0 1 720.2893 484.6111)">
|
||||
<stop offset="0" style="stop-color:#8D8DE4"/>
|
||||
<stop offset="1" style="stop-color:#89A2E5;stop-opacity:0"/>
|
||||
<stop offset="1" style="stop-color:#BBD9FF;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
<path class="st2" d="M23.1,97.5l53.5,31.6V8.8L23.1,97.5z"/>
|
||||
</g>
|
||||
|
||||
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="23.0618" y1="-1965.4794" x2="76.6382" y2="-1965.4794" gradientTransform="matrix(1 0 0 -1 0 -1820)">
|
||||
<stop offset="0" style="stop-color:#E3FFFF"/>
|
||||
<stop offset="1" style="stop-color:#89A2E5"/>
|
||||
<stop offset="1" style="stop-color:#BBF9FF;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
<path class="st3" d="M23.1,107.8l53.6,75.4v-43.8L23.1,107.8z"/>
|
||||
|
||||
<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="-50.0858" y1="1004.2726" x2="414.7754" y2="677.7925" gradientTransform="matrix(1 0 0 1 0 -754)">
|
||||
<stop offset="6.489749e-03" style="stop-color:#DC614D"/>
|
||||
<stop offset="0.3603" style="stop-color:#8D8DE4"/>
|
||||
<stop offset="1" style="stop-color:#89A2E5"/>
|
||||
</linearGradient>
|
||||
<path class="st4" d="M76.6,139.4v43.8l53.6-75.4L76.6,139.4z"/>
|
||||
<g>
|
||||
<path class="st5" d="M76.6,73.2L23.1,97.6l53.6,31.6l53.6-31.6L76.6,73.2z"/>
|
||||
</g>
|
||||
<path class="st6" d="M89.1,63c-3.9-1.5-8.1-2.4-12.4-2.4c-9,0-17.4,3.5-23.7,9.9c-6.3,6.4-9.8,14.8-9.9,23.7v1.2l1.1,0.6
|
||||
c5.1,2.9,10.8,4.4,16.5,4.4c0.2,0,0.3,0,0.5,0c5.1-0.1,10.1-1.3,14.6-3.5c-1.5-0.8-2.9-1.7-4.1-2.7c-7.9,3.2-16.8,2.7-24.4-1.2
|
||||
C48,77.2,61,64.6,76.6,64.6c4.4,0,8.7,1,12.6,2.9C89.3,66,89.3,64.6,89.1,63"/>
|
||||
<path class="st6" d="M110.3,94.1c-0.1-11.3-5.6-21.4-14.6-27.7c0,1.7-0.1,3.3-0.3,4.9c6.4,5.3,10.4,13,10.8,21.5
|
||||
C92.4,100,75,95,67.1,81.3c-2.2-3.7-3.4-7.8-3.8-12.1c-1.4,0.8-2.7,1.5-3.8,2.5c0.7,4.1,2,8.1,4.1,11.6
|
||||
c4.5,7.8,11.8,13.4,20.4,15.8c2.9,0.8,5.9,1.2,8.8,1.2c5.7,0,11.4-1.5,16.6-4.4l1.1-0.6L110.3,94.1z"/>
|
||||
<path class="st6" d="M77.8,37.2l-1.1-0.6l-1,0.6c-5.1,3-9.4,7.4-12.3,12.4c-2.5,4.4-4,9.4-4.4,14.5c1.4-0.9,2.9-1.5,4.4-2.2
|
||||
c1.3-8.4,6.2-16,13.4-20.5c13.2,8.5,17.5,26.2,9.6,39.9c-2.2,3.7-5.1,6.9-8.6,9.4c1.3,0.8,2.7,1.5,4.1,2c3.2-2.7,6-5.7,8.1-9.4
|
||||
C99.3,67.3,93.8,46.6,77.8,37.2"/>
|
||||
<polygon class="st7" points="76.6,145.2 130.3,107.8 130.3,107.8 76.6,139.4 23.1,107.8 23.1,107.8 "/>
|
||||
|
||||
<linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="75.316" y1="-1829.4694" x2="42.8308" y2="-1962.051" gradientTransform="matrix(1 0 0 -1 0 -1820)">
|
||||
<stop offset="0" style="stop-color:#E3FFFF"/>
|
||||
<stop offset="1" style="stop-color:#BBF9FF;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
<path class="st8" d="M23.1,97.6l53.6,31.6V8.8L23.1,97.6z"/>
|
||||
|
||||
<linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="116.8103" y1="-1924.3955" x2="55.5375" y2="-1870.5176" gradientTransform="matrix(1 0 0 -1 0 -1820)">
|
||||
<stop offset="1.975860e-02" style="stop-color:#DD5C47"/>
|
||||
<stop offset="1" style="stop-color:#BBF9FF;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
<path class="st9" d="M76.6,8.8v120.5l53.6-31.6L76.6,8.8z"/>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 5.9 KiB |
@ -1,3 +0,0 @@
|
||||
:root
|
||||
--color-link #3171B0
|
||||
--color-primary #7499BF
|
@ -1,111 +0,0 @@
|
||||
# Updating the docs
|
||||
|
||||
If you want to open a PR on the Cosmos SDK to update the documentation, please follow the guidelines in the [`CONTRIBUTING.md`](https://github.com/tharsis/ethermint/tree/main/CONTRIBUTING.md#updating-documentation)
|
||||
|
||||
## Translating
|
||||
|
||||
- Docs translations live in a `docs/country-code/` folder, where `country-code` stands for the country code of the language used (`cn` for Chinese, `kr` for Korea, `fr` for France, ...).
|
||||
- Always translate content living on `main`.
|
||||
- Only content under `/docs/intro/`, `/docs/basics/`, `/docs/core/`, `/docs/building-modules/` and `docs/interfaces` needs to be translated, as well as `docs/README.md`. It is also nice (but not mandatory) to translate `/docs/spec/`.
|
||||
- Specify the release/tag of the translation in the README of your translation folder. Update the release/tag each time you update the translation.
|
||||
|
||||
## Docs Build Workflow
|
||||
|
||||
The documentation for Ethermint is hosted at https://ethermint.dev/
|
||||
|
||||
built from the files in this (`/docs`) directory for
|
||||
[master](https://github.com/tharsis/ethermint/tree/main/docs).
|
||||
|
||||
### How It Works
|
||||
|
||||
There is a CircleCI job listening for changes in the `/docs` directory, on
|
||||
the `main` branch. Any updates to files in this directory
|
||||
on that branch will automatically trigger a website deployment. Under the hood,
|
||||
the private website repository has a `make build-docs` target consumed by a CircleCI job in that repo.
|
||||
|
||||
## README
|
||||
|
||||
The [README.md](./README.md) is also the landing page for the documentation
|
||||
on the website. During the Jenkins build, the current commit is added to the bottom
|
||||
of the README.
|
||||
|
||||
## Config.js
|
||||
|
||||
The [config.js](./.vuepress/config.js) generates the sidebar and Table of Contents
|
||||
on the website docs. Note the use of relative links and the omission of
|
||||
file extensions. Additional features are available to improve the look
|
||||
of the sidebar.
|
||||
|
||||
## Links
|
||||
|
||||
**NOTE:** Strongly consider the existing links - both within this directory
|
||||
and to the website docs - when moving or deleting files.
|
||||
|
||||
Relative links should be used nearly everywhere, having discovered and weighed the following:
|
||||
|
||||
### Relative
|
||||
|
||||
Where is the other file, relative to the current one?
|
||||
|
||||
- works both on GitHub and for the VuePress build
|
||||
- confusing / annoying to have things like: `../../../../myfile.md`
|
||||
- requires more updates when files are re-shuffled
|
||||
|
||||
### Absolute
|
||||
|
||||
Where is the other file, given the root of the repo?
|
||||
|
||||
- works on GitHub, doesn't work for the VuePress build
|
||||
- this is much nicer: `/docs/hereitis/myfile.md`
|
||||
- if you move that file around, the links inside it are preserved (but not to it, of course)
|
||||
|
||||
### Full
|
||||
|
||||
The full GitHub URL to a file or directory. Used occasionally when it makes sense
|
||||
to send users to the GitHub.
|
||||
|
||||
## Building Locally
|
||||
|
||||
Make sure you are in the `docs` directory and run the following commands:
|
||||
|
||||
```bash
|
||||
rm -rf node_modules
|
||||
```
|
||||
|
||||
This command will remove old version of the visual theme and required packages. This step is optional.
|
||||
|
||||
```bash
|
||||
yarn install
|
||||
```
|
||||
|
||||
Install the theme and all dependencies.
|
||||
|
||||
```bash
|
||||
yarn run serve
|
||||
```
|
||||
|
||||
Run `pre` and `post` hooks and start a hot-reloading web-server. See output of this command for the URL (it is often [https://localhost:8080](https://localhost:8080)).
|
||||
|
||||
To build documentation as a static website run `yarn run build`. You will find the website in `.vuepress/dist` directory.
|
||||
|
||||
## Search
|
||||
|
||||
We are using [Algolia](https://www.algolia.com) to power full-text search. This uses a public API search-only key in the `config.js` as well as a [cosmos_network.json](https://github.com/algolia/docsearch-configs/blob/main/configs/cosmos_network.json) configuration file that we can update with PRs.
|
||||
|
||||
### Update and Build the RPC docs
|
||||
|
||||
1. Execute the following command at the root directory to install the swagger-ui generate tool.
|
||||
|
||||
```bash
|
||||
make tools
|
||||
```
|
||||
|
||||
2. Edit API docs
|
||||
1. Directly Edit API docs manually: `client/lcd/swagger-ui/swagger.yaml`.
|
||||
2. Edit API docs within the [Swagger Editor](https://editor.swagger.io/). Please refer to this [document](https://swagger.io/docs/specification/2-0/basic-structure/) for the correct structure in `.yaml`.
|
||||
3. Download `swagger.yaml` and replace the old `swagger.yaml` under fold `client/lcd/swagger-ui`.
|
||||
4. Compile ethermintd
|
||||
|
||||
```bash
|
||||
make install
|
||||
```
|
@ -1,60 +0,0 @@
|
||||
<!--
|
||||
layout: home
|
||||
title: Ethermint Documentation
|
||||
description: Ethermint is a scalable and interoperable Ethereum, built on Proof-of-Stake with fast-finality.
|
||||
sections:
|
||||
- title: Introduction
|
||||
desc: Read a high-level overview of Ethermint and its architecture.
|
||||
url: /intro
|
||||
icon: ethereum-intro
|
||||
- title: Basics
|
||||
desc: Start with the basic concepts of Ethermint, like accounts and transactions.
|
||||
url: /basics
|
||||
icon: basics
|
||||
- title: Core Concepts
|
||||
desc: Read about the core concepts like encoding and events.
|
||||
url: /core
|
||||
icon: core
|
||||
stack:
|
||||
- title: Cosmos SDK
|
||||
desc: The SDK is the world’s most popular framework for building application-specific blockchains.
|
||||
color: "#5064FB"
|
||||
label: sdk
|
||||
url: http://docs.cosmos.network
|
||||
- title: Ethereum
|
||||
desc: Ethereum is a global, open-source platform for decentralized applications.
|
||||
color: "#1A1F36"
|
||||
label: ethereum-black
|
||||
url: https://eth.wiki
|
||||
- title: Tendermint Core
|
||||
desc: The leading BFT engine for building blockchains, powering Ethermint.
|
||||
color: "#00BB00"
|
||||
label: core
|
||||
url: http://docs.tendermint.com
|
||||
footer:
|
||||
newsletter: false
|
||||
aside: false
|
||||
-->
|
||||
|
||||
# Ethermint Documentation
|
||||
|
||||
## Get Started
|
||||
|
||||
- **[Introduction](./intro/overview.md)**: High-level overview of Ethermint.
|
||||
|
||||
## Reference
|
||||
|
||||
- **[Basics](./basics/)**: Documentation on the basic concepts of Ethermint, like the standard anatomy of an application, the transaction lifecycle and accounts management.
|
||||
- **[Core](./core/)**: Documentation on the core concepts of Ethermint, like `encoding`, and `events`.
|
||||
- **[Building Modules](./building-modules/)**: Important concepts for module developers like `message`s, `keeper`s, `handler`s and `querier`s.
|
||||
- **[Interfaces](./interfaces/)**: Documentation on building interfaces for Ethermint applications.
|
||||
|
||||
## Other Resources
|
||||
|
||||
- **[Module Directory](../x/)**: Module implementations and their respective documentation.
|
||||
- **[Ethermint API Reference](https://godoc.org/github.com/tharsis/ethermint)**: Godocs of Ethermint.
|
||||
- **[REST API spec](https://cosmos.network/rpc/)**: List of REST endpoints to interact with an full-node through REST.
|
||||
|
||||
## Contribute
|
||||
|
||||
See [this file](https://github.com/tharsis/ethermint/blob/main/docs/DOCS_README.md) for details of the build process and considerations when making changes.
|
@ -1,12 +0,0 @@
|
||||
<!--
|
||||
order: false
|
||||
parent:
|
||||
order: 1
|
||||
-->
|
||||
|
||||
# API
|
||||
|
||||
This section contains different client and API reference document.
|
||||
|
||||
1. [JSON-RPC](./json-rpc.md)
|
||||
1. [Protobuf Docs](./proto-docs.md)
|
@ -1,130 +0,0 @@
|
||||
<!--
|
||||
order: 5
|
||||
-->
|
||||
|
||||
# Events
|
||||
|
||||
`Event`s are objects that contain information about the execution of the application. They are
|
||||
mainly used by service providers like block explorers and wallet to track the execution of various
|
||||
messages and index transactions. {synopsis}
|
||||
|
||||
## Pre-requisite Readings
|
||||
|
||||
- [Cosmos SDK Events](https://docs.cosmos.network/master/core/events.html) {prereq}
|
||||
- [Ethereum's PubSub JSON-RPC API](https://geth.ethereum.org/docs/rpc/pubsub) {prereq}
|
||||
|
||||
## Subscribing to Events
|
||||
|
||||
### SDK and Tendermint Events
|
||||
|
||||
It is possible to subscribe to `Events` via Tendermint's [Websocket](https://tendermint.com/docs/app-dev/subscribing-to-events-via-websocket.html#subscribing-to-events-via-websocket).
|
||||
This is done by calling the `subscribe` RPC method via Websocket:
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "subscribe",
|
||||
"id": "0",
|
||||
"params": {
|
||||
"query": "tm.event='eventCategory' AND eventType.eventAttribute='attributeValue'"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The main `eventCategory` you can subscribe to are:
|
||||
|
||||
- `NewBlock`: Contains `events` triggered during `BeginBlock` and `EndBlock`.
|
||||
- `Tx`: Contains `events` triggered during `DeliverTx` (i.e. transaction processing).
|
||||
- `ValidatorSetUpdates`: Contains validator set updates for the block.
|
||||
|
||||
These events are triggered from the `state` package after a block is committed. You can get the full
|
||||
list of `event` categories
|
||||
[here](https://godoc.org/github.com/tendermint/tendermint/types#pkg-constants).
|
||||
|
||||
The `type` and `attribute` value of the `query` allow you to filter the specific `event` you are
|
||||
looking for. For example, a `MsgEthereumTx` transaction triggers an `event` of type `ethermint` and
|
||||
has `sender` and `recipient` as `attributes`. Subscribing to this `event` would be done like so:
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "subscribe",
|
||||
"id": "0",
|
||||
"params": {
|
||||
"query": "tm.event='Tx' AND ethereum.recipient='hexAddress'"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
where `hexAddress` is an Ethereum hex address (eg: `0x1122334455667788990011223344556677889900`).
|
||||
|
||||
### Ethereum JSON-RPC Events
|
||||
|
||||
Ethermint also supports the Ethereum [JSON-RPC](https://eth.wiki/json-rpc/API) filters calls to
|
||||
subscribe to [state logs](https://eth.wiki/json-rpc/API#eth_newfilter),
|
||||
[blocks](https://eth.wiki/json-rpc/API#eth_newblockfilter) or [pending
|
||||
transactions](https://eth.wiki/json-rpc/API#eth_newpendingtransactionfilter) changes.
|
||||
|
||||
Under the hood, it uses the Tendermint RPC client's event system to process subscriptions that are
|
||||
then formatted to Ethereum-compatible events.
|
||||
|
||||
```bash
|
||||
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_newBlockFilter","params":[],"id":1}' -H "Content-Type: application/json" http://localhost:8545
|
||||
|
||||
{"jsonrpc":"2.0","id":1,"result":"0x3503de5f0c766c68f78a03a3b05036a5"}
|
||||
```
|
||||
|
||||
Then you can check if the state changes with the [`eth_getFilterChanges`](https://eth.wiki/json-rpc/API#eth_getfilterchanges) call:
|
||||
|
||||
```bash
|
||||
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getFilterChanges","params":["0x3503de5f0c766c68f78a03a3b05036a5"],"id":1}' -H "Content-Type: application/json" http://localhost:8545
|
||||
|
||||
{"jsonrpc":"2.0","id":1,"result":["0x7d44dceff05d5963b5bc81df7e9f79b27e777b0a03a6feca09f3447b99c6fa71","0x3961e4050c27ce0145d375255b3cb829a5b4e795ac475c05a219b3733723d376","0xd7a497f95167d63e6feca70f344d9f6e843d097b62729b8f43bdcd5febf142ab","0x55d80a4ba6ef54f2a8c0b99589d017b810ed13a1fda6a111e1b87725bc8ceb0e","0x9e8b92c17280dd05f2562af6eea3285181c562ebf41fc758527d4c30364bcbc4","0x7353a4b9d6b35c9eafeccaf9722dd293c46ae2ffd4093b2367165c3620a0c7c9","0x026d91bda61c8789c59632c349b38fd7e7557e6b598b94879654a644cfa75f30","0x73e3245d4ddc3bba48fa67633f9993c6e11728a36401fa1206437f8be94ef1d3"]}
|
||||
```
|
||||
|
||||
## Websocket Connection
|
||||
|
||||
### Tendermint Websocket
|
||||
|
||||
To start a connection with the Tendermint websocket you need to define the address with the `--rpc.laddr`
|
||||
flag when starting the node (default `tcp://127.0.0.1:26657`):
|
||||
|
||||
```bash
|
||||
ethermintd start --rpc.laddr="tcp://127.0.0.1:26657"
|
||||
```
|
||||
|
||||
Then, start a websocket subscription with [ws](https://github.com/hashrocket/ws)
|
||||
|
||||
```bash
|
||||
# connect to tendermint websocket at port 8080 as defined above
|
||||
ws ws://localhost:8080/websocket
|
||||
|
||||
# subscribe to new Tendermint block headers
|
||||
> { "jsonrpc": "2.0", "method": "subscribe", "params": ["tm.event='NewBlockHeader'"], "id": 1 }
|
||||
```
|
||||
|
||||
### Ethereum Websocket
|
||||
|
||||
Since Ethermint runs uses Tendermint Core as it's consensus Engine and it's built with the Cosmos
|
||||
SDK framework, it inherits the event format from them. However, in order to support the native Web3
|
||||
compatibility for websockets of the [Ethereum's
|
||||
PubSubAPI](https://geth.ethereum.org/docs/rpc/pubsub), Ethermint needs to cast the Tendermint
|
||||
responses retrieved into the Ethereum types.
|
||||
|
||||
You can start a connection with the Ethereum websocket using the `--json-rpc.ws-address` flag when starting
|
||||
the node (default `"0.0.0.0:8546"`):
|
||||
|
||||
```bash
|
||||
ethermintd start --json-rpc.address"0.0.0.0:8545" --json-rpc.ws-address="0.0.0.0:8546" --evm.rpc.api="eth,web3,net,txpool,debug" --json-rpc.enable
|
||||
```
|
||||
|
||||
Then, start a websocket subscription with [`ws`](https://github.com/hashrocket/ws)
|
||||
|
||||
```bash
|
||||
# connect to tendermint websocet at port 8546 as defined above
|
||||
ws ws://localhost:8546/
|
||||
|
||||
# subscribe to new Ethereum-formatted block Headers
|
||||
> {"id": 1, "method": "eth_subscribe", "params": ["newHeads", {}]}
|
||||
< {"jsonrpc":"2.0","result":"0x44e010cb2c3161e9c02207ff172166ef","id":1}
|
||||
```
|
@ -1,26 +0,0 @@
|
||||
<!--
|
||||
order: 3
|
||||
-->
|
||||
|
||||
# Namespaces
|
||||
|
||||
Check the JSON-RPC namespaces supported on Ethermint. {synopsis}
|
||||
|
||||
## Pre-requisite Readings
|
||||
|
||||
- [Geth JSON-RPC Namespaces](https://geth.ethereum.org/docs/rpc/server) {prereq}
|
||||
|
||||
## Ethereum Namespaces
|
||||
|
||||
| Namespace | Description | Supported | Enabled by Default |
|
||||
|--------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|--------------------|
|
||||
| [`eth`](./endpoints.md#eth-methods) | Ethermint provides several extensions to the standard `eth` JSON-RPC namespace. | ✔ | ✔ |
|
||||
| [`web3`](./endpoints.md#web3-methods) | The `web3` API provides utility functions for the web3 client. | ✔ | ✔ |
|
||||
| [`net`](./endpoints.md#net-methods) | The `net` API provides access to network information of the node | ✔ | ✔ |
|
||||
| `clique` | The `clique` API provides access to the state of the clique consensus engine. You can use this API to manage signer votes and to check the health of a private network. | ❌ | |
|
||||
| `debug` | The `debug` API gives you access to several non-standard RPC methods, which will allow you to inspect, debug and set certain debugging flags during runtime. | ✔ | |
|
||||
| `les` | The `les` API allows you to manage LES server settings, including client parameters and payment settings for prioritized clients. It also provides functions to query checkpoint information in both server and client mode. | ❌ | |
|
||||
| [`miner`](./endpoints.md#miner-methods) | The `miner` API allows you to remote control the node’s mining operation and set various mining specific settings. | ✔ | ❌ |
|
||||
| [`txpool`](./endpoints.md#txpool-methods) | The `txpool` API gives you access to several non-standard RPC methods to inspect the contents of the transaction pool containing all the currently pending transactions as well as the ones queued for future processing. | ✔ | ❌ |
|
||||
| `admin` | The `admin` API gives you access to several non-standard RPC methods, which will allow you to have a fine grained control over your nodeinstance, including but not limited to network peer and RPC endpoint management. | ❌ | |
|
||||
| [`personal`](./endpoints.md#personal-methods) | The `personal` API manages private keys in the key store. | ✔ | ❌ |
|
@ -1,54 +0,0 @@
|
||||
<!--
|
||||
order: 2
|
||||
-->
|
||||
|
||||
# Running the Server
|
||||
|
||||
Learn how to run and setup the JSON-RPC server on Ethermint. {synopsis}
|
||||
|
||||
## Enable Server
|
||||
|
||||
To enable RPC server use the following flag (set to true by default).
|
||||
|
||||
```bash
|
||||
ethermintd start --json-rpc.enable
|
||||
```
|
||||
|
||||
## Defining Namespaces
|
||||
|
||||
`Eth`,`Net` and `Web3` [namespaces](./namespaces) are enabled by default. In order to enable other namespaces use flag `--json-rpc.api`.
|
||||
|
||||
```bash
|
||||
ethermintd start --json-rpc.api eth,txpool,personal,net,debug,web3,miner
|
||||
```
|
||||
|
||||
## Set a Gas Cap
|
||||
|
||||
`eth_call` and `eth_estimateGas` define a global gas cap over rpc for DoS protection. You can override the default gas cap value of 25,000,000 by passing a custom value when starting the node:
|
||||
|
||||
```bash
|
||||
# set gas cap to 85M
|
||||
ethermintd start --json-rpc.gas-cap 85000000000
|
||||
|
||||
# set gas cap to infinite (=0)
|
||||
ethermintd start --json-rpc.gas-cap 0
|
||||
```
|
||||
|
||||
## CORS
|
||||
|
||||
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.
|
||||
|
||||
The CORS setting can be updated from the `app.toml`
|
||||
|
||||
```toml
|
||||
###############################################################################
|
||||
### API Configuration ###
|
||||
###############################################################################
|
||||
|
||||
[api]
|
||||
|
||||
# ...
|
||||
|
||||
# EnableUnsafeCORS defines if CORS should be enabled (unsafe - use it at your own risk).
|
||||
enabled-unsafe-cors = true # default false
|
||||
```
|
@ -1,73 +0,0 @@
|
||||
<!--
|
||||
order: 1
|
||||
-->
|
||||
|
||||
# JSON-RPC Server
|
||||
|
||||
Learn about the JSON-RPC server to interact with the EVM. {synopsis}
|
||||
|
||||
## Pre-requisite Readings
|
||||
|
||||
- [EthWiki JSON-RPC API](https://eth.wiki/json-rpc/API) {prereq}
|
||||
- [Geth JSON-RPC Server](https://geth.ethereum.org/docs/rpc/server) {prereq}
|
||||
|
||||
## JSON-RPC API
|
||||
|
||||
[JSON](https://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](https://www.ietf.org/rfc/rfc4627.txt)) as data format.
|
||||
|
||||
## JSON-RPC Support
|
||||
|
||||
Ethermint supports all standard web3 JSON-RPC APIs. You can find documentation for these APIs on the [`JSON-RPC Methods`](./endpoints.md) page.
|
||||
|
||||
JSON-RPC is provided on multiple transports. Ethermint supports JSON-RPC over HTTP and WebSocket. Transports must be enabled through command-line flags or through the `app.toml` configuration file. For more details see the []
|
||||
|
||||
Ethereum JSON-RPC APIs use a name-space system. RPC methods are grouped into several categories depending on their purpose. All method names are composed of the namespace, an underscore, and the actual method name within the namespace. For example, the eth_call method resides in the eth namespace.
|
||||
|
||||
Access to RPC methods can be enabled on a per-namespace basis. Find documentation for individual namespaces in the [Namespaces](./namespaces.md) page.
|
||||
|
||||
## HEX value encoding
|
||||
|
||||
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`)
|
||||
|
||||
## Default block parameter
|
||||
|
||||
The following methods have an extra default block parameter:
|
||||
|
||||
- [`eth_getBalance`](./endpoints.md#eth-getbalance)
|
||||
- [`eth_getCode`](./endpoints.md#eth-getcode)
|
||||
- [`eth_getTransactionCount`](./endpoints.md#eth-gettransactioncount)
|
||||
- [`eth_getStorageAt`](./endpoints.md#eth-getstorageat)
|
||||
- [`eth_call`](./endpoints.md#eth-call)
|
||||
|
||||
When requests are made that act on the state of Ethermint, 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
|
||||
|
||||
## Curl Examples Explained
|
||||
|
||||
The curl options below might return a response where the node complains about the content type, this is because the `--data` option sets the content type to `application/x-www-form-urlencoded`. If your node does complain, manually set the header by placing `-H "Content-Type: application/json"` at the start of the call.
|
||||
|
||||
The examples also do not include the URL/IP & port combination which must be the last argument given to curl e.x. `127.0.0.1:8545`
|
@ -1,17 +0,0 @@
|
||||
<!--
|
||||
order: false
|
||||
parent:
|
||||
order: 3
|
||||
-->
|
||||
|
||||
# Basics
|
||||
|
||||
This repository contains reference documentation on the basic concepts of Ethermint.
|
||||
|
||||
1. [Chain ID](./chain_id.md)
|
||||
1. [Accounts](./accounts.md)
|
||||
1. [Gas and Fees](./gas.md)
|
||||
1. [Lifecycle of a transaction](./transactions.md)
|
||||
1. [Tokens](./tokens.md)
|
||||
|
||||
After reading the basics, head on to the [Core Reference](../core/README.md) for more advanced material.
|
@ -1,168 +0,0 @@
|
||||
<!--
|
||||
order: 2
|
||||
-->
|
||||
|
||||
# Accounts
|
||||
|
||||
This document describes the in-built accounts system of Ethermint. {synopsis}
|
||||
|
||||
## Pre-requisite Readings
|
||||
|
||||
- [Cosmos SDK Accounts](https://docs.cosmos.network/master/basics/accounts.html) {prereq}
|
||||
- [Ethereum Accounts](https://ethereum.org/en/whitepaper/#ethereum-accounts) {prereq}
|
||||
|
||||
## Ethermint Accounts
|
||||
|
||||
Ethermint defines its own custom `Account` type that uses Ethereum's ECDSA secp256k1 curve for keys. This
|
||||
satisfies the [EIP84](https://github.com/ethereum/EIPs/issues/84) for full [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) paths.
|
||||
The root HD path for Ethermint-based accounts is `m/44'/60'/0'/0`.
|
||||
|
||||
+++ https://github.com/tharsis/ethermint/blob/main/types/account.pb.go#L28-L33
|
||||
|
||||
## Addresses and Public Keys
|
||||
|
||||
[BIP-0173](https://github.com/satoshilabs/slips/blob/master/slip-0173.md) defines a new format for segregated witness output addresses that contains a human-readable part that identifies the Bech32 usage. Ethermint uses the following HRP (human readable prefix) as the base HRP:
|
||||
|
||||
| Network | Mainnet | Testnet | Regtest |
|
||||
|-----------|---------|---------|---------|
|
||||
| Ethermint | `ethm` | `ethm` | |
|
||||
|
||||
There are 3 main types of HRP for the `Addresses`/`PubKeys` available by default on Ethermint:
|
||||
|
||||
- Addresses and Keys for **accounts**, which identify users (e.g. the sender of a `message`). They are derived using the **`eth_secp256k1`** curve.
|
||||
- Addresses and Keys for **validator operators**, which identify the operators of validators. They are derived using the **`eth_secp256k1`** curve.
|
||||
- Addresses and Keys for **consensus nodes**, which identify the validator nodes participating in consensus. They are derived using the **`ed25519`** curve.
|
||||
|
||||
| | Address bech32 Prefix | Pubkey bech32 Prefix | Curve | Address byte length | Pubkey byte length |
|
||||
|--------------------|-----------------------|----------------------|-----------------|---------------------|--------------------|
|
||||
| Accounts | `ethm` | `ethmpub` | `eth_secp256k1` | `20` | `33` (compressed) |
|
||||
| Validator Operator | `ethmvaloper` | `ethmvaloperpub` | `eth_secp256k1` | `20` | `33` (compressed) |
|
||||
| Consensus Nodes | `ethmvalcons` | `ethmvalconspub` | `ed25519` | `20` | `32` |
|
||||
|
||||
## Address formats for clients
|
||||
|
||||
`EthAccount` can be represented in both [Bech32](https://en.bitcoin.it/wiki/Bech32) (`ethm1...`) and hex (`0x...`) formats for Ethereum's Web3 tooling compatibility.
|
||||
|
||||
The Bech32 format is the default format for Cosmos-SDK queries and transactions through CLI and REST
|
||||
clients. The hex format on the other hand, is the Ethereum `common.Address` representation of a
|
||||
Cosmos `sdk.AccAddress`.
|
||||
|
||||
- **Address (Bech32)**: `ethm1j800cll9vq7l4rxfke2u74mjgkdlzrr0r5mu97`
|
||||
- **Address ([EIP55](https://eips.ethereum.org/EIPS/eip-55) Hex)**: `0x91defC7fE5603DFA8CC9B655cF5772459BF10c6f`
|
||||
- **Compressed Public Key**: `{"@type":"/ethermint.crypto.v1.ethsecp256k1.PubKey","key":"Aq9WtHGKtvX523b2ptvimGVfp3hZ1GDxVdINYWBM9+Gy"}`
|
||||
|
||||
### Address conversion
|
||||
|
||||
The `ethermintd debug addr <address>` can be used to convert an address between hex and bech32 formats. For example:
|
||||
|
||||
:::: tabs
|
||||
::: tab Bech32
|
||||
|
||||
```bash
|
||||
ethermintd debug addr ethm10jmp6sgh4cc6zt3e8gw05wavvejgr5pwtu750w
|
||||
Address bytes: [124 182 29 65 23 174 49 161 46 57 58 28 250 59 172 102 100 129 208 46]
|
||||
Address (hex): 7CB61D4117AE31A12E393A1CFA3BAC666481D02E
|
||||
Address (EIP-55): 0x7cB61D4117AE31a12E393a1Cfa3BaC666481D02E
|
||||
Bech32 Acc: ethm10jmp6sgh4cc6zt3e8gw05wavvejgr5pwtu750w
|
||||
Bech32 Val: ethmvaloper10jmp6sgh4cc6zt3e8gw05wavvejgr5pwyv5chn
|
||||
```
|
||||
|
||||
:::
|
||||
::: tab Hex
|
||||
|
||||
```bash
|
||||
ethermintd debug addr 0x7cB61D4117AE31a12E393a1Cfa3BaC666481D02E
|
||||
Address bytes: [124 182 29 65 23 174 49 161 46 57 58 28 250 59 172 102 100 129 208 46]
|
||||
Address (hex): 7CB61D4117AE31A12E393A1CFA3BAC666481D02E
|
||||
Address (EIP-55): 0x7cB61D4117AE31a12E393a1Cfa3BaC666481D02E
|
||||
Bech32 Acc: ethm10jmp6sgh4cc6zt3e8gw05wavvejgr5pwtu750w
|
||||
Bech32 Val: ethmvaloper10jmp6sgh4cc6zt3e8gw05wavvejgr5pwyv5chn
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
### Key output
|
||||
|
||||
::: tip
|
||||
The Cosmos SDK Keyring output (i.e `ethermintd keys`) only supports addresses and public keys in Bech32 format.
|
||||
:::
|
||||
|
||||
We can use the `keys show` command of `ethermintd` with the flag `--bech <type> (acc|val|cons)` to
|
||||
obtain the addresses and keys as mentioned above,
|
||||
|
||||
:::: tabs
|
||||
::: tab Account
|
||||
|
||||
```bash
|
||||
ethermintd keys show mykey --bech acc
|
||||
- name: mykey
|
||||
type: local
|
||||
address: ethm1qsklxwt77qrxur494uvw07zjynu03dq9alwh37
|
||||
pubkey: '{"@type":"/ethermint.crypto.v1.ethsecp256k1.PubKey","key":"A8nbJ3eW9oAb2RNZoS8L71jFMfjk6zVa1UISYgKK9HPm"}'
|
||||
mnemonic: ""
|
||||
```
|
||||
|
||||
:::
|
||||
::: tab Validator
|
||||
|
||||
```bash
|
||||
ethermintd keys show test --bech val
|
||||
- name: mykey
|
||||
type: local
|
||||
address: ethmvaloper1qsklxwt77qrxur494uvw07zjynu03dq9rdsrlq
|
||||
pubkey: '{"@type":"/ethermint.crypto.v1.ethsecp256k1.PubKey","key":"A8nbJ3eW9oAb2RNZoS8L71jFMfjk6zVa1UISYgKK9HPm"}'
|
||||
mnemonic: ""
|
||||
```
|
||||
|
||||
:::
|
||||
::: tab Consensus
|
||||
|
||||
```bash
|
||||
ethermintd keys show test --bech cons
|
||||
- name: mykey
|
||||
type: local
|
||||
address: ethmvalcons1qsklxwt77qrxur494uvw07zjynu03dq9h7rlnp
|
||||
pubkey: '{"@type":"/ethermint.crypto.v1.ethsecp256k1.PubKey","key":"A8nbJ3eW9oAb2RNZoS8L71jFMfjk6zVa1UISYgKK9HPm"}'
|
||||
mnemonic: ""
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
## Querying an Account
|
||||
|
||||
You can query an account address using the CLI, gRPC or
|
||||
|
||||
### Command Line Interface
|
||||
|
||||
```bash
|
||||
# NOTE: the --output (-o) flag will define the output format in JSON or YAML (text)
|
||||
ethermintd q auth account $(ethermintd keys show <MYKEY> -a) -o text
|
||||
|
|
||||
'@type': /ethermint.types.v1beta1.EthAccount
|
||||
base_account:
|
||||
account_number: "3"
|
||||
address: inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku
|
||||
pub_key: null
|
||||
sequence: "0"
|
||||
code_hash: xdJGAYb3IzySfn2y3McDwOUAtlPKgic7e/rYBF2FpHA=
|
||||
```
|
||||
|
||||
### Cosmos gRPC and REST
|
||||
|
||||
``` bash
|
||||
# GET /cosmos/auth/v1beta1/accounts/{address}
|
||||
curl -X GET "http://localhost:10337/cosmos/auth/v1beta1/accounts/ethm14au322k9munkmx5wrchz9q30juf5wjgz2cfqku" -H "accept: application/json"
|
||||
```
|
||||
|
||||
### JSON-RPC
|
||||
|
||||
To retrieve the Ethereum hex address using Web3, use the JSON-RPC [`eth_accounts`](./../api/json-rpc/endpoints.md#eth-accounts) or [`personal_listAccounts`](./../api/json-rpc/endpoints#personal-listAccounts.md) endpoints:
|
||||
|
||||
```bash
|
||||
# query against a local node
|
||||
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_accounts","params":[],"id":1}' -H "Content-Type: application/json" http://localhost:8545
|
||||
|
||||
curl -X POST --data '{"jsonrpc":"2.0","method":"personal_listAccounts","params":[],"id":1}' -H "Content-Type: application/json" http://localhost:8545
|
||||
```
|
@ -1,38 +0,0 @@
|
||||
<!--
|
||||
order: 1
|
||||
-->
|
||||
|
||||
# Chain ID
|
||||
|
||||
Learn about the Ethermint chain-id format {synopsis}
|
||||
|
||||
## The Chain Identifier
|
||||
|
||||
Every chain must have a unique identifier or `chain-id`. Tendermint requires each application to
|
||||
define its own `chain-id` in the [genesis.json fields](https://docs.tendermint.com/master/spec/core/genesis.html#genesis-fields). However, in order to comply with both EIP155 and Cosmos standard for chain upgrades, Ethermint-compatible chains must implement a special structure for their chain identifiers.
|
||||
|
||||
## Structure
|
||||
|
||||
The Ethermint Chain ID contains 3 main components
|
||||
|
||||
- **Identifier**: Unstructured string that defines the name of the application.
|
||||
- **EIP155 Number**: Immutable [EIP155](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md) `CHAIN_ID` that defines the replay attack protection number.
|
||||
- **Version Number**: Is the version number (always positive) that the chain is currently running.
|
||||
This number **MUST** be incremented every time the chain is upgraded or forked in order to avoid network or consensus errors.
|
||||
|
||||
### Format
|
||||
|
||||
The format for specifying and Ethermint compatible chain-id in genesis is the following:
|
||||
|
||||
```bash
|
||||
{identifier}_{EIP155}-{version}
|
||||
```
|
||||
|
||||
The following table provides an example where the second row corresponds to an upgrade from the first one:
|
||||
|
||||
| ChainID | Identifier | EIP155 Number | Version Number |
|
||||
|--------------------|------------|---------------|----------------|
|
||||
| `ethermint_9000-1` | ethermint | 9000 | 1 |
|
||||
| `ethermint_9000-2` | ethermint | 9000 | 2 |
|
||||
| `...` | ... | ... | ... |
|
||||
| `ethermint_9000-N` | ethermint | 9000 | N |
|
@ -1,96 +0,0 @@
|
||||
<!--
|
||||
order: 4
|
||||
-->
|
||||
|
||||
# Gas and Fees
|
||||
|
||||
Learn about the differences between `Gas` and `Fees` in Ethereum and Cosmos. {synopsis}
|
||||
|
||||
## Pre-requisite Readings
|
||||
|
||||
- [Cosmos SDK Gas](https://docs.cosmos.network/master/basics/gas-fees.html) {prereq}
|
||||
- [Ethereum Gas](https://ethereum.org/en/developers/docs/gas/) {prereq}
|
||||
|
||||
The concept of Gas represents the amount of computational effort required to execute specific operations on the state machine.
|
||||
|
||||
Gas was created on Ethereum to disallow the EVM (Ethereum Virtual Machine) from running infinite
|
||||
loops by allocating a small amount of monetary value into the system. A unit of gas, usually in a
|
||||
form as a fraction of the native coin, is consumed for every operation on the EVM and requires a
|
||||
user to pay for these operations. These operations consist in state transitions such as sending a
|
||||
transaction or calling a contract.
|
||||
|
||||
Exactly like Ethereum, Cosmos utilizes the concept of gas and this is how Cosmos tracks the resource
|
||||
usage of operations during execution. Operations on Cosmos are represented as read or writes done to the chain's store.
|
||||
|
||||
In Cosmos, a fee is calculated and charged to the user during a message execution. This fee is
|
||||
calculated from the sum of all gas consumed in an message execution:
|
||||
|
||||
$$fee = gas ~ * ~ gasPrice$$
|
||||
|
||||
In both networks, gas is used to make sure that operations do not require an excess amount of
|
||||
computational power to complete and as a way to deter bad-acting users from spamming the network.
|
||||
|
||||
## Cosmos SDK `Gas`
|
||||
|
||||
In the Cosmos SDK, gas is tracked in the main `GasMeter` and the `BlockGasMeter`:
|
||||
|
||||
- `GasMeter`: keeps track of the gas consumed during executions that lead to state transitions. It is reset on every transaction execution.
|
||||
- `BlockGasMeter`: keeps track of the gas consumed in a block and enforces that the gas does not go over a predefined limit. This limit is defined in the Tendermint consensus parameters and can be changed via governance parameter change proposals.
|
||||
|
||||
More information regarding gas in Cosmos SDK can be found [here](https://docs.cosmos.network/master/basics/gas-fees.html).
|
||||
|
||||
## Matching EVM Gas consumption
|
||||
|
||||
Ethermint is an EVM-compatible chain that supports Ethereum Web3 tooling. For this reason, gas
|
||||
consumption must be equitable with other EVMs, most importantly Ethereum.
|
||||
|
||||
The main difference between EVM and Cosmos state transitions, is that the EVM uses a [gas table](https://github.com/ethereum/go-ethereum/blob/master/params/protocol_params.go) for each OPCODE, whereas Cosmos uses a `GasConfig` that charges gas for each CRUD operation by setting a flat and per-byte cost for accessing the database.
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/3fd376bd5659f076a4dc79b644573299fd1ec1bf/store/types/gas.go#L187-L196
|
||||
|
||||
In order to match the the gas consumed by the EVM, the gas consumption logic from the SDK is ignored, and instead the gas consumed is calculated by subtracting the state transition leftover gas plus refund from the gas limit defined on the message.
|
||||
|
||||
To ignore the SDK gas consumption, we reset the transaction `GasMeter` count to 0 and manually set it to the `gasUsed` value computed by the EVM module at the end of the execution.
|
||||
|
||||
+++ https://github.com/tharsis/ethermint/blob/098da6d0cc0e0c4cefbddf632df1057383973e4a/x/evm/keeper/state_transition.go#L188
|
||||
|
||||
### `AnteHandler`
|
||||
|
||||
The Cosmos SDK [`AnteHandler`](https://docs.cosmos.network/master/basics/gas-fees.html#antehandler)
|
||||
performs basic checks prior to transaction execution. These checks are usually signature
|
||||
verification, transaction field validation, transaction fees, etc.
|
||||
|
||||
Regarding gas consumption and fees, the `AnteHandler` checks that the user has enough balance to
|
||||
cover for the tx cost (amount plus fees) as well as checking that the gas limit defined in the
|
||||
message is greater or equal than the computed intrinsic gas for the message.
|
||||
|
||||
## Gas Refunds
|
||||
|
||||
In the EVM, gas can be specified prior to execution. The totality of the gas specified is consumed at the beginning of the execution (during the `AnteHandler` step) and the remaining gas is refunded back to
|
||||
the user if any gas is left over after the execution. Additionally the EVM can also define gas to be refunded back to the user but those will be capped to a fraction of the used gas depending on the fork/version being used.
|
||||
|
||||
## 0 Fee Transactions
|
||||
|
||||
In Cosmos, a minimum gas price is not enforced by the `AnteHandler` as the `min-gas-prices` is
|
||||
checked against the local node/validator. In other words, the minimum fees accepted are determined
|
||||
by the validators of the network, and each validator can specify a different minimum value for their fees.
|
||||
This potentially allows end users to submit 0 fee transactions if there is at least one single
|
||||
validator that is willing to include transactions with `0` gas price in their blocks proposed.
|
||||
|
||||
For this same reason, in Ethermint it is possible to send transactions with `0` fees for transaction
|
||||
types other than the ones defined by the `evm` module. EVM module transactions cannot have `0` fees
|
||||
as gas is required inherently by the EVM. This check is done by the EVM transactions stateless validation
|
||||
(i.e `ValidateBasic`) function as well as on the custom `AnteHandler` defined by Ethermint.
|
||||
|
||||
## Gas estimation
|
||||
|
||||
Ethereum provides a JSON-RPC endpoint `eth_estimateGas` to help users set up a correct gas limit in their transactions.
|
||||
|
||||
Unfortunately, we cannot make use of the SDK `tx simulation` for gas estimation because the pre-check in the Ante Handlers would require a valid signature, and the sender balance to be enough to pay for the gas. But in Ethereum, this endpoint can be called without specifying any sender address.
|
||||
|
||||
For that reason, a specific query API `EstimateGas` is implemented in Ethermint. It will apply the transaction against the current block/state and perform a binary search in order to find the optimal gas value to return to the user (the same transaction will be applied over and over until we find the minimum gas needed before it fails). The reason we need to use a binary search is that the gas required for the
|
||||
transaction might be higher than the value returned by the EVM after applying the transaction, so we need to try until we find the optimal value.
|
||||
|
||||
A cache context will be used during the whole execution to avoid changes be persisted in the state.
|
||||
|
||||
+++ https://github.com/tharsis/ethermint/blob/098da6d0cc0e0c4cefbddf632df1057383973e4a/x/evm/keeper/grpc_query.go#L100
|
Before Width: | Height: | Size: 19 KiB |
@ -1,32 +0,0 @@
|
||||
<!--
|
||||
order: 5
|
||||
-->
|
||||
|
||||
# Tokens
|
||||
|
||||
Learn about the the different types of tokens available in Ethermint. {synopsis}
|
||||
|
||||
## Introduction
|
||||
|
||||
Ethermint is a Cosmos SDK-based chain with full EVM support. Because of this architecture, tokens and assets in the network may come from different independent sources: the `bank` module and the `evm` module.
|
||||
|
||||
## Cosmos Coins
|
||||
|
||||
Accounts can own SDK coins in their balance, which are used for operations with other Cosmos modules and transactions. Examples of these are using the coins for staking, IBC transfers, governance deposits and EVM
|
||||
|
||||
### Photon
|
||||
|
||||
The denomination used for staking, governance and gas consumption on the EVM is the Photon. The Photon provides the utility of: securing the Proof-of-Stake chain, token used for governance proposals, fee distribution and as a mean of gas for running smart contracts on the EVM.
|
||||
|
||||
Ethermint uses [Atto](https://en.wikipedia.org/wiki/Atto-) Photon as the base denomination to maintain parity with Ethereum.
|
||||
|
||||
$$1 photon = 1 ~ * ~ 10^{18} aphoton$$
|
||||
|
||||
This matches Ethereum denomination of:
|
||||
|
||||
$$1 ETH = 1 ~ * ~ 10^{18} wei$$
|
||||
|
||||
### EVM Tokens
|
||||
|
||||
Ethermint is compatible with ERC20 tokens and other non-fungible token standards (EIP721, EIP1155)
|
||||
that are natively supported by the EVM.
|
@ -1,40 +0,0 @@
|
||||
<!--
|
||||
order: 3
|
||||
-->
|
||||
|
||||
# Transaction Lifecycle
|
||||
|
||||
This document describes the lifecycle of a transaction from creation to committed state changes on the EVM. {synopsis}
|
||||
|
||||
## Pre-requisite Readings
|
||||
|
||||
- [SDK transaction lifecycle](https://docs.cosmos.network/master/basics/tx-lifecycle.html) {prereq}
|
||||
|
||||
<!-- TODO: rewrite. This is not a lifecycle doc -->
|
||||
## Routing
|
||||
|
||||
Ethermint needs to parse and handle transactions routed for both the EVM and for Cosmos SDK modules. We
|
||||
attempt to achieve this by mimicking [geth's](https://github.com/ethereum/go-ethereum) `Transaction`
|
||||
structure and treat it as a unique Cosmos SDK message type. An Ethereum transaction is a single
|
||||
[`sdk.Msg`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#Msg). All relevant Ethereum
|
||||
transaction information is contained in this message. This includes the signature, gas, payload,
|
||||
amount, etc.
|
||||
|
||||
Being that Ethermint implements the Tendermint ABCI application interface, as transactions are
|
||||
consumed, they are passed through a series of handlers. Once such handler, the `AnteHandler`, is
|
||||
responsible for performing preliminary message execution business logic such as fee payment,
|
||||
signature verification, etc. This is particular to Cosmos SDK routed transactions. Ethereum routed
|
||||
transactions will bypass this as the EVM handles the same business logic.
|
||||
|
||||
All EVM transactions are [RLP](./../core/encoding.md#rlp) encoded using a custom tx encoder.
|
||||
|
||||
## Signers
|
||||
|
||||
The signature processing and verification in Ethereum is performed by the `Signer` interface. The
|
||||
protocol supports different signer types based on the chain configuration params and the block number.
|
||||
|
||||
+++ https://github.com/ethereum/go-ethereum/blob/v1.10.3/core/types/transaction_signing.go#L145-L166
|
||||
|
||||
Ethermint supports all Ethereum `Signer`s up to the latest go-ethereum version (London, Berlin,
|
||||
EIP155, Homestead and Frontier). The chain will generate the latest `Signer` type depending on the
|
||||
`ChainConfig`.
|
@ -1,14 +0,0 @@
|
||||
<!--
|
||||
order: false
|
||||
parent:
|
||||
order: 4
|
||||
-->
|
||||
|
||||
# Core Concepts
|
||||
|
||||
This repository contains reference documentation on the core concepts of Ethermint.
|
||||
|
||||
1. [Encoding](./encoding.md)
|
||||
2. [Pending State](./pending_state.md)
|
||||
|
||||
After reading the core concepts, head on to the [guides](../guides/README.md) to learn how to use Ethereum tooling with Ethermint.
|
@ -1,69 +0,0 @@
|
||||
<!--
|
||||
order: 1
|
||||
-->
|
||||
|
||||
# Encoding
|
||||
|
||||
Learn about the encoding formats used on Ethermint. {synopsis}
|
||||
|
||||
## Pre-requisite Readings
|
||||
|
||||
- [Cosmos SDK Encoding](https://docs.cosmos.network/master/core/encoding.html) {prereq}
|
||||
- [Ethereum RLP](https://eth.wiki/en/fundamentals/rlp) {prereq}
|
||||
|
||||
## Encoding Formats
|
||||
|
||||
### Protocol Buffers
|
||||
|
||||
The Cosmos [Stargate](https://stargate.cosmos.network/) release introduces
|
||||
[protobuf](https://developers.google.com/protocol-buffers) as the main encoding format for both
|
||||
client and state serialization. All the EVM module types that are used for state and clients
|
||||
(transaction messages, genesis, query services, etc) will be implemented as protocol buffer messages.
|
||||
|
||||
### Amino
|
||||
|
||||
The Cosmos SDK also supports the legacy Amino encoding format for backwards compatibility with
|
||||
previous versions, specially for client encoding and signing with Ledger devices. Ethermint does not
|
||||
support Amino in the EVM module, but it is supported for all other Cosmos SDK modules that enable it.
|
||||
|
||||
### RLP
|
||||
|
||||
Recursive Length Prefix ([RLP](https://eth.wiki/en/fundamentals/rlp)), is an encoding/decoding algorithm that serializes a message and
|
||||
allows for quick reconstruction of encoded data. Ethermint uses RLP to encode/decode Ethereum
|
||||
messages for JSON-RPC handling to conform messages to the proper Ethereum format. This allows
|
||||
messages to be encoded and decoded in the exact format as Ethereum's.
|
||||
|
||||
The `x/evm` transactions (`MsgEthereumTx`) encoding is performed by casting the message to a go-ethereum's `Transaction` and then marshaling the transaction data using RLP:
|
||||
|
||||
```go
|
||||
// TxEncoder overwrites sdk.TxEncoder to support MsgEthereumTx
|
||||
func (g txConfig) TxEncoder() sdk.TxEncoder {
|
||||
return func(tx sdk.Tx) ([]byte, error) {
|
||||
msg, ok := tx.(*evmtypes.MsgEthereumTx)
|
||||
if ok {
|
||||
return msg.AsTransaction().MarshalBinary()
|
||||
}
|
||||
return g.TxConfig.TxEncoder()(tx)
|
||||
}
|
||||
}
|
||||
|
||||
// TxDecoder overwrites sdk.TxDecoder to support MsgEthereumTx
|
||||
func (g txConfig) TxDecoder() sdk.TxDecoder {
|
||||
return func(txBytes []byte) (sdk.Tx, error) {
|
||||
tx := ðtypes.Transaction{}
|
||||
|
||||
err := tx.UnmarshalBinary(txBytes)
|
||||
if err == nil {
|
||||
msg := &evmtypes.MsgEthereumTx{}
|
||||
msg.FromEthereumTx(tx)
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
return g.TxConfig.TxDecoder()(txBytes)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Next {hide}
|
||||
|
||||
Learn how [pending state](./pending_state.md) is handled on Ethermint. {hide}
|
@ -1,49 +0,0 @@
|
||||
<!--
|
||||
order: 2
|
||||
-->
|
||||
|
||||
# Pending State
|
||||
|
||||
Learn how Ethermint handles pending state queries. {synopsis}
|
||||
|
||||
## Pre-requisite Readings
|
||||
|
||||
- [Tendermint Mempool](https://docs.tendermint.com/master/tendermint-core/mempool.htm) {prereq}
|
||||
|
||||
## Ethermint vs Ethereum
|
||||
|
||||
In Ethereum, pending blocks are generated as they are queued for production by miners. These pending
|
||||
blocks include pending transactions that are picked out by miners, based on the highest reward paid
|
||||
in gas. This mechanism exists as block finality is not possible on the Ethereum network. Blocks are
|
||||
committed with probabilistic finality, which means that transactions and blocks become less likely
|
||||
to become reverted as more time (and blocks) passes.
|
||||
|
||||
Ethermint is designed quite differently on this front as there is no concept of a "pending state".
|
||||
Ethermint uses [Tendermint Core](https://docs.tendermint.com/) BFT consensus which provides instant
|
||||
finality for transaction. For this reason, Etheremint does not require a pending state mechanism, as
|
||||
all (if not most) of the transactions will be committed to the next block (avg. block time on Cosmos chains is ~8s). However, this causes a
|
||||
few hiccups in terms of the Ethereum Web3-compatible queries that can be made to pending state.
|
||||
|
||||
Another significant difference with Ethereum, is that blocks are produced by validators or block producers, who include transactions from their local mempool into blocks in a
|
||||
first-in-first-out (FIFO) fashion. Transactions on Ethermint cannot be ordered or cherry picked out from the Tendermint node [mempool](https://docs.tendermint.com/master/tendermint-core/mempool.html#transaction-ordering).
|
||||
|
||||
## Pending State Queries
|
||||
|
||||
Ethermint will make queries which will account for any unconfirmed transactions present in a node's
|
||||
transaction mempool. A pending state query made will be subjective and the query will be made on the
|
||||
target node's mempool. Thus, the pending state will not be the same for the same query to two
|
||||
different nodes.
|
||||
|
||||
### JSON-RPC Calls on Pending Transactions
|
||||
|
||||
- [`eth_getBalance`](./../api/json-rpc/endpoints.md#eth_getbalance)
|
||||
- [`eth_getTransactionCount`](./../api/json-rpc/endpoints.md#eth-gettransactioncount)
|
||||
- [`eth_getBlockTransactionCountByNumber`](./../api/json-rpc/endpoints.md#eth-getblocktransactioncountbynumber)
|
||||
- [`eth_getBlockByNumber`](./../api/json-rpc/endpoints.md#eth-getblockbynumber)
|
||||
- [`eth_getTransactionByHash`](./../api/json-rpc/endpoints.md#eth-gettransactionbyhash)
|
||||
- [`eth_getTransactionByBlockNumberAndIndex`](./../api/json-rpc/endpoints.html#eth-gettransactionbyblockhashandindex)
|
||||
- [`eth_sendTransaction`](./../api/json-rpc/endpoints.md#eth-sendtransaction)
|
||||
|
||||
## Next {hide}
|
||||
|
||||
Learn how to deploy a Solidity smart contract on Ethermint using [Truffle](./../guides/truffle.md) {hide}
|
@ -1,59 +0,0 @@
|
||||
# Snapshot and Revert in Ethermint
|
||||
|
||||
EVM uses state-reverting exceptions to handle errors. Such an exception will undo all changes made to the state in the current call (and all its sub-calls), and the caller could handle the error and don't propagate. We need to implement the `Snapshot` and `RevertToSnapshot` apis in `StateDB` interfaces to support this feature.
|
||||
|
||||
[go-ethereum implementation](https://github.com/ethereum/go-ethereum/blob/master/core/state/journal.go#L39) manages transient states in memory, and uses a list of journal logs to record all the state modification operations done so far, snapshot is an index in the log list, and to revert to a snapshot it just undo the journal logs after the snapshot index in reversed order.
|
||||
|
||||
Ethermint uses cosmos-sdk's storage api to manage states, fortunately the storage api supports creating cached overlays, it works like this:
|
||||
|
||||
```golang
|
||||
// create a cached overlay storage on top of ctx storage.
|
||||
overlayCtx, commit := ctx.CacheContext()
|
||||
// Modify states using the overlayed storage
|
||||
err := doCall(overlayCtx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// commit will write the dirty states into the underlying storage
|
||||
commit()
|
||||
|
||||
// Now, just drop the overlayCtx and keep using ctx
|
||||
```
|
||||
|
||||
And it can be used in a nested way, like this:
|
||||
|
||||
```golang
|
||||
overlayCtx1, commit1 := ctx.CacheContext()
|
||||
doCall1(overlayCtx1)
|
||||
{
|
||||
overlayCtx2, commit2 := overlayCtx1.CacheContext()
|
||||
doCall2(overlayCtx2)
|
||||
commit2()
|
||||
}
|
||||
commit1()
|
||||
```
|
||||
|
||||
With this feature, we can use a stake of overlayed contexts to implement nested `Snapshot` and `RevertToSnapshot` calls.
|
||||
|
||||
```golang
|
||||
type cachedContext struct {
|
||||
ctx sdk.Context
|
||||
commit func()
|
||||
}
|
||||
var contextStack []cachedContext
|
||||
func Snapshot() int {
|
||||
ctx, commit := contextStack.Top().CacheContext()
|
||||
contextStack.Push(cachedContext{ctx, commit})
|
||||
return len(contextStack) - 1
|
||||
}
|
||||
func RevertToSnapshot(int snapshot) {
|
||||
contextStack = contextStack[:snapshot]
|
||||
}
|
||||
func Commit() {
|
||||
for i := len(contextStack) - 1; i >= 0; i-- {
|
||||
contextStack[i].commit()
|
||||
}
|
||||
contextStack = {}
|
||||
}
|
||||
```
|
||||
|
Before Width: | Height: | Size: 64 KiB |
@ -1,20 +0,0 @@
|
||||
<!--
|
||||
order: false
|
||||
parent:
|
||||
order: 5
|
||||
-->
|
||||
|
||||
# Guides
|
||||
|
||||
1. Localnet
|
||||
* [Single Node Localnet](./localnet/single_node)
|
||||
* [Multi Node Localnet](./localnet/multi_node)
|
||||
2. Keys and Wallets
|
||||
* [Keyring](./keys-wallets/keyring)
|
||||
* [MetaMask](./keys-wallets/metamask)
|
||||
3. Ethereum Tooling
|
||||
* [Remix](./tools/remix)
|
||||
* [Hardhat](./tools/hardhat)
|
||||
* [Truffle](./tools/truffle)
|
||||
4. [Validators](./validators/overview)
|
||||
5. [Key Management System](./kms/kms)
|
Before Width: | Height: | Size: 159 KiB |
Before Width: | Height: | Size: 252 KiB |
Before Width: | Height: | Size: 127 KiB |
Before Width: | Height: | Size: 131 KiB |
Before Width: | Height: | Size: 153 KiB |
@ -1,121 +0,0 @@
|
||||
<!--
|
||||
order: 1
|
||||
-->
|
||||
|
||||
# Keyring
|
||||
|
||||
Create, import, export and delete keys using the CLI keyring {synopsis}
|
||||
|
||||
The keyring holds the private/public keypairs used to interact with the node. For instance, a validator key needs to be set up before running the node, so that blocks can be correctly signed. The private key can be stored in different locations, called ["backends"](#keyring-backends), such as a file or the operating system's own key storage.
|
||||
|
||||
## Add keys
|
||||
|
||||
You can use `ethermintd keys` for help about the keys command and `ethermintd keys [command] --help` for more information about a particular subcommand.
|
||||
|
||||
To create a new key in the keyring, run the `add` subcommand with a `<key_name>` argument. For the purpose of this tutorial, we will solely use the `test` backend, and call our new key `mykey`. This key will be used in the next section.
|
||||
|
||||
```bash
|
||||
ethermintd keys add mykey --keyring-backend test
|
||||
|
||||
# Put the generated address in a variable for later use.
|
||||
MY_VALIDATOR_ADDRESS=$(ethermintd keys show mykey -a --keyring-backend test)
|
||||
```
|
||||
|
||||
This command generates a new 24-word mnemonic phrase, persists it to the relevant backend, and outputs information about the keypair. If this keypair will be used to hold value-bearing tokens, be sure to write down the mnemonic phrase somewhere safe!
|
||||
|
||||
By default, the keyring generates a `eth_secp256k1` keypair. The keyring also supports `ed25519` and `secp256k1` keys, which may be created by passing the `--algo` flag. A keyring can of course hold both types of keys simultaneously.
|
||||
|
||||
## Keyring Backends
|
||||
|
||||
### OS
|
||||
|
||||
The `os` backend relies on operating system-specific defaults to handle key storage
|
||||
securely. Typically, an operating system's credential sub-system handles password prompts,
|
||||
private keys storage, and user sessions according to the user's password policies. Here
|
||||
is a list of the most popular operating systems and their respective passwords manager:
|
||||
|
||||
- macOS (since Mac OS 8.6): [Keychain](https://support.apple.com/en-gb/guide/keychain-access/welcome/mac)
|
||||
- Windows: [Credentials Management API](https://docs.microsoft.com/en-us/windows/win32/secauthn/credentials-management)
|
||||
- GNU/Linux:
|
||||
- [libsecret](https://gitlab.gnome.org/GNOME/libsecret)
|
||||
- [kwallet](https://api.kde.org/frameworks/kwallet/html/index.html)
|
||||
|
||||
GNU/Linux distributions that use GNOME as default desktop environment typically come with
|
||||
[Seahorse](https://wiki.gnome.org/Apps/Seahorse). Users of KDE based distributions are
|
||||
commonly provided with [KDE Wallet Manager](https://userbase.kde.org/KDE_Wallet_Manager).
|
||||
Whilst the former is in fact a `libsecret` convenient frontend, the latter is a `kwallet`
|
||||
client.
|
||||
|
||||
`os` is the default option since operating system's default credentials managers are
|
||||
designed to meet users' most common needs and provide them with a comfortable
|
||||
experience without compromising on security.
|
||||
|
||||
The recommended backends for headless environments are `file` and `pass`.
|
||||
|
||||
### File
|
||||
|
||||
The `file` stores the keyring encrypted within the app's configuration directory. This
|
||||
keyring will request a password each time it is accessed, which may occur multiple
|
||||
times in a single command resulting in repeated password prompts. If using bash scripts
|
||||
to execute commands using the `file` option you may want to utilize the following format
|
||||
for multiple prompts:
|
||||
|
||||
```bash
|
||||
# assuming that KEYPASSWD is set in the environment
|
||||
yes $KEYPASSWD | ethermintd keys add me
|
||||
yes $KEYPASSWD | ethermintd keys show me
|
||||
# start ethermintd with keyring-backend flag
|
||||
ethermintd --keyring-backend=file start
|
||||
```
|
||||
|
||||
::: tip
|
||||
The first time you add a key to an empty keyring, you will be prompted to type the password twice.
|
||||
:::
|
||||
|
||||
### Password Store
|
||||
|
||||
The `pass` backend uses the [pass](https://www.passwordstore.org/) utility to manage on-disk
|
||||
encryption of keys' sensitive data and metadata. Keys are stored inside `gpg` encrypted files
|
||||
within app-specific directories. `pass` is available for the most popular UNIX
|
||||
operating systems as well as GNU/Linux distributions. Please refer to its manual page for
|
||||
information on how to download and install it.
|
||||
|
||||
::: tip
|
||||
**pass** uses [GnuPG](https://gnupg.org/) for encryption. `gpg` automatically invokes the `gpg-agent`
|
||||
daemon upon execution, which handles the caching of GnuPG credentials. Please refer to `gpg-agent`
|
||||
man page for more information on how to configure cache parameters such as credentials TTL and
|
||||
passphrase expiration.
|
||||
:::
|
||||
|
||||
The password store must be set up prior to first use:
|
||||
|
||||
```sh
|
||||
pass init <GPG_KEY_ID>
|
||||
```
|
||||
|
||||
Replace `<GPG_KEY_ID>` with your GPG key ID. You can use your personal GPG key or an alternative
|
||||
one you may want to use specifically to encrypt the password store.
|
||||
|
||||
### KDE Wallet Manager
|
||||
|
||||
The `kwallet` backend uses `KDE Wallet Manager`, which comes installed by default on the
|
||||
GNU/Linux distributions that ships KDE as default desktop environment. Please refer to
|
||||
[KWallet Handbook](https://docs.kde.org/stable5/en/kdeutils/kwallet5/index.html) for more
|
||||
information.
|
||||
|
||||
### Testing
|
||||
|
||||
The `test` backend is a password-less variation of the `file` backend. Keys are stored
|
||||
**unencrypted** on disk.
|
||||
|
||||
:::danger
|
||||
Provided for testing purposes only. The `test` backend is **NOT** recommended for use in production environments.
|
||||
:::
|
||||
|
||||
### In Memory
|
||||
|
||||
The `memory` backend stores keys in memory. The keys are immediately deleted after the program has exited.
|
||||
|
||||
:::danger
|
||||
Provided for testing purposes only. The `memory` backend is **NOT** recommended for use in production environments.
|
||||
:::
|
@ -1,68 +0,0 @@
|
||||
<!--
|
||||
order: 2
|
||||
-->
|
||||
|
||||
# MetaMask
|
||||
|
||||
Connect your MetaMask wallet with Ethermint {synopsis}
|
||||
|
||||
The MetaMask browser extension is a wallet for accessing Ethereum-enabled applications and managing user identities. It can be used to connect to Ethermint through the official testnet or via a locally-running Ethermint node.
|
||||
|
||||
::: tip
|
||||
If you are planning on developing on Ethermint locally and you haven’t already set up your own local node, refer to [the quickstart tutorial](../../quickstart/run_node/), or follow the instructions in the [GitHub repository](https://github.com/tharsis/ethermint/).
|
||||
:::
|
||||
|
||||
## Adding a New Network
|
||||
|
||||
Open the MetaMask extension on your browser, you may have to log in to your MetaMask account if you are not already. Then click the top right circle and go to `Settings` > `Networks` > `Add Network` and fill the form as shown below.
|
||||
|
||||
::: tip
|
||||
You can also find the full `ChainID` form the `genesis.json` file. To get the [EIP155](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md) chain ID from the Cosmos chain ID, check the [Chain ID](./../../basics/chain_id) documentation page.
|
||||
:::
|
||||
|
||||
![metamask networks settings](./../img/metamask_network_settings.png)
|
||||
|
||||
Here is the list of fields that you can use to paste on Metamask:
|
||||
|
||||
:::: tabs
|
||||
::: tab Local Node
|
||||
|
||||
- **Network Name:** `{{ $themeConfig.project.name }} Local`
|
||||
- **New RPC URL:** `{{ $themeConfig.project.rpc_url_local }}`
|
||||
- **Chain ID:** `{{ $themeConfig.project.chain_id }}`
|
||||
- **Currency Symbol (optional):** `{{ $themeConfig.project.ticker }}-LOCAL`
|
||||
- **Block Explorer URL (optional):** `n/a`
|
||||
:::
|
||||
::: tab Testnet
|
||||
- **Network Name:** `{{ $themeConfig.project.name }}`
|
||||
- **New RPC URL:** `{{ $themeConfig.project.rpc_url }}`
|
||||
- **Chain ID:** `{{ $themeConfig.project.chain_id }}`
|
||||
- **Currency Symbol (optional):** `{{ $themeConfig.project.ticker }}`
|
||||
- **Block Explorer URL (optional):** `{{ $themeConfig.project.block_explorer_url }}`
|
||||
:::
|
||||
::::
|
||||
|
||||
## Import Account to Metamask
|
||||
|
||||
Then close the settings, and go to `My Accounts` (top right circle) and select `Import Account`. You should see and image like the following one:
|
||||
|
||||
![metamask import account page](./../img/metamask_import.png)
|
||||
|
||||
Now you can export your private key from the terminal using the following command. Again, make sure to replace `mykey` with the name of the key that you want to export and use the correct `keyring-backend`:
|
||||
|
||||
```bash
|
||||
ethermintd keys unsafe-export-eth-key mykey --keyring-backend test
|
||||
```
|
||||
|
||||
Go back to the browser and select the `Private Key` option. Then paste the private key exported from the `unsafe-export-eth-key` command.
|
||||
|
||||
Your account balance should show up as `1 APHOTON` and do transfers as usual.
|
||||
|
||||
::: tip
|
||||
If it takes some time to load the balance of the account, change the network to `Main Ethereum
|
||||
Network` (or any other than `Localhost 8545` or `Ethermint`) and then switch back to `Ethermint`.
|
||||
:::
|
||||
|
||||
## Downloading State
|
||||
|
||||
To see your Metamask logs, click the top right circle and go to `Settings` > `Advanced` > `Download State Logs`. If you search through the JSON file for the account address you'll find the transaction history.
|
@ -1,271 +0,0 @@
|
||||
<!--
|
||||
order: 3
|
||||
-->
|
||||
|
||||
# Multisig
|
||||
|
||||
Learn how to generate, sign and broadcast a transaction using the keyring multisig {synopsis}
|
||||
|
||||
A **multisig account** is a Ethermint account with a special key that can require more than one signatures to sign transactions. This can be useful for increasing the security of the account or for requiring the consent of multiple parties to make transactions. Multisig accounts can be created by specifying:
|
||||
|
||||
- threshold number of signatures required
|
||||
- the public keys involved in signing
|
||||
|
||||
To sign with a multisig account, the transaction must be signed individually by the different keys specified for the account. Then, the signatures will be combined into a multisignature which can be used to sign the transaction. If fewer than the threshold number of signatures needed are present, the resultant multisignature is considered invalid.
|
||||
|
||||
## Generate a Multisig key
|
||||
|
||||
```bash
|
||||
ethermintd keys add --multisig=name1,name2,name3[...] --multisig-threshold=K new_key_name
|
||||
```
|
||||
|
||||
`K` is the minimum number of private keys that must have signed the transactions that carry the public key's address as signer.
|
||||
|
||||
The `--multisig` flag must contain the name of public keys that will be combined into a public key that will be generated and stored as `new_key_name` in the local database. All names supplied through `--multisig` must already exist in the local database.
|
||||
|
||||
Unless the flag `--nosort` is set, the order in which the keys are supplied on the command line does not matter, i.e. the following commands generate two identical keys:
|
||||
|
||||
```bash
|
||||
ethermintd keys add --multisig=p1,p2,p3 --multisig-threshold=2 multisig_address
|
||||
ethermintd keys add --multisig=p2,p3,p1 --multisig-threshold=2 multisig_address
|
||||
```
|
||||
|
||||
Multisig addresses can also be generated on-the-fly and printed through the which command:
|
||||
|
||||
```bash
|
||||
ethermintd keys show --multisig-threshold=K name1 name2 name3 [...]
|
||||
```
|
||||
|
||||
## Signing a transaction
|
||||
|
||||
### Step 1: Create the multisig key
|
||||
|
||||
Let's assume that you have `test1` and `test2` want to make a multisig account with `test3`.
|
||||
|
||||
First import the public keys of `test3` into your keyring.
|
||||
|
||||
```sh
|
||||
ethermintd keys add \
|
||||
test3 \
|
||||
--pubkey=ethmpub1addwnpepqgcxazmq6wgt2j4rdfumsfwla0zfk8e5sws3p3zg5dkm9007hmfysxas0u2
|
||||
```
|
||||
|
||||
Generate the multisig key with 2/3 threshold.
|
||||
|
||||
```sh
|
||||
ethermintd keys add \
|
||||
multi \
|
||||
--multisig=test1,test2,test3 \
|
||||
--multisig-threshold=2
|
||||
```
|
||||
|
||||
You can see its address and details:
|
||||
|
||||
```sh
|
||||
ethermintd keys show multi
|
||||
|
||||
- name: multi
|
||||
type: multi
|
||||
address: ethm1e0fx0q9meawrcq7fmma9x60gk35lpr4xk3884m
|
||||
pubkey: ethmpub1ytql0csgqgfzd666axrjzq3mxw59ys6yqcd3ydjvhgs0uzs6kdk5fp4t73gmkl8t6y02yfq7tvfzd666axrjzq3sd69kp5usk492x6nehqjal67ynv0nfqapzrzy3gmdk27la0kjfqfzd666axrjzq6utqt639ka2j3xkncgk65dup06t297ccljmxhvhu3rmk92u3afjuyz9dg9
|
||||
mnemonic: ""
|
||||
threshold: 0
|
||||
pubkeys: []
|
||||
```
|
||||
|
||||
Let's add 10 PHOTON to the multisig wallet:
|
||||
|
||||
```bash
|
||||
ethermintd tx send \
|
||||
test1 \
|
||||
ethm1e0fx0q9meawrcq7fmma9x60gk35lpr4xk3884m \
|
||||
10000000000000000000aphoton \
|
||||
--chain-id=ethermint_9000-1 \
|
||||
--gas=auto \
|
||||
--fees=1000000aphoton \
|
||||
--broadcast-mode=block
|
||||
```
|
||||
|
||||
### Step 2: Create the multisig transaction
|
||||
|
||||
We want to send 5 PHOTON from our multisig account to `ethm1rgjxswhuxhcrhmyxlval0qa70vxwvqn2e0srft`.
|
||||
|
||||
```bash
|
||||
ethermintd tx send \
|
||||
ethm1rgjxswhuxhcrhmyxlval0qa70vxwvqn2e0srft \
|
||||
ethm157g6rn6t6k5rl0dl57zha2wx72t633axqyvvwq \
|
||||
5000000000000000000aphoton \
|
||||
--gas=200000 \
|
||||
--fees=1000000aphoton \
|
||||
--chain-id=ethermint_9000-1 \
|
||||
--generate-only > unsignedTx.json
|
||||
```
|
||||
|
||||
The file `unsignedTx.json` contains the unsigned transaction encoded in JSON.
|
||||
|
||||
```json
|
||||
{
|
||||
"body": {
|
||||
"messages": [
|
||||
{
|
||||
"@type": "/cosmos.bank.v1beta1.MsgSend",
|
||||
"from_address": "ethm1rgjxswhuxhcrhmyxlval0qa70vxwvqn2e0srft",
|
||||
"to_address": "ethm157g6rn6t6k5rl0dl57zha2wx72t633axqyvvwq",
|
||||
"amount": [
|
||||
{
|
||||
"denom": "aphoton",
|
||||
"amount": "5000000000000000000"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"memo": "",
|
||||
"timeout_height": "0",
|
||||
"extension_options": [],
|
||||
"non_critical_extension_options": []
|
||||
},
|
||||
"auth_info": {
|
||||
"signer_infos": [],
|
||||
"fee": {
|
||||
"amount": [
|
||||
{
|
||||
"denom": "aphoton",
|
||||
"amount": "1000000"
|
||||
}
|
||||
],
|
||||
"gas_limit": "200000",
|
||||
"payer": "",
|
||||
"granter": ""
|
||||
}
|
||||
},
|
||||
"signatures": []
|
||||
}
|
||||
```
|
||||
|
||||
### Step 3: Sign individually
|
||||
|
||||
Sign with `test1` and `test2` and create individual signatures.
|
||||
|
||||
```sh
|
||||
ethermintd tx sign \
|
||||
unsignedTx.json \
|
||||
--multisig=ethm1e0fx0q9meawrcq7fmma9x60gk35lpr4xk3884m \
|
||||
--from=test1 \
|
||||
--output-document=test1sig.json \
|
||||
--chain-id=ethermint_9000-1
|
||||
```
|
||||
|
||||
```sh
|
||||
ethermintd tx sign \
|
||||
unsignedTx.json \
|
||||
--multisig=ethm1e0fx0q9meawrcq7fmma9x60gk35lpr4xk3884m \
|
||||
--from=test2 \
|
||||
--output-document=test2sig.json \
|
||||
--chain-id=ethermint_9000-1
|
||||
```
|
||||
|
||||
### Step 4: Create multisignature
|
||||
|
||||
Combine signatures to sign transaction.
|
||||
|
||||
```sh
|
||||
ethermintd tx multisign \
|
||||
unsignedTx.json \
|
||||
multi \
|
||||
test1sig.json test2sig.json \
|
||||
--output-document=signedTx.json \
|
||||
--chain-id=ethermint_9000-1
|
||||
```
|
||||
|
||||
The TX is now signed:
|
||||
|
||||
```json
|
||||
{
|
||||
"body": {
|
||||
"messages": [
|
||||
{
|
||||
"@type": "/cosmos.bank.v1beta1.MsgSend",
|
||||
"from_address": "ethm1rgjxswhuxhcrhmyxlval0qa70vxwvqn2e0srft",
|
||||
"to_address": "ethm157g6rn6t6k5rl0dl57zha2wx72t633axqyvvwq",
|
||||
"amount": [
|
||||
{
|
||||
"denom": "aphoton",
|
||||
"amount": "5000000000000000000"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"memo": "",
|
||||
"timeout_height": "0",
|
||||
"extension_options": [],
|
||||
"non_critical_extension_options": []
|
||||
},
|
||||
"auth_info": {
|
||||
"signer_infos": [
|
||||
{
|
||||
"public_key": {
|
||||
"@type": "/cosmos.crypto.multisig.LegacyAminoPubKey",
|
||||
"threshold": 2,
|
||||
"public_keys": [
|
||||
{
|
||||
"@type": "/cosmos.crypto.secp256k1.PubKey",
|
||||
"key": "ApCzSG8k7Tr4aM6e4OJRExN7cNtvH21L9azbh+uRrvt4"
|
||||
},
|
||||
{
|
||||
"@type": "/cosmos.crypto.secp256k1.PubKey",
|
||||
"key": "Ah91erz8ChNanqLe9ea948rvAiXMCRlR5Ka7EE/c0xUK"
|
||||
},
|
||||
{
|
||||
"@type": "/cosmos.crypto.secp256k1.PubKey",
|
||||
"key": "A0OjtIUCFJM3AobJ9HJTWKP9RZV2+WPcwVjLgsAidrZ/"
|
||||
}
|
||||
]
|
||||
},
|
||||
"mode_info": {
|
||||
"multi": {
|
||||
"bitarray": {
|
||||
"extra_bits_stored": 3,
|
||||
"elems": "wA=="
|
||||
},
|
||||
"mode_infos": [
|
||||
{
|
||||
"single": {
|
||||
"mode": "SIGN_MODE_LEGACY_AMINO_JSON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"single": {
|
||||
"mode": "SIGN_MODE_LEGACY_AMINO_JSON"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"sequence": "1"
|
||||
}
|
||||
],
|
||||
"fee": {
|
||||
"amount": [
|
||||
{
|
||||
"denom": "aphoton",
|
||||
"amount": "1000000"
|
||||
}
|
||||
],
|
||||
"gas_limit": "200000",
|
||||
"payer": "",
|
||||
"granter": ""
|
||||
}
|
||||
},
|
||||
"signatures": [
|
||||
"CkCEeIbeGc+I1ipZuhp/0KhVNnWAv2tTlvgo5x61lzk1KHmLPV38m/YFurrFt5cm5+fqIXrn+FlOjrJuzBhw8ogYCkCawm9mpXsBHk0CFsE5618fVnvScEkfrzW0c2jCcjqV8EPuj3ut74UWzZyQkwtJGxUWtro9EgnGsB7Di1Gzizst"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Step 5: Broadcast transaction
|
||||
|
||||
```sh
|
||||
ethermintd tx broadcast signedTx.json \
|
||||
--chain-id=ethermint_9000-1 \
|
||||
--broadcast-mode=block
|
||||
```
|
@ -1,34 +0,0 @@
|
||||
<!--
|
||||
order: 1
|
||||
-->
|
||||
|
||||
# Tendermint KMS
|
||||
|
||||
[Tendermint KMS](https://github.com/iqlusioninc/tmkms) is a key management service that allows separating key management from Tendermint nodes. In addition it provides other advantages such as:
|
||||
|
||||
- Improved security and risk management policies
|
||||
- Unified API and support for various HSM (hardware security modules)
|
||||
- Double signing protection (software or hardware based)
|
||||
|
||||
It is recommended that the KMS service runs in a separate physical hosts.
|
||||
|
||||
## Building
|
||||
|
||||
Detailed build instructions can be found [here](https://github.com/iqlusioninc/tmkms#installation).
|
||||
|
||||
::: tip
|
||||
When compiling the KMS, ensure you have enabled the applicable features:
|
||||
:::
|
||||
|
||||
| Backend | Recommended Command line |
|
||||
|-------------------------|-----------------------------------|
|
||||
| YubiHSM | `cargo build --features yubihsm` |
|
||||
| Ledger + Tendermint App | `cargo build --features ledgertm` |
|
||||
|
||||
## Configuration
|
||||
|
||||
A KMS can be configured using the following HSMs:
|
||||
|
||||
### Using a YubiHSM
|
||||
|
||||
Detailed information on how to setup a KMS with YubiHSM2 can be found [here](https://github.com/iqlusioninc/tmkms/blob/master/README.yubihsm.md)
|
@ -1,214 +0,0 @@
|
||||
<!--
|
||||
order: 2
|
||||
-->
|
||||
|
||||
# Multi Node
|
||||
|
||||
## Pre-requisite Readings
|
||||
|
||||
- [Install Starport](https://docs.starport.network/#install-starport) {prereq}
|
||||
- [Install Docker](https://docs.docker.com/engine/installation/) {prereq}
|
||||
- [Install docker-compose](https://docs.docker.com/compose/install/) {prereq}
|
||||
|
||||
## Automated Localnet with Starport
|
||||
|
||||
Once you have installed `starport`, just run the localnet by using
|
||||
|
||||
```bash
|
||||
starport chain serve --reset-once -v -c ./starport.yml
|
||||
```
|
||||
|
||||
## Automated Localnet with Docker
|
||||
|
||||
### Build & Start
|
||||
|
||||
To build start a 4 node testnet run:
|
||||
|
||||
```bash
|
||||
make localnet-start
|
||||
```
|
||||
|
||||
This command creates a 4-node network using the `ethermintdnode` Docker image.
|
||||
The ports for each node are found in this table:
|
||||
|
||||
| Node ID | P2P Port | Tendermint RPC Port | REST/ Ethereum JSON-RPC Port | WebSocket Port |
|
||||
|------------------|----------|---------------------|------------------------------|----------------|
|
||||
| `ethermintnode0` | `26656` | `26657` | `8545` | `8546` |
|
||||
| `ethermintnode1` | `26659` | `26660` | `8547` | `8548` |
|
||||
| `ethermintnode2` | `26661` | `26662` | `8549` | `8550` |
|
||||
| `ethermintnode3` | `26663` | `26664` | `8551` | `8552` |
|
||||
|
||||
To update the binary, just rebuild it and restart the nodes
|
||||
|
||||
```bash
|
||||
make localnet-start
|
||||
```
|
||||
|
||||
The command above command will run containers in the background using Docker compose. You will see the network being created:
|
||||
|
||||
```bash
|
||||
...
|
||||
Creating network "ethermint_localnet" with driver "bridge"
|
||||
Creating ethermintdnode0 ... done
|
||||
Creating ethermintdnode2 ... done
|
||||
Creating ethermintdnode1 ... done
|
||||
Creating ethermintdnode3 ... done
|
||||
```
|
||||
|
||||
### Stop Localnet
|
||||
|
||||
Once you are done, execute:
|
||||
|
||||
```bash
|
||||
make localnet-stop
|
||||
```
|
||||
|
||||
### Configuration
|
||||
|
||||
The `make localnet-start` creates files for a 4-node testnet in `./build` by
|
||||
calling the `ethermintd testnet` command. This outputs a handful of files in the
|
||||
`./build` directory:
|
||||
|
||||
```bash
|
||||
tree -L 3 build/
|
||||
|
||||
build/
|
||||
├── ethermintd
|
||||
├── ethermintd
|
||||
├── gentxs
|
||||
│ ├── node0.json
|
||||
│ ├── node1.json
|
||||
│ ├── node2.json
|
||||
│ └── node3.json
|
||||
├── node0
|
||||
│ ├── ethermintd
|
||||
│ │ ├── key_seed.json
|
||||
│ │ └── keyring-test-cosmos
|
||||
│ └── ethermintd
|
||||
│ ├── config
|
||||
│ ├── data
|
||||
│ └── ethermintd.log
|
||||
├── node1
|
||||
│ ├── ethermintd
|
||||
│ │ ├── key_seed.json
|
||||
│ │ └── keyring-test-cosmos
|
||||
│ └── ethermintd
|
||||
│ ├── config
|
||||
│ ├── data
|
||||
│ └── ethermintd.log
|
||||
├── node2
|
||||
│ ├── ethermintd
|
||||
│ │ ├── key_seed.json
|
||||
│ │ └── keyring-test-cosmos
|
||||
│ └── ethermintd
|
||||
│ ├── config
|
||||
│ ├── data
|
||||
│ └── ethermintd.log
|
||||
└── node3
|
||||
├── ethermintd
|
||||
│ ├── key_seed.json
|
||||
│ └── keyring-test-cosmos
|
||||
└── ethermintd
|
||||
├── config
|
||||
├── data
|
||||
└── ethermintd.log
|
||||
```
|
||||
|
||||
Each `./build/nodeN` directory is mounted to the `/ethermintd` directory in each container.
|
||||
|
||||
### Logging
|
||||
|
||||
In order to see the logs of a particular node you can use the following command:
|
||||
|
||||
```bash
|
||||
# node 0: daemon logs
|
||||
docker exec ethermintdnode0 tail ethermintd.log
|
||||
|
||||
# node 0: REST & RPC logs
|
||||
docker exec ethermintdnode0 tail ethermintd.log
|
||||
```
|
||||
|
||||
The logs for the daemon will look like:
|
||||
|
||||
```bash
|
||||
I[2020-07-29|17:33:52.452] starting ABCI with Tendermint module=main
|
||||
E[2020-07-29|17:33:53.394] Can't add peer's address to addrbook module=p2p err="Cannot add non-routable address 272a247b837653cf068d39efd4c407ffbd9a0e6f@192.168.10.5:26656"
|
||||
E[2020-07-29|17:33:53.394] Can't add peer's address to addrbook module=p2p err="Cannot add non-routable address 3e05d3637b7ebf4fc0948bbef01b54d670aa810a@192.168.10.4:26656"
|
||||
E[2020-07-29|17:33:53.394] Can't add peer's address to addrbook module=p2p err="Cannot add non-routable address 689f8606ede0b26ad5b79ae244c14cc67ab4efe7@192.168.10.3:26656"
|
||||
I[2020-07-29|17:33:58.828] Executed block module=state height=88 validTxs=0 invalidTxs=0
|
||||
I[2020-07-29|17:33:58.830] Committed state module=state height=88 txs=0 appHash=90CC5FA53CF8B5EC49653A14DA20888AD81C92FCF646F04D501453FD89FCC791
|
||||
I[2020-07-29|17:34:04.032] Executed block module=state height=89 validTxs=0 invalidTxs=0
|
||||
I[2020-07-29|17:34:04.034] Committed state module=state height=89 txs=0 appHash=0B54C4DB1A0DACB1EEDCD662B221C048C826D309FD2A2F31FF26BAE8D2D7D8D7
|
||||
I[2020-07-29|17:34:09.381] Executed block module=state height=90 validTxs=0 invalidTxs=0
|
||||
I[2020-07-29|17:34:09.383] Committed state module=state height=90 txs=0 appHash=75FD1EE834F0669D5E717C812F36B21D5F20B3CCBB45E8B8D415CB9C4513DE51
|
||||
I[2020-07-29|17:34:14.700] Executed block module=state height=91 validTxs=0 invalidTxs=0
|
||||
```
|
||||
|
||||
::: tip
|
||||
You can disregard the `Can't add peer's address to addrbook` warning. As long as the blocks are
|
||||
being produced and the app hashes are the same for each node, there should not be any issues.
|
||||
:::
|
||||
|
||||
Whereas the logs for the REST & RPC server would look like:
|
||||
|
||||
```bash
|
||||
I[2020-07-30|09:39:17.488] Starting application REST service (chain-id: "7305661614933169792")... module=rest-server
|
||||
I[2020-07-30|09:39:17.488] Starting RPC HTTP server on 127.0.0.1:8545 module=rest-server
|
||||
...
|
||||
```
|
||||
|
||||
#### Follow Logs
|
||||
|
||||
You can also watch logs as they are produced via Docker with the `--follow` (`-f`) flag, for
|
||||
example:
|
||||
|
||||
```bash
|
||||
docker logs -f ethermintdnode0
|
||||
```
|
||||
|
||||
### Interact with the Localnet
|
||||
|
||||
#### Ethereum JSON-RPC & Websocket Ports
|
||||
|
||||
To interact with the testnet via WebSockets or RPC/API, you will send your request to the corresponding ports:
|
||||
|
||||
| EVM JSON-RPC | Eth Websocket |
|
||||
|--------------|---------------|
|
||||
| `8545` | `8546` |
|
||||
|
||||
You can send a curl command such as:
|
||||
|
||||
```bash
|
||||
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_accounts","params":[],"id":1}' -H "Content-Type: application/json" 192.162.10.1:8545
|
||||
```
|
||||
|
||||
::: tip
|
||||
The IP address will be the public IP of the docker container.
|
||||
:::
|
||||
|
||||
Additional instructions on how to interact with the WebSocket can be found on the [events documentation](./events.md#ethereum-websocket).
|
||||
|
||||
### Keys & Accounts
|
||||
|
||||
To interact with `ethermintd` and start querying state or creating txs, you use the
|
||||
`ethermintd` directory of any given node as your `home`, for example:
|
||||
|
||||
```bash
|
||||
ethermintd keys list --home ./build/node0/ethermintd
|
||||
```
|
||||
|
||||
Now that accounts exists, you may create new accounts and send those accounts
|
||||
funds!
|
||||
|
||||
::: tip
|
||||
**Note**: Each node's seed is located at `./build/nodeN/ethermintd/key_seed.json` and can be restored to the CLI using the `ethermintd keys add --restore` command
|
||||
:::
|
||||
|
||||
### Special Binaries
|
||||
|
||||
If you have multiple binaries with different names, you can specify which one to run with the BINARY environment variable. The path of the binary is relative to the attached volume. For example:
|
||||
|
||||
```bash
|
||||
# Run with custom binary
|
||||
BINARY=ethermint make localnet-start
|
||||
```
|
@ -1,140 +0,0 @@
|
||||
<!--
|
||||
order: 1
|
||||
-->
|
||||
|
||||
# Single Node
|
||||
|
||||
## Pre-requisite Readings
|
||||
|
||||
- [Install Binary](./../../quickstart/installation) {prereq}
|
||||
|
||||
## Automated Localnet (script)
|
||||
|
||||
You can customize the local testnet script by changing values for convenience for example:
|
||||
|
||||
```bash
|
||||
# customize the name of your key, the chain-id, moniker of the node, keyring backend, and log level
|
||||
KEY="mykey"
|
||||
CHAINID="ethermint_9000-1"
|
||||
MONIKER="localtestnet"
|
||||
KEYRING="test"
|
||||
LOGLEVEL="info"
|
||||
|
||||
|
||||
# Allocate genesis accounts (cosmos formatted addresses)
|
||||
ethermintd add-genesis-account $KEY 100000000000000000000000000aphoton --keyring-backend $KEYRING
|
||||
|
||||
# Sign genesis transaction
|
||||
ethermintd gentx $KEY 1000000000000000000000aphoton --keyring-backend $KEYRING --chain-id $CHAINID
|
||||
```
|
||||
|
||||
The default configuration will generate a single validator localnet with the chain-id
|
||||
`ethermint_9000-1` and one predefined account (`mykey`) with some allocated funds at the genesis.
|
||||
|
||||
You can start the local chain using:
|
||||
|
||||
```bash
|
||||
init.sh
|
||||
```
|
||||
|
||||
## Manual Localnet
|
||||
|
||||
This guide helps you create a single validator node that runs a network locally for testing and other development related uses.
|
||||
|
||||
### Initialize the chain
|
||||
|
||||
Before actually running the node, we need to initialize the chain, and most importantly its genesis file. This is done with the `init` subcommand:
|
||||
|
||||
```bash
|
||||
$MONIKER=testing
|
||||
$KEY=mykey
|
||||
$CHAINID="ethermint_9000-1"
|
||||
|
||||
# The argument $MONIKER is the custom username of your node, it should be human-readable.
|
||||
ethermintd init $MONIKER --chain-id=$CHAINID
|
||||
```
|
||||
|
||||
::: tip
|
||||
You can [edit](./../../quickstart/binary.md#configuring-the-node) this `moniker` later by updating the `config.toml` file.
|
||||
:::
|
||||
|
||||
The command above creates all the configuration files needed for your node and validator to run, as well as a default genesis file, which defines the initial state of the network. All these [configuration files](./../../quickstart/binary.md#configuring-the-node) are in `~/.ethermintd` by default, but you can overwrite the location of this folder by passing the `--home` flag.
|
||||
|
||||
### Genesis Procedure
|
||||
|
||||
### Adding Genesis Accounts
|
||||
|
||||
Before starting the chain, you need to populate the state with at least one account using the [keyring](./../keys-wallets/keyring.md#add-keys):
|
||||
|
||||
```bash
|
||||
ethermintd keys add my_validator --keyring-backend=test
|
||||
```
|
||||
|
||||
Once you have created a local account, go ahead and grant it some `aphoton` tokens in your chain's genesis file. Doing so will also make sure your chain is aware of this account's existence:
|
||||
|
||||
```bash
|
||||
ethermintd add-genesis-account my_validator 10000000000aphoton --keyring-backend test
|
||||
```
|
||||
|
||||
Now that your account has some tokens, you need to add a validator to your chain.
|
||||
|
||||
For this guide, you will add your local node (created via the `init` command above) as a validator of your chain. Validators can be declared before a chain is first started via a special transaction included in the genesis file called a `gentx`:
|
||||
|
||||
```bash
|
||||
# Create a gentx
|
||||
# NOTE: this command lets you set the number of coins.
|
||||
# Make sure this account has some coins with the genesis.app_state.staking.params.bond_denom denom
|
||||
ethermintd add-genesis-account my_validator 1000000000stake,10000000000aphoton
|
||||
```
|
||||
|
||||
A `gentx` does three things:
|
||||
|
||||
1. Registers the `validator` account you created as a validator operator account (i.e. the account that controls the validator).
|
||||
2. Self-delegates the provided `amount` of staking tokens.
|
||||
3. Link the operator account with a Tendermint node pubkey that will be used for signing blocks. If no `--pubkey` flag is provided, it defaults to the local node pubkey created via the `ethermintd init` command above.
|
||||
|
||||
For more information on `gentx`, use the following command:
|
||||
|
||||
```bash
|
||||
ethermintd gentx --help
|
||||
```
|
||||
|
||||
### Collecting `gentx`
|
||||
|
||||
By default, the genesis file do not contain any `gentxs`. A `gentx` is a transaction that bonds
|
||||
staking token present in the genesis file under `accounts` to a validator, essentially creating a
|
||||
validator at genesis. The chain will start as soon as more than 2/3rds of the validators (weighted
|
||||
by voting power) that are the recipient of a valid `gentx` come online after `genesis_time`.
|
||||
|
||||
A `gentx` can be added manually to the genesis file, or via the following command:
|
||||
|
||||
```bash
|
||||
# Add the gentx to the genesis file
|
||||
ethermintd collect-gentxs
|
||||
```
|
||||
|
||||
This command will add all the `gentxs` stored in `~/.ethermintd/config/gentx` to the genesis file.
|
||||
|
||||
### Run Testnet
|
||||
|
||||
Finally, check the correctness of the `genesis.json` file:
|
||||
|
||||
```bash
|
||||
ethermintd validate-genesis
|
||||
```
|
||||
|
||||
Now that everything is set up, you can finally start your node:
|
||||
|
||||
```bash
|
||||
ethermintd start
|
||||
```
|
||||
|
||||
:::tip
|
||||
To check all the available customizable options when running the node, use the `--help` flag.
|
||||
:::
|
||||
|
||||
You should see blocks come in.
|
||||
|
||||
The previous command allow you to run a single node. This is enough for the next section on interacting with this node, but you may wish to run multiple nodes at the same time, and see how consensus happens between them.
|
||||
|
||||
You can then stop the node using `Ctrl+C`.
|
@ -1,200 +0,0 @@
|
||||
<!--
|
||||
order: 2
|
||||
-->
|
||||
|
||||
# Hardhat: Deploying a Smart Contract
|
||||
|
||||
Learn how to deploy a simple Solidity-based smart contract to Ethermint using the Hardhat environment {synopsis}
|
||||
|
||||
[Hardhat](https://hardhat.org/) is a flexible development environment for building Ethereum-based smart contracts. It is designed with integrations and extensibility in mind
|
||||
|
||||
## Pre-requisite Readings
|
||||
|
||||
- [Installation](./../../quickstart/installation.md) {prereq}
|
||||
- [Run a node](./../../quickstart/run_node.md) {prereq}
|
||||
|
||||
## Install Dependencies
|
||||
|
||||
Before proceeding, you need to install Node.js (we'll use v16.x) and the npm package manager. You can download directly from [Node.js](https://nodejs.org/en/download/) or in your terminal:
|
||||
|
||||
:::: tabs
|
||||
::: tab Ubuntu
|
||||
|
||||
```bash
|
||||
curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -
|
||||
|
||||
sudo apt install -y nodejs
|
||||
```
|
||||
|
||||
:::
|
||||
::: tab MacOS
|
||||
|
||||
```bash
|
||||
# You can use homebrew (https://docs.brew.sh/Installation)
|
||||
$ brew install node
|
||||
|
||||
# Or you can use nvm (https://github.com/nvm-sh/nvm)
|
||||
$ nvm install node
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
You can verify that everything is installed correctly by querying the version for each package:
|
||||
|
||||
```bash
|
||||
$ node -v
|
||||
...
|
||||
|
||||
$ npm -v
|
||||
...
|
||||
```
|
||||
|
||||
::: tip
|
||||
If you haven't already, you will also need to install Ethermint if you plan on deploying your smart contracts locally. Check this [document](./../../quickstart/installation.md) for the full instructions.
|
||||
:::
|
||||
|
||||
## Create Hardhat Project
|
||||
|
||||
To create a new project, navigate to your project directory and run:
|
||||
|
||||
```bash
|
||||
$ npx hardhat
|
||||
|
||||
888 888 888 888 888
|
||||
888 888 888 888 888
|
||||
888 888 888 888 888
|
||||
8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888
|
||||
888 888 "88b 888P" d88" 888 888 "88b "88b 888
|
||||
888 888 .d888888 888 888 888 888 888 .d888888 888
|
||||
888 888 888 888 888 Y88b 888 888 888 888 888 Y88b.
|
||||
888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888
|
||||
|
||||
Welcome to Hardhat v2.0.8
|
||||
|
||||
? What do you want to do? …
|
||||
❯ Create a sample project
|
||||
Create an empty hardhat.config.js
|
||||
```
|
||||
|
||||
Following the prompts should create a new project structure in your directory. Consult the [Hardhat config page](https://hardhat.org/config/) for a list of configuration options to specify in `hardhat.config.js`. Most importantly, you should set the `defaultNetwork` entry to point to your desired JSON-RPC network:
|
||||
|
||||
:::: tabs
|
||||
::: tab Local Node
|
||||
|
||||
```javascript
|
||||
module.exports = {
|
||||
defaultNetwork: "local",
|
||||
networks: {
|
||||
hardhat: {
|
||||
},
|
||||
local: {
|
||||
url: "http://localhost:8545/",
|
||||
accounts: [privateKey1, privateKey2, ...]
|
||||
}
|
||||
},
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
::: tab Testnet
|
||||
|
||||
```javascript
|
||||
module.exports = {
|
||||
defaultNetwork: "testnet",
|
||||
networks: {
|
||||
hardhat: {
|
||||
},
|
||||
testnet: {
|
||||
url: "",
|
||||
accounts: [privateKey1, privateKey2, ...]
|
||||
}
|
||||
},
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
To ensure you are targeting the correct network, you can query for a list of accounts available to you from your default network provider:
|
||||
|
||||
```bash
|
||||
$ npx hardhat accounts
|
||||
0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
|
||||
0x70997970C51812dc3A010C7d01b50e0d17dc79C8
|
||||
0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC
|
||||
0x90F79bf6EB2c4f870365E785982E1f101E93b906
|
||||
...
|
||||
```
|
||||
|
||||
## Deploying a Smart Contract
|
||||
|
||||
You will see that a default smart contract, written in Solidity, has already been provided under `contracts/Greeter.sol`:
|
||||
|
||||
```javascript
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "hardhat/console.sol";
|
||||
|
||||
contract Greeter {
|
||||
string private greeting;
|
||||
|
||||
constructor(string memory _greeting) {
|
||||
console.log("Deploying a Greeter with greeting:", _greeting);
|
||||
greeting = _greeting;
|
||||
}
|
||||
|
||||
function greet() public view returns (string memory) {
|
||||
return greeting;
|
||||
}
|
||||
|
||||
function setGreeting(string memory _greeting) public {
|
||||
console.log("Changing greeting from '%s' to '%s'", greeting, _greeting);
|
||||
greeting = _greeting;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This contract allows you to set and query a string `greeting`. Hardhat also provides a script to deploy smart contracts to a target network; this can be invoked via the following command, targeting your default network:
|
||||
|
||||
```bash
|
||||
npx hardhat run scripts/sample-script.js
|
||||
```
|
||||
|
||||
Hardhat also lets you manually specify a target network via the `--network <your-network>` flag:
|
||||
|
||||
:::: tabs
|
||||
::: tab Local Node
|
||||
|
||||
```bash
|
||||
npx hardhat run --network {{ $themeConfig.project.rpc_url_local }} scripts/sample-script.js
|
||||
```
|
||||
|
||||
:::
|
||||
::: tab Testnet
|
||||
|
||||
```bash
|
||||
npx hardhat run --network {{ $themeConfig.project.rpc_url }} scripts/sample-script.js
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
Finally, try running a Hardhat test:
|
||||
|
||||
```bash
|
||||
$ npx hardhat test
|
||||
Compiling 1 file with 0.8.4
|
||||
Compilation finished successfully
|
||||
|
||||
|
||||
Greeter
|
||||
Deploying a Greeter with greeting: Hello, world!
|
||||
Changing greeting from 'Hello, world!' to 'Hola, mundo!'
|
||||
✓ Should return the new greeting once it's changed (803ms)
|
||||
|
||||
|
||||
1 passing (805ms)
|
||||
```
|
@ -1,65 +0,0 @@
|
||||
<!--
|
||||
order: 1
|
||||
-->
|
||||
|
||||
# Remix: Deploying a Smart Contract
|
||||
|
||||
Learn how to deploy a simple Solidity-based smart contract to Ethermint using the Remix in-browser IDE {synopsis}
|
||||
|
||||
## Pre-requisite Readings
|
||||
|
||||
- [Installation](./../../quickstart/installation.md) {prereq}
|
||||
- [Run a node](./../../quickstart/run_node.md) {prereq}
|
||||
- [MetaMask](../keys-wallets/metamask.md) {prereq}
|
||||
|
||||
[Remix](http://remix.ethereum.org/) is an in-browser IDE for [Solidity](https://github.com/ethereum/solidity) smart contracts. In this guide, we will learn how to deploy a contract to a running Ethermint network through Remix and interact with it.
|
||||
|
||||
## Connect Ethermint account to Remix
|
||||
|
||||
::: tip
|
||||
If you haven’t already, follow the steps in the [Metamask guide](.//metamask.md) to import your Ethermint private key into Metamask. Start the Ethermint daemon and REST server.
|
||||
:::
|
||||
|
||||
Go to [Remix](http://remix.ethereum.org/). There are some contracts in the File Explorer. Replace these with the source code to `Counter.sol` below. On the left-most bar, select the Solidity Compiler and compile the contract.
|
||||
|
||||
```javascript
|
||||
pragma solidity >=0.7.0 <0.9.0;
|
||||
|
||||
contract Counter {
|
||||
uint256 counter = 0;
|
||||
|
||||
function add() public {
|
||||
counter++;
|
||||
}
|
||||
|
||||
function subtract() public {
|
||||
counter--;
|
||||
}
|
||||
|
||||
function getCounter() public view returns (uint256) {
|
||||
return counter;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Next, select the `Deploy and Run` option. Select `Injected Web3` as the `Environment`. This will open a metamask popup for you to connect your Metamask to Remix. Select `Connect` to confirm.
|
||||
|
||||
You should see your account show up in the left-hand panel.
|
||||
|
||||
![remix connected to ethermint](./../img/remix_deploy.png)
|
||||
|
||||
## Deploy and Interact
|
||||
|
||||
Now that your account is connected, you are able to deploy the contract. Press the `Deploy` button. A metamask pop-up will appear asking you to confirm. Confirm the transaction. You should see a log for the deployment transaction in the Ethermint daemon logs:
|
||||
|
||||
```bash
|
||||
I[2020-07-15|17:26:43.155] Added good transaction module=mempool tx=877A8E6600FA27EC2B2362719274314977B243671DC4E5F8796ED97FFC0CBE42 res="&{CheckTx:log:\"[]\" gas_wanted:121193 }" height=31 total=1
|
||||
```
|
||||
|
||||
Once the contract has been successfully deployed, you will see it show up in the `Deployed Contracts` section in the left-hand side, as well as a green check in the Remix console showing the transaction details.
|
||||
|
||||
![deployed contract through remix](./../img/remix_deployed.png)
|
||||
|
||||
Now, you are able to interact with the contract through Remix. For `Counter.sol`, click `add`. This will open a Metamask pop-up asking you to confirm. Confirm the transaction. Then, click `getCounter` to get the count, which should be `1`.
|
||||
|
||||
![interacting with deployed contract through remix](./../img/remix_interact.png)
|
@ -1,159 +0,0 @@
|
||||
<!--
|
||||
order: 3
|
||||
-->
|
||||
|
||||
# Truffle: Deploying a Smart Contract
|
||||
|
||||
Learn how to deploy a simple Solidity-based smart contract to Ethermint using the Truffle environment {synopsis}
|
||||
|
||||
## Pre-requisite Readings
|
||||
|
||||
- [Installation](./../quickstart/installation.md) {prereq}
|
||||
- [Run a node](./../quickstart/run_node.md) {prereq}
|
||||
|
||||
[Truffle](https://www.trufflesuite.com/truffle) is a development framework for deploying and managing [Solidity](https://github.com/ethereum/solidity) smart contracts.
|
||||
|
||||
## Install Dependencies
|
||||
|
||||
First, install the latest Truffle version on your machine globally.
|
||||
|
||||
```bash
|
||||
yarn install truffle -g
|
||||
```
|
||||
|
||||
::: tip
|
||||
If you haven't already, you will also need to install Ethermint if you plan on deploying your smart contracts locally. Check this [document](./../../quickstart/installation.md) for the full instructions.
|
||||
:::
|
||||
|
||||
## Create Truffle Project
|
||||
|
||||
In this step we will create a simple counter contract. Feel free to skip this step if you already have your own compiled contract.
|
||||
|
||||
Create a new directory to host the contracts and initialize it:
|
||||
|
||||
```console
|
||||
mkdir ethermint-truffle
|
||||
cd ethermint-truffle
|
||||
```
|
||||
|
||||
Initialize the Truffle suite with:
|
||||
|
||||
```bash
|
||||
truffle init
|
||||
```
|
||||
|
||||
Create `contracts/Counter.sol` containing the following contract:
|
||||
|
||||
```javascript
|
||||
pragma solidity >=0.7.0 <0.9.0;
|
||||
|
||||
contract Counter {
|
||||
uint256 counter = 0;
|
||||
|
||||
function add() public {
|
||||
counter++;
|
||||
}
|
||||
|
||||
function subtract() public {
|
||||
counter--;
|
||||
}
|
||||
|
||||
function getCounter() public view returns (uint256) {
|
||||
return counter;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Compile the contract using the `compile` command:
|
||||
|
||||
```bash
|
||||
truffle compile
|
||||
```
|
||||
|
||||
Create `test/counter_test.js` containing the following tests in Javascript using [Mocha](https://mochajs.org/):
|
||||
|
||||
```javascript
|
||||
const Counter = artifacts.require("Counter")
|
||||
|
||||
contract('Counter', accounts => {
|
||||
const from = accounts[0]
|
||||
let counter
|
||||
|
||||
before(async() => {
|
||||
counter = await Counter.new()
|
||||
})
|
||||
|
||||
it('should add', async() => {
|
||||
await counter.add()
|
||||
let count = await counter.getCounter()
|
||||
assert(count == 1, `count was ${count}`)
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
## Truffle configuration
|
||||
|
||||
Open `truffle-config.js` and uncomment the `development` section in `networks`:
|
||||
|
||||
```javascript
|
||||
development: {
|
||||
host: "127.0.0.1", // Localhost (default: none)
|
||||
port: 8545, // Standard Ethereum port (default: none)
|
||||
network_id: "*", // Any network (default: none)
|
||||
},
|
||||
```
|
||||
|
||||
This will allow your contract to connect to your Ethermint local node.
|
||||
|
||||
## Start Node
|
||||
|
||||
Start your local node using the following command on the Terminal
|
||||
|
||||
```bash
|
||||
# from the ~/ethermint/ directory
|
||||
$ init.sh
|
||||
```
|
||||
|
||||
::: tip
|
||||
For further information on how to run a node, please refer to the [quickstart guide](./../../quickstart/run_node.md).
|
||||
:::
|
||||
|
||||
## Deploy contract
|
||||
|
||||
In the Truffle terminal, migrate the contract using:
|
||||
|
||||
```bash
|
||||
truffle migrate --network development
|
||||
```
|
||||
|
||||
You should see incoming deployment logs in the Ethermint daemon Terminal tab for each transaction (one to deploy `Migrations.sol` and the other to deploy `Counter.sol`).
|
||||
|
||||
```bash
|
||||
$ I[2020-07-15|17:35:59.934] Added good transaction module=mempool tx=22245B935689918D332F58E82690F02073F0453D54D5944B6D64AAF1F21974E2 res="&{CheckTx:log:\"[]\" gas_wanted:6721975 }" height=3 total=1
|
||||
I[2020-07-15|17:36:02.065] Executed block module=state height=4 validTxs=1 invalidTxs=0
|
||||
I[2020-07-15|17:36:02.068] Committed state module=state height=4 txs=1 appHash=76BA85365F10A59FE24ADCA87544191C2D72B9FB5630466C5B71E878F9C0A111
|
||||
I[2020-07-15|17:36:02.981] Added good transaction module=mempool tx=84516B4588CBB21E6D562A6A295F1F8876076A0CFF2EF1B0EC670AD8D8BB5425 res="&{CheckTx:log:\"[]\" gas_wanted:6721975 }" height=4 total=1
|
||||
```
|
||||
|
||||
## Run Truffle tests
|
||||
|
||||
Now, you can run the Truffle tests using the Ethermint node using the `test` command:
|
||||
|
||||
```bash
|
||||
$ truffle test --network development
|
||||
|
||||
Using network 'development'.
|
||||
|
||||
|
||||
Compiling your contracts...
|
||||
===========================
|
||||
> Everything is up to date, there is nothing to compile.
|
||||
|
||||
|
||||
|
||||
Contract: Counter
|
||||
✓ should add (5036ms)
|
||||
|
||||
|
||||
1 passing (10s)
|
||||
```
|
@ -1,97 +0,0 @@
|
||||
<!--
|
||||
order: 5
|
||||
-->
|
||||
|
||||
# Upgrade Node
|
||||
|
||||
Learn how to upgrade your full node to the latest software version {synopsis}
|
||||
|
||||
## Software Upgrade
|
||||
|
||||
These instructions are for full nodes that have ran on previous versions of and would like to upgrade to the latest testnet.
|
||||
|
||||
First, stop your instance of `ethermintd`. Next, upgrade the software:
|
||||
|
||||
```bash
|
||||
cd ethermint
|
||||
git fetch --all && git checkout <new_version>
|
||||
make install
|
||||
```
|
||||
|
||||
::: tip
|
||||
If you have issues at this step, please check that you have the latest stable version of GO installed.
|
||||
:::
|
||||
|
||||
You will need to ensure that the version installed matches the one needed for th testnet. Check the Ethermint [release page](https://github.com/tharsis/ethermint/releases) for details on each release.
|
||||
|
||||
## Upgrade Genesis File
|
||||
|
||||
:::warning
|
||||
If the new version you are upgrading to has breaking changes, you will have to restart your chain. If it is **not** breaking, you can skip to [Restart](#restart-node).
|
||||
:::
|
||||
|
||||
To upgrade the genesis file, you can either fetch it from a trusted source or export it locally using the `ethermintd export` command.
|
||||
|
||||
### Fetch from a Trusted Source
|
||||
|
||||
If you are joining an existing testnet, you can fetch the genesis from the appropriate testnet source/repository where the genesis file is hosted.
|
||||
|
||||
Save the new genesis as `new_genesis.json`. Then, replace the old `genesis.json` with `new_genesis.json`.
|
||||
|
||||
```bash
|
||||
cd $HOME/.ethermintd/config
|
||||
cp -f genesis.json new_genesis.json
|
||||
mv new_genesis.json genesis.json
|
||||
```
|
||||
|
||||
Finally, go to the [reset data](./run_node.md#reset-data) section.
|
||||
|
||||
### Export State
|
||||
|
||||
Ethermint can dump the entire application state to a JSON file. This, besides upgrades, can be
|
||||
useful for manual analysis of the state at a given height.
|
||||
|
||||
Export state with:
|
||||
|
||||
```bash
|
||||
ethermintd export > new_genesis.json
|
||||
```
|
||||
|
||||
You can also export state from a particular height (at the end of processing the block of that height):
|
||||
|
||||
```bash
|
||||
ethermintd export --height [height] > new_genesis.json
|
||||
```
|
||||
|
||||
If you plan to start a new network for 0 height (i.e genesis) from the exported state, export with the `--for-zero-height` flag:
|
||||
|
||||
```bash
|
||||
ethermintd export --height [height] --for-zero-height > new_genesis.json
|
||||
```
|
||||
|
||||
Then, replace the old `genesis.json` with `new_genesis.json`.
|
||||
|
||||
```bash
|
||||
cp -f genesis.json new_genesis.json
|
||||
mv new_genesis.json genesis.json
|
||||
```
|
||||
|
||||
At this point, you might want to run a script to update the exported genesis into a genesis state that is compatible with your new version.
|
||||
|
||||
You can use the `migrate` command to migrate from a given version to the next one (eg: `v0.X.X` to `v1.X.X`):
|
||||
|
||||
```bash
|
||||
ethermintd migrate [target-version] [/path/to/genesis.json] --chain-id=<new_chain_id> --genesis-time=<yyyy-mm-ddThh:mm:ssZ>
|
||||
```
|
||||
|
||||
## Restart Node
|
||||
|
||||
To restart your node once the new genesis has been updated, use the `start` command:
|
||||
|
||||
```bash
|
||||
ethermintd start
|
||||
```
|
||||
|
||||
## Next {hide}
|
||||
|
||||
Learn about how to setup a [validator](./validator-setup.md) node on Ethermint {hide}
|
@ -1,51 +0,0 @@
|
||||
<!--
|
||||
order: 4
|
||||
-->
|
||||
|
||||
# Validator Security Checklist
|
||||
|
||||
Conduct a security checklist survey to go through the security measures of a validator {synopsis}
|
||||
|
||||
## Pre-requisite Readings
|
||||
|
||||
- [Validator Security](./security.md) {prereq}
|
||||
|
||||
## Conduct Survey on General Controls of Hosting Data Centre
|
||||
|
||||
Perform a survey on the hosting data centre, and compare your result with the best practice suggested below
|
||||
|
||||
For example, your hosting data centre should have following features
|
||||
|
||||
| Controls Category | Description of Best Practice |
|
||||
|-------------------|---------------------------------|
|
||||
| Data Center | Redundant Power |
|
||||
| Data Center | Redundant Cooling |
|
||||
| Data Center | Redundant Networking |
|
||||
| Data Center | Physical Cage/Gated Access |
|
||||
| Data Center | Remote Alerting Security Camera |
|
||||
|
||||
## Current Status of Node Setup
|
||||
|
||||
Perform a survey on your current status of node setup, and compare your result with the best practice suggested below
|
||||
|
||||
| Controls Category | Description of Best Practice |
|
||||
|----------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| General System Security | Operating system appropriately patched. Kernel is updated to latest stable version. The node should be operated in x86_64 environment |
|
||||
| General System Security | Auto-updates for operation system is configured. Toolkit for automatic upgrades exists (e.g. auter, yum-cron, dnf-automatic, unattended-upgrades) |
|
||||
| General System Security | Security framework enabled and enforcing. SELinux / AppArmor / Tomoyo / Grsecurity Enabled. |
|
||||
| General System Security | No insecure and unnecessary services Installed. (e.g. telnet, rsh, inetd, etc ...) |
|
||||
| General System Security | GRUB boot loader password is configured. Grub2 configured with password |
|
||||
| General System Security | Only root permissions on core system files |
|
||||
| File Directory Security | Secure the directory `~/.ethermintd` to be accessible by owner only |
|
||||
| Binary Configuration | Recommend the following settings in config.toml for both performance and security - For **sentry nodes**: `max_num_inbound_peers = 500, max_num_outbound_peers = 50, flush_throttle_timeout = "300ms"` - For **validator node**: `max_num_inbound_peers = 100, max_num_outbound_peers = 10, flush_throttle_timeout = "100ms"` |
|
||||
| Account Security & Remote Access | Following Password policies are enforced: No Blank Passwords; Weak Passwords Not Allowed |
|
||||
| Account Security & Remote Access | Following SSH configurations are enabled: PermitRootLogin: `no`; PasswordAuthentication `no`; ChallengeResponseAuthentication `no`; UsePAM `yes`; AllowUsers `Necessary user only`; AllowGroups `Necessary group only`. |
|
||||
| Networking | Network throughput test using speedtest. Recommend to have at least 5 Mbps upload, 5 Mbps download) |
|
||||
| Networking | Host-based (e.g. iptables) or cloud-based (e.g. AWS Security Group) firewall is enabled to protect all the involved nodes. Remote management ports (e.g. SSH - TCP 22) should only be exposed to selected IP instead of the internet. No overly permissive rules (e.g. wide range of allowed ports 1-65535) should be set. For internal communication channels between nodes, they should be set with specific source and destination addresses. For internet reachable nodes, set TCP 26656 to be the only incoming port, if possible. |
|
||||
| Networking | Intrusion Detection / Prevention System (e.g. Fail2Ban, Snort, OSSEC) is installed and enforcing |
|
||||
| Networking | Setup sentry node architecture to protect validator node, and set firewall rules to restrict direct internet access to it. |
|
||||
| Networking | The Remote Procedure Call (RPC) provides sensitive operations and information that is not supposed to be exposed to the Internet. By default, RPC is on and allow connection from 127.0.0.1 only. Please be extremely careful if you need to allow RPC from other IP addresses. |
|
||||
| Redundancy | Hot standby node is setup with the same configuration as main node |
|
||||
| Redundancy | System monitoring and alerting is setup to alert owners on anomalies |
|
||||
| Key Management | Setup Tendermint KMS with HSM or equivalent online service, which should replace the static key file. |
|
||||
| DDOS | Setup validator in accordance with sentry architecture. Kindly refer to the setup [instruction](https://docs.tendermint.com/master/nodes/validators.html#setting-up-a-validator) and [detailed description](https://forum.cosmos.network/t/sentry-node-architecture-overview/454). |
|
@ -1,310 +0,0 @@
|
||||
<!--
|
||||
order: 5
|
||||
-->
|
||||
|
||||
# Validator FAQ
|
||||
|
||||
Check the FAQ for running a validator on Ethermint {synopsis}
|
||||
|
||||
## General Concepts
|
||||
|
||||
### What is a validator?
|
||||
|
||||
Ethermint is powered by [Tendermint](https://tendermint.com/docs/introduction/what-is-tendermint.html) Core, which relies on a set of validators to secure the network. Validators run a full node and participate in consensus by broadcasting votes which contain cryptographic signatures signed by their private key. Validators commit new blocks in the blockchain and receive revenue in exchange for their work. They also participate in on-procotol treasury governance by voting on governance proposals. A validator's voting influence is weighted according to their total stake.
|
||||
|
||||
### What is "staking"?
|
||||
|
||||
Ethermint is a public Proof-of-Stake (PoS) blockchain, meaning that validator's weight is determined by the amount of staking tokens (Photon) bonded as collateral. These staking tokens can be staked directly by the validator or delegated to them by Photon holders.
|
||||
|
||||
Any user in the system can declare its intention to become a validator by sending a [`create-validator`](#how-to-become-a-validator) transaction. From there, they become validators.
|
||||
|
||||
The weight (i.e. total stake or voting power) of a validator determines wether or not it is an active validator, and also how frequently this node will have to propose a block and how much revenue it will obtain. Initially, only the top 125 validators with the most weight will be active validators. If validators double-sign, or are frequently offline, they risk their staked tokens (including Photons delegated by users) being "slashed" by the protocol to penalize negligence and misbehavior.
|
||||
|
||||
### What is a full node?
|
||||
|
||||
A full node is a program that fully validates transactions and blocks of a blockchain. It is distinct from a light client node that only processes block headers and a small subset of transactions. Running a full node requires more resources than a light client but is necessary in order to be a validator. In practice, running a full-node only implies running a non-compromised and up-to-date version of the software with low network latency and without downtime.
|
||||
|
||||
Of course, it is possible and encouraged for any user to run full nodes even if they do not plan to be validators.
|
||||
|
||||
### What is a delegator?
|
||||
|
||||
Delegators are Photon holders who cannot, or do not want to run validator operations themselves. Users can delegate Photons to a validator and obtain a part of its revenue in exchange (for more detail on how revenue is distributed, see [What is the incentive to stake?](#what-is-the-incentive-to-stake) and [What is a validator's commission?](#what-is-a-validators-commission) sections below).
|
||||
|
||||
Because they share revenue with their validators, delegators also share responsibility. Should a validator misbehave, each of its delegators will be partially slashed in proportion to their stake. This is why delegators should perform due-diligence on validators before delegating, as well as diversifying by spreading their stake over multiple validators.
|
||||
|
||||
Delegators play a critical role in the system, as they are responsible for choosing validators. Be aware that being a delegator is not a passive role. Delegators are obligated to remain vigilant and actively monitor the actions of their validators, switching should they fail to act responsibly.
|
||||
|
||||
## Becoming a Validator
|
||||
|
||||
### How to become a validator?
|
||||
|
||||
Any participant in the network can signal their intent to become a validator by creating a validator and registering its validator profile. To do so, the candidate broadcasts a `create-validator` transaction, in which they must submit the following information:
|
||||
|
||||
- **Validator's PubKey**: Validator operators can have different accounts for validating and holding liquid funds. The PubKey submitted must be associated with the private key with which the validator intends to sign _prevotes_ and _precommits_.
|
||||
- **Validator's Address**: `ethmvaloper1-` address. This is the address used to identify your validator publicly. The private key associated with this address is used to bond, unbond, and claim rewards.
|
||||
- **Validator's name** (also known as the **moniker**)
|
||||
- **Validator's website** _(optional)_
|
||||
- **Validator's description** _(optional)_
|
||||
- **Initial commission rate**: The commission rate on block provisions, block rewards and fees charged to delegators.
|
||||
- **Maximum commission**: The maximum commission rate which this validator will be allowed to charge.
|
||||
- **Commission change rate**: The maximum daily increase of the validator commission.
|
||||
- **Minimum self-bond amount**: Minimum amount of Photon the validator needs to have bonded at all times. If the validator's self-bonded stake falls below this limit, its entire staking pool will be unbonded.
|
||||
- **Initial self-bond amount**: Initial amount of Photon the validator wants to self-bond.
|
||||
|
||||
```bash
|
||||
ethermintd tx staking create-validator
|
||||
--pubkey ethmvalconspub1zcjduepqs5s0vddx5m65h5ntjzwd0x8g3245rgrytpds4ds7vdtlwx06mcesmnkzly
|
||||
--amount "2aphoton"
|
||||
--from tmp
|
||||
--commission-rate="0.20"
|
||||
--commission-max-rate="1.00"
|
||||
--commission-max-change-rate="0.01"
|
||||
--min-self-delegation "1"
|
||||
--moniker "validator"
|
||||
--chain-id "ethermint_9000-1"
|
||||
--gas auto
|
||||
--node tcp://127.0.0.1:26647
|
||||
```
|
||||
|
||||
Once a validator is created and registered, Photon holders can delegate Photons to it, effectively adding stake to its pool. The total stake of a validator is the sum of the Photon self-bonded by the validator's operator and the Photon bonded by external delegators.
|
||||
|
||||
**Only the top 125 validators with the most stake are considered the active validators**, becoming **bonded validators**. If ever a validator's total stake dips below the top 125, the validator loses its validator privileges (meaning that it won't generate rewards) and no longer serves as part of the active set (i.e doesn't participate in consensus), entering **unbonding mode** and eventually becomes **unbonded**.
|
||||
|
||||
## Validator keys and states
|
||||
|
||||
### What are the different types of keys?
|
||||
|
||||
In short, there are two types of keys:
|
||||
|
||||
- **Tendermint Key**: This is a unique key used to sign block hashes. It is associated with a public key `ethmvalconspub`.
|
||||
|
||||
- Generated when the node is created with `ethermintd init`.
|
||||
- Get this value with `ethermintd tendermint show-validator`
|
||||
e.g. `ethmvalconspub1zcjduc3qcyj09qc03elte23zwshdx92jm6ce88fgc90rtqhjx8v0608qh5ssp0w94c`
|
||||
|
||||
- **Application keys**: These keys are created from the application and used to sign transactions. As a validator, you will probably use one key to sign staking-related transactions, and another key to sign oracle-related transactions. Application keys are associated with a public key `ethmpub-` and an address `ethm-`. Both are derived from account keys generated by `ethermintd keys add`.
|
||||
|
||||
::: warning
|
||||
A validator's operator key is directly tied to an application key, but uses reserved prefixes solely for this purpose: `ethmvaloper` and `ethmvaloperpub`
|
||||
:::
|
||||
|
||||
### What are the different states a validator can be in?
|
||||
|
||||
After a validator is created with a `create-validator` transaction, it can be in three states:
|
||||
|
||||
- `bonded`: Validator is in the active set and participates in consensus. Validator is earning rewards and can be slashed for misbehaviour.
|
||||
|
||||
- `unbonding`: Validator is not in the active set and does not participate in consensus. Validator is not earning rewards, but can still be slashed for misbehaviour. This is a transition state from `bonded` to `unbonded`. If validator does not send a `rebond` transaction while in `unbonding` mode, it will take three weeks for the state transition to complete.
|
||||
|
||||
- `unbonded`: Validator is not in the active set, and therefore not signing blocks. Unbonded validators cannot be slashed, but do not earn any rewards from their operation. It is still possible to delegate Photon to this validator. Un-delegating from an `unbonded` validator is immediate.
|
||||
|
||||
Delegators have the same state as their validator.
|
||||
|
||||
::: warning
|
||||
Delegations are not necessarily bonded. Photon can be delegated and bonded, delegated and unbonding, delegated and unbonded, or liquid.
|
||||
:::
|
||||
|
||||
### What is "self-bond"? How can I increase my "self-bond"?
|
||||
|
||||
The validator operator's "self-bond" refers to the amount of Photon stake delegated to itself. You can increase your self-bond by delegating more Photon to your validator account.
|
||||
|
||||
### Is there a faucet?
|
||||
|
||||
<!-- TODO: add link -->
|
||||
If you want to obtain coins for the testnet, you can do so by using the faucet (link to be announced).
|
||||
|
||||
### Is there a minimum amount of Photon that must be staked to be an active (bonded) validator?
|
||||
|
||||
There is no minimum. The top 125 validators with the highest total stake (where `total stake = self-bonded stake + delegators stake`) are the active validators.
|
||||
|
||||
### How will delegators choose their validators?
|
||||
|
||||
Delegators are free to choose validators according to their own subjective criteria. That said, criteria anticipated to be important include:
|
||||
|
||||
- **Amount of self-bonded Photon:** Number of Photons a validator self-bonded to its staking pool. A validator with higher amount of self-bonded Photon has more skin in the game, making it more liable for its actions.
|
||||
|
||||
- **Amount of delegated Photons:** Total number of Photon delegated to a validator. A high stake shows that the community trusts this validator, but it also means that this validator is a bigger target for hackers. Validators are expected to become less and less attractive as their amount of delegated Photon grows. Bigger validators also increase the centralization of the network.
|
||||
|
||||
- **Commission rate:** Commission applied on revenue by validators before it is distributed to their delegators
|
||||
|
||||
- **Track record:** Delegators will likely look at the track record of the validators they plan to delegate to. This includes seniority, past votes on proposals, historical average uptime and how often the node was compromised.
|
||||
|
||||
Apart from these criteria, there will be a possibility for validators to signal a website address to complete their resume. Validators will need to build reputation one way or another to attract delegators. For example, it would be a good practice for validators to have their setup audited by third parties. Note though, that the Ethermint team will not approve or conduct any audit itself.
|
||||
|
||||
## Responsibilites
|
||||
|
||||
### Do validators need to be publicly identified?
|
||||
|
||||
No, they do not. Each delegator will value validators based on their own criteria. Validators will be able(and are advised) to register a website address when they nominate themselves so that they can advertise their operation as they see fit. Some delegators may prefer a website that clearly displays the team running the validator and their resume, while others might prefer anonymous validators with positive track records. Most likely both identified and anonymous validators will coexist in the validator set.
|
||||
|
||||
### What are the responsiblities of a validator?
|
||||
|
||||
Validators have three main responsibilities:
|
||||
|
||||
- **Be able to constantly run a correct version of the software:** validators need to make sure that their servers are always online and their private keys are not compromised.
|
||||
|
||||
- **Provide oversight and feedback on correct deployment of community pool funds:** the Ethermint protocol includes the a governance system for proposals to the facilitate adoption of its currencies. Validators are expected to hold budget executors to account to provide transparency and efficient use of funds.
|
||||
|
||||
Additionally, validators are expected to be active members of the community. They should always be up-to-date with the current state of the ecosystem so that they can easily adapt to any change.
|
||||
|
||||
### What does staking imply?
|
||||
|
||||
Staking Photon can be thought of as a safety deposit on validation activities. When a validator or a delegator wants to retrieve part or all of their deposit, they send an unbonding transaction. Then, Photon undergo a _three weeks unbonding period_ during which they are liable to being slashed for potential misbehaviors committed by the validator before the unbonding process started.
|
||||
|
||||
Validators, and by association delegators, receive block provisions, block rewards, and fee rewards. If a validator misbehaves, a certain portion of its total stake is slashed (the severity of the penalty depends on the type of misbehavior). This means that every user that bonded Photon to this validator gets penalized in proportion to its stake. Delegators are therefore incentivized to delegate to validators that they anticipate will function safely.
|
||||
|
||||
### Can a validator run away with its delegators' Photon?
|
||||
|
||||
By delegating to a validator, a user delegates staking power. The more staking power a validator has, the more weight it has in the consensus and processes. This does not mean that the validator has custody of its delegators' Photon. _By no means can a validator run away with its delegator's funds_.
|
||||
|
||||
Even though delegated funds cannot be stolen by their validators, delegators are still liable if their validators misbehave. In such case, each delegators' stake will be partially slashed in proportion to their relative stake.
|
||||
|
||||
### How often will a validator be chosen to propose the next block? Does it go up with the quantity of Photon staked?
|
||||
|
||||
The validator that is selected to mine the next block is called the **proposer**, the "leader" in the consensus for the round. Each proposer is selected deterministically, and the frequency of being chosen is equal to the relative total stake (where total stake = self-bonded stake + delegators stake) of the validator. For example, if the total bonded stake across all validators is 100 Photon, and a validator's total stake is 10 Photon, then this validator will be chosen 10% of the time as the proposer.
|
||||
|
||||
To understand more about the proposer selection process in Tendermint BFT consensus, read more [in their official docs](https://docs.tendermint.com/master/spec/reactors/consensus/proposer-selection.html).
|
||||
|
||||
## Incentives
|
||||
|
||||
### What is the incentive to stake?
|
||||
|
||||
Each member of a validator's staking pool earns different types of revenue:
|
||||
|
||||
- **Block rewards:** Native tokens of applications run by validators (e.g. Photons on Ethermint) are inflated to produce block provisions. These provisions exist to incentivize Photon holders to bond their stake, as non-bonded Photon will be diluted over time.
|
||||
- **Transaction fees:** Ethermint maintains a whitelist of token that are accepted as fee payment. The initial fee token is the `photon`.
|
||||
|
||||
This total revenue is divided among validators' staking pools according to each validator's weight. Then, within each validator's staking pool the revenue is divided among delegators in proportion to each delegator's stake. A commission on delegators' revenue is applied by the validator before it is distributed.
|
||||
|
||||
### What is the incentive to run a validator ?
|
||||
|
||||
Validators earn proportionally more revenue than their delegators because of commissions.
|
||||
|
||||
Validators also play a major role in governance. If a delegator does not vote, they inherit the vote from their validator. This gives validators a major responsibility in the ecosystem.
|
||||
|
||||
### What is a validator's commission?
|
||||
|
||||
Revenue received by a validator's pool is split between the validator and its delegators. The validator can apply a commission on the part of the revenue that goes to its delegators. This commission is set as a percentage. Each validator is free to set its initial commission, maximum daily commission change rate and maximum commission. Ethermint enforces the parameter that each validator sets. These parameters can only be defined when initially declaring candidacy, and may only be constrained further after being declared.
|
||||
|
||||
### How are block provisions distributed?
|
||||
|
||||
Block provisions (rewards) are distributed proportionally to all validators relative to their total stake (voting power). This means that even though each validator gains Photons with each provision, all validators will still maintain equal weight.
|
||||
|
||||
Let us take an example where we have 10 validators with equal staking power and a commission rate of 1%. Let us also assume that the provision for a block is 1000 Photons and that each validator has 20% of self-bonded Photon. These tokens do not go directly to the proposer. Instead, they are evenly spread among validators. So now each validator's pool has 100 Photons. These 100 Photons will be distributed according to each participant's stake:
|
||||
|
||||
- Commission: `100*80%*1% = 0.8 Photons`
|
||||
- Validator gets: `100\*20% + Commission = 20.8 Photons`
|
||||
- All delegators get: `100\*80% - Commission = 79.2 Photons`
|
||||
|
||||
Then, each delegator can claim its part of the 79.2 Photons in proportion to their stake in the validator's staking pool. Note that the validator's commission is not applied on block provisions. Note that block rewards (paid in Photons) are distributed according to the same mechanism.
|
||||
|
||||
### How are fees distributed?
|
||||
|
||||
Fees are similarly distributed with the exception that the block proposer can get a bonus on the fees of the block it proposes if it includes more than the strict minimum of required precommits.
|
||||
|
||||
When a validator is selected to propose the next block, it must include at least ⅔ precommits for the previous block in the form of validator signatures. However, there is an incentive to include more than ⅔ precommits in the form of a bonus. The bonus is linear: it ranges from 1% if the proposer includes ⅔rd precommits (minimum for the block to be valid) to 5% if the proposer includes 100% precommits. Of course the proposer should not wait too long or other validators may timeout and move on to the next proposer. As such, validators have to find a balance between wait-time to get the most signatures and risk of losing out on proposing the next block. This mechanism aims to incentivize non-empty block proposals, better networking between validators as well as to mitigate censorship.
|
||||
|
||||
Let's take a concrete example to illustrate the aforementioned concept. In this example, there are 10 validators with equal stake. Each of them applies a 1% commission and has 20% of self-bonded Photon. Now comes a successful block that collects a total of 1005 Photons in fees. Let's assume that the proposer included 100% of the signatures in its block. It thus obtains the full bonus of 5%.
|
||||
|
||||
We have to solve this simple equation to find the reward $R$ for each validator:
|
||||
|
||||
$$9R ~ + ~ R ~ + ~ 5\%(R) ~ = ~ 1005 ~ \Leftrightarrow ~ R ~ = ~ 1005 ~/ ~10.05 ~ = ~ 100$$
|
||||
|
||||
- For the proposer validator:
|
||||
|
||||
- The pool obtains $R ~ + ~ 5\%(R)$: 105 Photons
|
||||
- Commission: $105 ~ * ~ 80\% ~ * ~ 1\%$ = 0.84 Photons
|
||||
- Validator's reward: $105 ~ * ~ 20\% ~ + ~ Commission$ = 21.84 Photons
|
||||
- Delegators' rewards: $105 ~ * ~ 80\% ~ - ~ Commission$ = 83.16 Photons \(each delegator will be able to claim its portion of these rewards in proportion to their stake\)
|
||||
|
||||
- The pool obtains $R$: 100 Photons
|
||||
- Commission: $100 ~ * ~ 80\% ~ * ~ 1\%$ = 0.8 Photons
|
||||
- Validator's reward: $100 ~ * ~ 20\% ~ + ~ Commission$ = 20.8 Photons
|
||||
- Delegators' rewards: $100 ~ * ~ 80\% ~ - ~ Commission$ = 79.2 Photons \(each delegator will be able to claim its portion of these rewards in proportion to their stake\)
|
||||
|
||||
### What are the slashing conditions?
|
||||
|
||||
If a validator misbehaves, its bonded stake along with its delegators' stake and will be slashed. The severity of the punishment depends on the type of fault. There are 3 main faults that can result in slashing of funds for a validator and its delegators:
|
||||
|
||||
- **Double-signing:** If someone reports on chain A that a validator signed two blocks at the same height on chain A and chain B, and if chain A and chain B share a common ancestor, then this validator will get slashed on chain A.
|
||||
|
||||
- **Downtime:** If a validator misses more than 95% of the last 10.000 blocks, they will get slashed by 0.01%.
|
||||
- **Unavailability:** If a validator's signature has not been included in the last X blocks, the validator will get slashed by a marginal amount proportional to X. If X is above a certain limit Y, then the validator will get unbonded.
|
||||
- **Non-voting:** If a validator did not vote on a proposal, its stake could receive a minor slash.
|
||||
|
||||
Note that even if a validator does not intentionally misbehave, it can still be slashed if its node crashes, looses connectivity, gets DDoSed, or if its private key is compromised.
|
||||
|
||||
### Do validators need to self-bond Photons
|
||||
|
||||
No, they do not. A validators total stake is equal to the sum of its own self-bonded stake and of its delegated stake. This means that a validator can compensate its low amount of self-bonded stake by attracting more delegators. This is why reputation is very important for validators.
|
||||
|
||||
Even though there is no obligation for validators to self-bond Photon, delegators should want their validator to have self-bonded Photon in their staking pool. In other words, validators should have skin-in-the-game.
|
||||
|
||||
In order for delegators to have some guarantee about how much skin-in-the-game their validator has, the latter can signal a minimum amount of self-bonded Photon. If a validator's self-bond goes below the limit that it predefined, this validator and all of its delegators will unbond.
|
||||
|
||||
### How to prevent concentration of stake in the hands of a few top validators?
|
||||
|
||||
For now the community is expected to behave in a smart and self-preserving way. When a mining pool in Bitcoin gets too much mining power the community usually stops contributing to that pool. Ethermint will rely on the same effect initially. In the future, other mechanisms will be deployed to smoothen this process as much as possible:
|
||||
|
||||
- **Penalty-free re-delegation:** This is to allow delegators to easily switch from one validator to another, in order to reduce validator stickiness.
|
||||
- **UI warning:** Wallets can implement warnings that will be displayed to users if they want to delegate to a validator that already has a significant amount of staking power.
|
||||
|
||||
## Technical Requirements
|
||||
|
||||
### What are hardware requirements?
|
||||
|
||||
Validators should expect to provision one or more data center locations with redundant power, networking, firewalls, HSMs and servers.
|
||||
|
||||
We expect that a modest level of hardware specifications will be needed initially and that they might rise as network use increases. Participating in the testnet is the best way to learn more.
|
||||
|
||||
### What are software requirements?
|
||||
|
||||
In addition to running an Ethermint node, validators should develop monitoring, alerting and management solutions.
|
||||
|
||||
### What are bandwidth requirements?
|
||||
|
||||
Ethermint has the capacity for very high throughput compared to chains like Ethereum or Bitcoin.
|
||||
|
||||
As such, we recommend that the data center nodes only connect to trusted full nodes in the cloud or other validators that know each other socially. This relieves the data center node from the burden of mitigating denial-of-service attacks.
|
||||
|
||||
Ultimately, as the network becomes more used, one can realistically expect daily bandwidth on the order of several gigabytes.
|
||||
|
||||
### What does running a validator imply in terms of logistics?
|
||||
|
||||
A successful validator operation will require the efforts of multiple highly skilled individuals and continuous operational attention. This will be considerably more involved than running a bitcoin miner for instance.
|
||||
|
||||
### How to handle key management?
|
||||
|
||||
Validators should expect to run an HSM that supports ed25519 keys. Here are potential options:
|
||||
|
||||
- YubiHSM 2
|
||||
- Ledger Nano S
|
||||
- Ledger BOLOS SGX enclave
|
||||
- Thales nShield support
|
||||
- [Strangelove Horocrux](https://github.com/strangelove-ventures/horcrux)
|
||||
|
||||
The Ethermint team does not recommend one solution above the other. The community is encouraged to bolster the effort to improve HSMs and the security of key management.
|
||||
|
||||
### What can validators expect in terms of operations?
|
||||
|
||||
Running effective operation is the key to avoiding unexpectedly unbonding or being slashed. This includes being able to respond to attacks, outages, as well as to maintain security and isolation in your data center.
|
||||
|
||||
### What are the maintenance requirements?
|
||||
|
||||
Validators should expect to perform regular software updates to accommodate upgrades and bug fixes. There will inevitably be issues with the network early in its bootstrapping phase that will require substantial vigilance.
|
||||
|
||||
### How can validators protect themselves from Denial-of-Service attacks?
|
||||
|
||||
Denial-of-service attacks occur when an attacker sends a flood of internet traffic to an IP address to prevent the server at the IP address from connecting to the internet.
|
||||
|
||||
An attacker scans the network, tries to learn the IP address of various validator nodes and disconnect them from communication by flooding them with traffic.
|
||||
|
||||
One recommended way to mitigate these risks is for validators to carefully structure their network topology in a so-called sentry node architecture.
|
||||
|
||||
Validator nodes should only connect to full-nodes they trust because they operate them themselves or are run by other validators they know socially. A validator node will typically run in a data center. Most data centers provide direct links the networks of major cloud providers. The validator can use those links to connect to sentry nodes in the cloud. This shifts the burden of denial-of-service from the validator's node directly to its sentry nodes, and may require new sentry nodes be spun up or activated to mitigate attacks on existing ones.
|
||||
|
||||
Sentry nodes can be quickly spun up or change their IP addresses. Because the links to the sentry nodes are in private IP space, an internet based attacked cannot disturb them directly. This will ensure validator block proposals and votes always make it to the rest of the network.
|
||||
|
||||
It is expected that good operating procedures on that part of validators will completely mitigate these threats.
|
||||
|
||||
For more on sentry node architecture, see [this](https://forum.cosmos.network/t/sentry-node-architecture-overview/454).
|
@ -1,39 +0,0 @@
|
||||
<!--
|
||||
order: 1
|
||||
-->
|
||||
|
||||
# Overview
|
||||
|
||||
Learn about validating on Ethermint {synopsis}
|
||||
|
||||
## Introduction
|
||||
|
||||
Ethermint is based on [Tendermint](https://github.com/tendermint/tendermint/blob/master/docs/introduction/what-is-tendermint.md), which relies on a set of validators that are responsible for committing new blocks in the blockchain. These validators participate in the consensus protocol by broadcasting votes which contain cryptographic signatures signed by each validator's private key.
|
||||
|
||||
Validator candidates can bond their own staking tokens and have the tokens "delegated", or staked, to them by token holders. The **Photon** is Ethermint's native token. At its onset, Ethermint will launch with 125 validators; this will increase to 300 validators according to a predefined schedule. The validators are determined by who has the most stake delegated to them — the top 125 validator candidates with the most stake will become Ethermint validators.
|
||||
|
||||
Validators and their delegators will earn Photons as block provisions and tokens as transaction fees through execution of the Tendermint consensus protocol. Initially, transaction fees will be paid in Photons but in the future, any token in the Cosmos ecosystem will be valid as fee tender if it is whitelisted by governance. Note that validators can set commission on the fees their delegators receive as additional incentive.
|
||||
|
||||
If validators double sign, are frequently offline or do not participate in governance, their staked Atoms (including Atoms of users that delegated to them) can be slashed. The penalty depends on the severity of the violation.
|
||||
|
||||
## Hardware
|
||||
|
||||
Validators should set up a physical operation secured with restricted access. A good starting place, for example, would be co-locating in secure data centers.
|
||||
|
||||
Validators should expect to equip their datacenter location with redundant power, connectivity, and storage backups. Expect to have several redundant networking boxes for fiber, firewall and switching and then small servers with redundant hard drive and failover. Hardware can be on the low end of datacenter gear to start out with.
|
||||
|
||||
We anticipate that network requirements will be low initially. Bandwidth, CPU and memory requirements will rise as the network grows. Large hard drives are recommended for storing years of blockchain history.
|
||||
|
||||
## Set Up a Website
|
||||
|
||||
Set up a dedicated validator's website and signal your intention to become a validator on Discord. This is important since delegators will want to have information about the entity they are delegating their Photons to.
|
||||
|
||||
## Seek Legal Advice
|
||||
|
||||
Seek legal advice if you intend to run a validator.
|
||||
|
||||
## Community
|
||||
|
||||
Discuss the finer details of being a validator on our community chat and forum:
|
||||
|
||||
* [Validator Forum](https://forum.cosmos.network/c/validating)
|
@ -1,61 +0,0 @@
|
||||
<!--
|
||||
order: 3
|
||||
-->
|
||||
|
||||
# Validator Security
|
||||
|
||||
Learn about sentry nodes and HSMs to secure a validator {synopsis}
|
||||
|
||||
Each validator candidate is encouraged to run its operations independently, as diverse setups increase the resilience of the network. Validator candidates should commence their setup phase now in order to be on time for launch.
|
||||
|
||||
## Key Management - HSM
|
||||
|
||||
It is mission critical that an attacker cannot steal a validator's key. If this is possible, it puts the entire stake delegated to the compromised validator at risk. Hardware security modules are an important strategy for mitigating this risk.
|
||||
|
||||
HSM modules must support `ed25519` signatures for the hub. The [YubiHSM2 supports `ed25519` and can be used with this yubikey [library](https://github.com/iqlusioninc/yubihsm.rs). The YubiHSM can protect a private key but cannot ensure in a secure setting that it won't sign the same block twice.
|
||||
|
||||
The Tendermint team is also working on extending our Ledger Nano S application to support validator signing. This app can store recent blocks and mitigate double signing attacks.
|
||||
|
||||
We will update this page when more key storage solutions become available.
|
||||
|
||||
## Sentry Nodes (DDOS Protection)
|
||||
|
||||
Validators are responsible for ensuring that the network can sustain denial of service attacks.
|
||||
|
||||
One recommended way to mitigate these risks is for validators to carefully structure their network topology in a so-called sentry node architecture.
|
||||
|
||||
Validator nodes should only connect to full-nodes they trust because they operate them themselves or are run by other validators they know socially. A validator node will typically run in a data center. Most data centers provide direct links the networks of major cloud providers. The validator can use those links to connect to sentry nodes in the cloud. This shifts the burden of denial-of-service from the validator's node directly to its sentry nodes, and may require new sentry nodes be spun up or activated to mitigate attacks on existing ones.
|
||||
|
||||
Sentry nodes can be quickly spun up or change their IP addresses. Because the links to the sentry nodes are in private IP space, an internet based attacked cannot disturb them directly. This will ensure validator block proposals and votes always make it to the rest of the network.
|
||||
|
||||
To setup your sentry node architecture you can follow the instructions below:
|
||||
|
||||
Validators nodes should edit their config.toml:
|
||||
|
||||
```bash
|
||||
# Comma separated list of nodes to keep persistent connections to
|
||||
# Do not add private peers to this list if you don't want them advertised
|
||||
persistent_peers =[list of sentry nodes]
|
||||
|
||||
# Set true to enable the peer-exchange reactor
|
||||
pex = false
|
||||
```
|
||||
|
||||
Sentry Nodes should edit their config.toml:
|
||||
|
||||
```bash
|
||||
# Comma separated list of peer IDs to keep private (will not be gossiped to other peers)
|
||||
# Example ID: 3e16af0cead27979e1fc3dac57d03df3c7a77acc@3.87.179.235:26656
|
||||
|
||||
private_peer_ids = "node_ids_of_private_peers"
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
By default, uppercase environment variables with the following prefixes will replace lowercase command-line flags:
|
||||
|
||||
- `EM` (for Ethermint flags)
|
||||
- `TM` (for Tendermint flags)
|
||||
- `BC` (for democli or basecli flags)
|
||||
|
||||
For example, the environment variable `GA_CHAIN_ID` will map to the command line flag `--chain-id`. Note that while explicit command-line flags will take precedence over environment variables, environment variables will take precedence over any of your configuration files. For this reason, it's imperative that you lock down your environment such that any critical parameters are defined as flags on the CLI or prevent modification of any environment variables.
|
@ -1,236 +0,0 @@
|
||||
<!--
|
||||
order: 2
|
||||
-->
|
||||
|
||||
# Run a Validator
|
||||
|
||||
Learn how to setup and run a validator node {synopsis}
|
||||
|
||||
## Pre-requisite Readings
|
||||
|
||||
- [Validator Overview](./overview.md) {prereq}
|
||||
- [Full Node Setup](../localnet/single_node.md#manual-localnet) {prereq}
|
||||
|
||||
If you plan to use a Key Management System (KMS), you should go through these steps first: [Using a KMS](./../kms/kms.md).
|
||||
|
||||
## What is a Validator?
|
||||
|
||||
[Validators](./overview.md) are responsible for committing new blocks to the blockchain through voting. A validator's stake is slashed if they become unavailable or sign blocks at the same height. Please read about [Sentry Node Architecture](./validator-faq.md#how-can-validators-protect-themselves-from-denial-of-service-attacks) to protect your node from DDoS attacks and to ensure high-availability.
|
||||
|
||||
::: danger Warning
|
||||
If you want to become a validator for the Hub's `mainnet`, you should [research security](./security.md).
|
||||
:::
|
||||
|
||||
## Supported OS
|
||||
|
||||
We officially support macOS, Windows and Linux only. Other platforms may work but there is no
|
||||
guarantee. We will extend our support to other platforms after we have stabilized our current
|
||||
architecture.
|
||||
|
||||
## Minimum Requirements
|
||||
|
||||
To run testnet nodes, you will need a machine with the following minimum requirements:
|
||||
|
||||
<!-- TODO: verify -->
|
||||
- 4-core, x86_64 architecture processor;
|
||||
- 16 GB RAM;
|
||||
- 256 GB of storage space.
|
||||
|
||||
## Create Your Validator
|
||||
|
||||
Your `ethmvalconspub` can be used to create a new validator by staking tokens. You can find your validator pubkey by running:
|
||||
|
||||
```bash
|
||||
ethermintd tendermint show-validator
|
||||
```
|
||||
|
||||
To create your validator, just use the following command:
|
||||
|
||||
::: warning
|
||||
Don't use more `aphoton` than you have!
|
||||
:::
|
||||
|
||||
```bash
|
||||
ethermintd tx staking create-validator \
|
||||
--amount=1000000aphoton \
|
||||
--pubkey=$(ethermintd tendermint show-validator) \
|
||||
--moniker="choose a moniker" \
|
||||
--chain-id=<chain_id> \
|
||||
--commission-rate="0.10" \
|
||||
--commission-max-rate="0.20" \
|
||||
--commission-max-change-rate="0.01" \
|
||||
--min-self-delegation="1000000" \
|
||||
--gas="auto" \
|
||||
--gas-prices="0.025aphoton" \
|
||||
--from=<key_name>
|
||||
```
|
||||
|
||||
::: tip
|
||||
When specifying commission parameters, the `commission-max-change-rate` is used to measure % _point_ change over the `commission-rate`. E.g. 1% to 2% is a 100% rate increase, but only 1 percentage point.
|
||||
:::
|
||||
|
||||
::: tip
|
||||
`Min-self-delegation` is a strictly positive integer that represents the minimum amount of self-delegated voting power your validator must always have. A `min-self-delegation` of `1000000` means your validator will never have a self-delegation lower than `1 aphoton`
|
||||
:::
|
||||
|
||||
You can confirm that you are in the validator set by using a third party explorer.
|
||||
|
||||
## Participate in Genesis as a Validator
|
||||
|
||||
If you want to participate in genesis as a validator, you need to justify that
|
||||
you have some stake at genesis, create one (or multiple) transactions to bond this stake to your validator address, and include this transaction in the genesis file.
|
||||
|
||||
Your `ethmvalconspub` can be used to create a new validator by staking tokens. You can find your validator pubkey by running:
|
||||
|
||||
```bash
|
||||
ethermintd tendermint show-validator
|
||||
```
|
||||
|
||||
Next, craft your `ethermintd gentx` command.
|
||||
|
||||
::: tip
|
||||
A `gentx` is a JSON file carrying a self-delegation. All genesis transactions are collected by a `genesis coordinator` and validated against an initial `genesis.json`.
|
||||
:::
|
||||
|
||||
::: warning Note
|
||||
Don't use more `aphoton` than you have!
|
||||
:::
|
||||
|
||||
```bash
|
||||
ethermintd gentx \
|
||||
--amount <amount_of_delegation_aphoton> \
|
||||
--commission-rate <commission_rate> \
|
||||
--commission-max-rate <commission_max_rate> \
|
||||
--commission-max-change-rate <commission_max_change_rate> \
|
||||
--pubkey <consensus_pubkey> \
|
||||
--name <key_name>
|
||||
```
|
||||
|
||||
::: tip
|
||||
When specifying commission parameters, the `commission-max-change-rate` is used to measure % _point_ change over the `commission-rate`. E.g. 1% to 2% is a 100% rate increase, but only 1 percentage point.
|
||||
:::
|
||||
|
||||
You can then submit your `gentx` on the [launch repository](https://github.com/cosmos/launch). These `gentx` will be used to form the final genesis file.
|
||||
|
||||
## Edit Validator Description
|
||||
|
||||
You can edit your validator's public description. This info is to identify your validator, and will be relied on by delegators to decide which validators to stake to. Make sure to provide input for every flag below. If a flag is not included in the command the field will default to empty (`--moniker` defaults to the machine name) if the field has never been set or remain the same if it has been set in the past.
|
||||
|
||||
The <key_name> specifies which validator you are editing. If you choose to not include certain flags, remember that the --from flag must be included to identify the validator to update.
|
||||
|
||||
The `--identity` can be used as to verify identity with systems like Keybase or UPort. When using with Keybase `--identity` should be populated with a 16-digit string that is generated with a [keybase.io](https://keybase.io) account. It's a cryptographically secure method of verifying your identity across multiple online networks. The Keybase API allows us to retrieve your Keybase avatar. This is how you can add a logo to your validator profile.
|
||||
|
||||
```bash
|
||||
ethermintd tx staking edit-validator
|
||||
--moniker="choose a moniker" \
|
||||
--website="https://ethermint.dev" \
|
||||
--identity=6A0D65E29A4CBC8E \
|
||||
--details="To infinity and beyond!" \
|
||||
--chain-id=<chain_id> \
|
||||
--gas="auto" \
|
||||
--gas-prices="0.025aphoton" \
|
||||
--from=<key_name> \
|
||||
--commission-rate="0.10"
|
||||
```
|
||||
|
||||
__Note__: The `commission-rate` value must adhere to the following invariants:
|
||||
|
||||
- Must be between 0 and the validator's `commission-max-rate`
|
||||
- Must not exceed the validator's `commission-max-change-rate` which is maximum
|
||||
% point change rate **per day**. In other words, a validator can only change
|
||||
its commission once per day and within `commission-max-change-rate` bounds.
|
||||
|
||||
## View Validator Description
|
||||
|
||||
View the validator's information with this command:
|
||||
|
||||
```bash
|
||||
ethermintd query staking validator <account_cosmos>
|
||||
```
|
||||
|
||||
## Track Validator Signing Information
|
||||
|
||||
In order to keep track of a validator's signatures in the past you can do so by using the `signing-info` command:
|
||||
|
||||
```bash
|
||||
ethermintd query slashing signing-info <validator-pubkey>\
|
||||
--chain-id=<chain_id>
|
||||
```
|
||||
|
||||
## Unjail Validator
|
||||
|
||||
When a validator is "jailed" for downtime, you must submit an `Unjail` transaction from the operator account in order to be able to get block proposer rewards again (depends on the zone fee distribution).
|
||||
|
||||
```bash
|
||||
ethermintd tx slashing unjail \
|
||||
--from=<key_name> \
|
||||
--chain-id=<chain_id>
|
||||
```
|
||||
|
||||
## Confirm Your Validator is Running
|
||||
|
||||
Your validator is active if the following command returns anything:
|
||||
|
||||
```bash
|
||||
ethermintd query tendermint-validator-set | grep "$(ethermintd tendermint show-address)"
|
||||
```
|
||||
|
||||
You should now see your validator in one of Ethermint explorers. You are looking for the `bech32` encoded `address` in the `~/.ethermintd/config/priv_validator.json` file.
|
||||
|
||||
::: warning Note
|
||||
To be in the validator set, you need to have more total voting power than the 100th validator.
|
||||
:::
|
||||
|
||||
## Halting Your Validator
|
||||
|
||||
When attempting to perform routine maintenance or planning for an upcoming coordinated
|
||||
upgrade, it can be useful to have your validator systematically and gracefully halt.
|
||||
You can achieve this by either setting the `halt-height` to the height at which
|
||||
you want your node to shutdown or by passing the `--halt-height` flag to `ethermintd`.
|
||||
The node will shutdown with a zero exit code at that given height after committing
|
||||
the block.
|
||||
|
||||
## Common Problems
|
||||
|
||||
### Problem #1: My validator has `voting_power: 0`
|
||||
|
||||
Your validator has become jailed. Validators get jailed, i.e. get removed from the active validator set, if they do not vote on `500` of the last `10000` blocks, or if they double sign.
|
||||
|
||||
If you got jailed for downtime, you can get your voting power back to your validator. First, if `ethermintd` is not running, start it up again:
|
||||
|
||||
```bash
|
||||
ethermintd start
|
||||
```
|
||||
|
||||
Wait for your full node to catch up to the latest block. Then, you can [unjail your validator](#unjail-validator)
|
||||
|
||||
Lastly, check your validator again to see if your voting power is back.
|
||||
|
||||
```bash
|
||||
ethermintd status
|
||||
```
|
||||
|
||||
You may notice that your voting power is less than it used to be. That's because you got slashed for downtime!
|
||||
|
||||
### Problem #2: My node crashes because of `too many open files`
|
||||
|
||||
The default number of files Linux can open (per-process) is `1024`. `ethermintd` is known to open more than `1024` files. This causes the process to crash. A quick fix is to run `ulimit -n 4096` (increase the number of open files allowed) and then restart the process with `ethermintd start`. If you are using `systemd` or another process manager to launch `ethermintd` this may require some configuration at that level. A sample `systemd` file to fix this issue is below:
|
||||
|
||||
```toml
|
||||
# /etc/systemd/system/ethermintd.service
|
||||
[Unit]
|
||||
Description=Ethermint Node
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=ubuntu
|
||||
WorkingDirectory=/home/ubuntu
|
||||
ExecStart=/home/ubuntu/go/bin/ethermintd start
|
||||
Restart=on-failure
|
||||
RestartSec=3
|
||||
LimitNOFILE=4096
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
@ -1,21 +0,0 @@
|
||||
<!--
|
||||
order: false
|
||||
parent:
|
||||
order: 1
|
||||
-->
|
||||
|
||||
# Introduction
|
||||
|
||||
This folder contains introduction material for Ethermint.
|
||||
|
||||
1. [Overview](./overview)
|
||||
1. [Architecture](./architecture)
|
||||
1. [Clients](./clients)
|
||||
1. [Use Cases](./use_cases)
|
||||
1. [Resources](./resources)
|
||||
|
||||
After reading the introduction material, head over to the [basics](../basics/README) to learn more.
|
||||
|
||||
## Next {hide}
|
||||
|
||||
Get an high-level [overview](./overview) of Ethermint {hide}
|
@ -1,42 +0,0 @@
|
||||
<!--
|
||||
order: 2
|
||||
-->
|
||||
|
||||
# Architecture
|
||||
|
||||
Learn how Ethermint's architecture leverages the Cosmos SDK Proof-of-Stake functionality, EVM compatibility and fast-finality from Tendermint Core's BFT consensus. {synopsis}
|
||||
|
||||
## Cosmos SDK
|
||||
|
||||
Ethermint enables the full composability and modularity of the [Cosmos SDK](https://docs.cosmos.network/).
|
||||
|
||||
## Tendermint Core & the Application Blockchain Interface (ABCI)
|
||||
|
||||
Tendermint consists of two chief technical components: a blockchain consensus
|
||||
engine and a generic application interface. The consensus engine, called
|
||||
[Tendermint Core](https://docs.tendermint.com/), ensures that the same transactions are recorded on every machine
|
||||
in the same order. The application interface, called the [Application Blockchain Interface (ABCI)](https://docs.tendermint.com/master/spec/abci/), enables the transactions to be processed in any programming
|
||||
language.
|
||||
|
||||
Tendermint has evolved to be a general purpose blockchain consensus engine that
|
||||
can host arbitrary application states. Since Tendermint can replicate arbitrary
|
||||
applications, it can be used as a plug-and-play replacement for the consensus
|
||||
engines of other blockchains. Ethermint is such an example of an ABCI application
|
||||
replacing Ethereum's PoW via Tendermint's consensus engine.
|
||||
|
||||
Another example of a cryptocurrency application built on Tendermint is the Cosmos
|
||||
network. Tendermint is able to decompose the blockchain design by offering a very
|
||||
simple API (ie. the ABCI) between the application process and consensus process.
|
||||
|
||||
## EVM module
|
||||
|
||||
Ethermint enables EVM compatibility by implementing various components that together support all the EVM state transitions while ensuring the same developer experience as Ethereum:
|
||||
|
||||
- Ethereum transaction format as a Cosmos SDK `Tx` and `Msg` interface
|
||||
- Ethereum's `secp256k1` curve for the Cosmos Keyring
|
||||
- `StateDB` interface for state updates and queries
|
||||
- JSON-RPC client for interacting with the EVM
|
||||
|
||||
## Next {hide}
|
||||
|
||||
Check the available Ethermint [resources](./resources.md) {hide}
|
@ -1,29 +0,0 @@
|
||||
<!--
|
||||
order: 3
|
||||
-->
|
||||
|
||||
# Clients
|
||||
|
||||
Learn about the client supported by your Ethermint node. {synopsis}
|
||||
|
||||
## Client Servers
|
||||
|
||||
The Ethermint client supports both [gRPC endpoints](https://cosmos.network/rpc) from the SDK and [Ethereum's JSON-RPC](https://eth.wiki/json-rpc/API).
|
||||
|
||||
### Cosmos gRPC and Tendermint RPC
|
||||
|
||||
Ethermint exposes gRPC endpoints (and REST) for all the integrated Cosmos-SDK modules. This makes it easier for
|
||||
wallets and block explorers to interact with the proof-of-stake logic and native Cosmos transactions and queries:
|
||||
|
||||
### Ethereum JSON-RPC server
|
||||
|
||||
Ethermint also supports most of the standard web3 [JSON-RPC
|
||||
APIs](./../api/json-rpc/running_server) to connect with existing web3 tooling.
|
||||
|
||||
::: tip
|
||||
See the list of supported JSON-RPC API [endpoints](./../api/json-rpc/endpoints) and [namespaces](./../api/json-rpc/namespaces).
|
||||
:::
|
||||
|
||||
To connect to the JSON-PRC server, start the node with the `--json-rpc.enable=true` flag and define the namespaces that you would like to run using the `--evm.rpc.api` flag (e.g. `"txpool,eth,web3,net,personal"`. Then, you can point any Ethereum development tooling to `http://localhost:8545` or whatever port you choose with the listen address flag (`--json-rpc.address`).
|
||||
|
||||
<!-- TODO: add Rosetta -->
|
@ -1,42 +0,0 @@
|
||||
<!--
|
||||
order: 1
|
||||
-->
|
||||
|
||||
# High-level Overview
|
||||
|
||||
Learn about Ethermint and its primary features. {synopsis}
|
||||
|
||||
## What is Ethermint
|
||||
|
||||
Ethermint is a scalable, high-throughput Proof-of-Stake blockchain that is fully compatible and
|
||||
interoperable with Ethereum. It's built using the [Cosmos SDK](https://github.com/cosmos/cosmos-sdk/) which runs on top of [Tendermint Core](https://github.com/tendermint/tendermint) consensus engine.
|
||||
|
||||
Ethermint allows for running vanilla Ethereum as a [Cosmos](https://cosmos.network/)
|
||||
application-specific blockchain. This allows developers to have all the desired features of
|
||||
Ethereum, while at the same time, benefit from Tendermint’s PoS implementation. Also, because it is
|
||||
built on top of the Cosmos SDK, it will be able to exchange value with the rest of the Cosmos
|
||||
Ecosystem through the Inter Blockchain Communication Protocol (IBC).
|
||||
|
||||
### Features
|
||||
|
||||
Here’s a glance at some of the key features of Ethermint:
|
||||
|
||||
* Web3 and EVM compatibility
|
||||
* High throughput via [Tendermint Core](https://github.com/tendermint/tendermint)
|
||||
* Horizontal scalability via [IBC](https://cosmos.network/ibc)
|
||||
* Fast transaction finality
|
||||
|
||||
Ethermint enables these key features by:
|
||||
|
||||
* Implementing Tendermint Core's Application Blockchain Interface ([ABCI](https://docs.tendermint.com/master/spec/abci/)) to manage the blockchain
|
||||
* Leveraging [modules](https://docs.cosmos.network/master/building-modules/intro.html) and other mechanisms implemented by the [Cosmos SDK](https://docs.cosmos.network/).
|
||||
* Utilizing [`geth`](https://github.com/ethereum/go-ethereum) as a library to avoid code reuse and improve maintainability.
|
||||
* Exposing a fully compatible Web3 [JSON-RPC](./../basic/json_rpc.md) layer for interacting with existing Ethereum clients and tooling ([Metamask](./../guides/metamask.md), [Remix](./../guides/remix.md), [Truffle](./../guides/truffle.md), etc).
|
||||
|
||||
The sum of these features allows developers to leverage existing Ethereum ecosystem tooling and
|
||||
software to seamlessly deploy smart contracts which interact with the rest of the Cosmos
|
||||
[ecosystem](https://cosmos.network/ecosystem)!
|
||||
|
||||
## Next {hide}
|
||||
|
||||
Learn about Ethermint's [architecture](./architecture.md) {hide}
|
@ -1,46 +0,0 @@
|
||||
<!--
|
||||
order: 4
|
||||
-->
|
||||
|
||||
# Resources
|
||||
|
||||
Learn about Ethermint with the list of official resources. {synopsis}
|
||||
|
||||
- Official Documentation: [https://ethermint.dev/](https://ethermint.dev/)
|
||||
- Official Codebase: [https://github.com/tharsis/ethermint](https://github.com/tharsis/ethermint)
|
||||
- Official Website: [https://ethermint.dev/](https://ethermint.dev/)
|
||||
|
||||
## Workshops and Videos
|
||||
|
||||
- [Cosmos Unchained: Ethermint vs Avalanche](https://www.youtube.com/watch?v=WL4vdAR0vSs)
|
||||
- [Code With Us: Ethermint Tutorial - Elizabeth Binks](https://www.youtube.com/watch?v=cH-4Mq-S4BA)
|
||||
- [Ethermint 2.0: Cosmos SDK + EVM - Chris Goes](https://www.youtube.com/watch?v=VCLbS1Oks8A)
|
||||
- [Getting Started with Ethermint - Austin Abell](https://www.youtube.com/watch?v=Rws-QQ_qcfU)
|
||||
- [Ethermint and NFTs - Billy Rennekamp](https://www.youtube.com/watch?v=ReYV5cnSLyE)
|
||||
- [HackAtom India Webinar: Getting Started with Ethermint - Elizabeth Binks](https://www.youtube.com/watch?v=4oCIMFekY_Q)
|
||||
|
||||
## Articles
|
||||
|
||||
### Cosmos Blog
|
||||
|
||||
::: tip
|
||||
Note: most of these articles are outdated as they refer to the previous Ethermint projects (linked below). They are listed here for reference only.
|
||||
:::
|
||||
|
||||
- [Ethermint Supports Web3 Personal API - Colin Schwarz](https://blog.cosmos.network/ethermint-supports-web3-personal-api-556adf75c24e)
|
||||
- [The Road to Ethermint - Colin Schwarz](https://blog.cosmos.network/the-road-to-ethermint-836c0745f535)
|
||||
- [A Beginners Guide to Ethermint - ICF](https://blog.cosmos.network/a-beginners-guide-to-ethermint-38ee15f8a6f4)
|
||||
- [Using Ethermint with Truffle - Billy Rennekamp](https://blog.cosmos.network/using-ethermint-with-truffle-984e6721e30d)
|
||||
- [Light Clients on Ethermint - ICF](https://blog.cosmos.network/light-clients-on-ethermint-9ae1f3c6c4f5)
|
||||
- [Cosmos Fee Token – Introducing the Photon - ICF](https://blog.cosmos.network/cosmos-fee-token-introducing-the-photon-8a62b2f51aa)
|
||||
- [Introducing the Hard Spoon - Chjango Unchained](https://blog.cosmos.network/introducing-the-hard-spoon-4a9288d3f0df)
|
||||
- [Ethermint and NFTs at EthDenver - Tendermint](https://blog.cosmos.network/ethermint-nfts-at-ethdenver-bf32766835b6)
|
||||
|
||||
## Previous Ethermint implementations
|
||||
|
||||
- [Ethermint ABCI:](https://github.com/cosmos/ethermint_abci) This project was the first and original Tendermint ABCI application with EVM support. Not built with Cosmos SDK.
|
||||
- [Ethermint (archive):](https://github.com/tharsis/ethermint-archive) Precursor implementation of the current project, developed by [All in Bits Inc](https://tendermint.com/). It was aiming to implement [Turbo-Geth](https://github.com/ledgerwatch/turbo-geth) as the EVM for scalability improvements.
|
||||
|
||||
## Next {hide}
|
||||
|
||||
Learn how to run an Ethermint [node](./../quickstart/run_node.md) {hide}
|
@ -1,54 +0,0 @@
|
||||
<!--
|
||||
order: 3
|
||||
-->
|
||||
|
||||
# Use Cases
|
||||
|
||||
Check out the 2 use cases for the Ethermint project. {synopsis}
|
||||
|
||||
## Ethermint chain
|
||||
|
||||
The Ethermint blockchain provides Ethereum developers to deploy their smart contracts to the
|
||||
Ethermint EVM and get the benefits of a fast-finality Proof-of-Stake (PoS) chain. Developers will
|
||||
also benefit from highly-reliable clients from testnets can be used to test and deploy their
|
||||
contracts.
|
||||
|
||||
Ethermint will also offer built-in interoperability functionalities with other Cosmos and BFT chains by using [IBC](https://cosmos.network/ibc). Developers can also benefit from using a bridge network to enable interoperability between mainnet Ethereum and Ethermint.
|
||||
|
||||
## EVM module dependency
|
||||
|
||||
The EVM module (aka [x/evm](https://github.com/tharsis/ethermint/tree/main/x/evm)) packaged inside
|
||||
Ethermint can be used separately as its own standalone module. This can be added as a dependency to
|
||||
any Cosmos chain, which will allow for smart contract support.
|
||||
|
||||
Importing EVM module can also enable use cases such as Proof-of-Authority
|
||||
([PoA](https://en.wikipedia.org/wiki/Proof_of_authority)) chains for enterprise and consortium
|
||||
projects. Every chain on Cosmos is an [application-specific
|
||||
blockchain](https://docs.cosmos.network/master/intro/why-app-specific.html) that is customized for
|
||||
the business logic defined by a single application. Thus, by using a predefined validator set and
|
||||
the EVM module as a dependency, enables projects with fast finality, interoperability as well as
|
||||
Proof-of-Stake (PoS) consensus.
|
||||
|
||||
## Trade offs
|
||||
|
||||
Either option above will allow for fast finality, using a PoS consensus engine. Using the EVM module
|
||||
as a dependency will require the importing of the EVM and the maintaining of the chain (including
|
||||
validator sets, code upgrades/conformance, community engagement, incentives, etc), thus it incurs on a
|
||||
higher operation cost. The benefit of importing the EVM module to your chains is that it allows for
|
||||
granular control over the network and chain specific configurations/features that may not be
|
||||
available in the Ethermint chain such as developing a module or importing a third-party one.
|
||||
|
||||
Using Ethermint chain will allow for the direct deployment of smart contracts to the Ethermint
|
||||
network. Utilizing the Ethermint client will defer the chain maintenance to the Ethermint network
|
||||
and allow for the participation in a more mature blockchain. The Ethermint client will also offer
|
||||
(in the near future) IBC compatibility which allows for interoperability between different network.
|
||||
|
||||
| | Ethermint Chain | x/evm dependency |
|
||||
|-----------------------------------------|-----------------|------------------|
|
||||
| Maintenance | Lower | Higher |
|
||||
| Sovereignty (validator, config, params) | Lower | Higher |
|
||||
| Storage requirements | Lower | Higher |
|
||||
|
||||
## Next {hide}
|
||||
|
||||
Read the available Ethermint [resources](./resources.md) {hide}
|
25554
docs/package-lock.json
generated
@ -1,38 +0,0 @@
|
||||
{
|
||||
"name": "docs",
|
||||
"version": "1.0.0",
|
||||
"description": "Ethermint Documentation",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"preserve": "./pre.sh",
|
||||
"serve": "vuepress dev",
|
||||
"build": "vuepress build",
|
||||
"docs:build": "vuepress build docs",
|
||||
"postserve": "./post.sh",
|
||||
"prebuild": "./pre.sh",
|
||||
"postbuild": "./post.sh"
|
||||
},
|
||||
"keywords": [
|
||||
"ethermint",
|
||||
"cosmos",
|
||||
"ethereum",
|
||||
"blockchain",
|
||||
"cryptocurrency",
|
||||
"evm"
|
||||
],
|
||||
"author": "Tharsis",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"entities": "^2.0.3",
|
||||
"markdown-it": "^12.0.6",
|
||||
"markdown-it-katex": "^2.0.3",
|
||||
"vuepress-theme-cosmos": "^1.0.182"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vuepress-plugin-element-tabs": "^0.2.8",
|
||||
"watchpack": "^1.7.2"
|
||||
},
|
||||
"resolutions": {
|
||||
"serialize-javascript": "^4.0.0"
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Modules
|
||||
rm -rf modules
|
12
docs/pre.sh
@ -1,12 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
mkdir -p modules
|
||||
|
||||
for D in ../x/*; do
|
||||
if [ -d "${D}" ]; then
|
||||
rm -rf "modules/$(echo $D | awk -F/ '{print $NF}')"
|
||||
mkdir -p "modules/$(echo $D | awk -F/ '{print $NF}')" && cp -r $D/spec/* "$_"
|
||||
fi
|
||||
done
|
||||
|
||||
cat ../x/README.md | sed 's/\.\/x/\/modules/g' | sed 's/spec\/README.md//g' | sed 's/\.\.\/docs\/building-modules\/README\.md/\/building-modules\/intro\.html/g' > ./modules/README.md
|
@ -1,105 +0,0 @@
|
||||
<!-- This file is auto-generated. Please do not modify it yourself. -->
|
||||
# Protobuf Documentation
|
||||
<a name="top"></a>
|
||||
|
||||
## Table of Contents
|
||||
{{range .Files}}
|
||||
{{$file_name := .Name}}- [{{.Name}}](#{{.Name}})
|
||||
{{- if .Messages }}
|
||||
{{range .Messages}} - [{{.LongName}}](#{{.FullName}})
|
||||
{{end}}
|
||||
{{- end -}}
|
||||
{{- if .Enums }}
|
||||
{{range .Enums}} - [{{.LongName}}](#{{.FullName}})
|
||||
{{end}}
|
||||
{{- end -}}
|
||||
{{- if .Extensions }}
|
||||
{{range .Extensions}} - [File-level Extensions](#{{$file_name}}-extensions)
|
||||
{{end}}
|
||||
{{- end -}}
|
||||
{{- if .Services }}
|
||||
{{range .Services}} - [{{.Name}}](#{{.FullName}})
|
||||
{{end}}
|
||||
{{- end -}}
|
||||
{{end}}
|
||||
- [Scalar Value Types](#scalar-value-types)
|
||||
|
||||
{{range .Files}}
|
||||
{{$file_name := .Name}}
|
||||
<a name="{{.Name}}"></a>
|
||||
<p align="right"><a href="#top">Top</a></p>
|
||||
|
||||
## {{.Name}}
|
||||
{{.Description}}
|
||||
|
||||
{{range .Messages}}
|
||||
<a name="{{.FullName}}"></a>
|
||||
|
||||
### {{.LongName}}
|
||||
{{.Description}}
|
||||
|
||||
{{if .HasFields}}
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
{{range .Fields -}}
|
||||
| `{{.Name}}` | [{{.LongType}}](#{{.FullType}}) | {{.Label}} | {{if (index .Options "deprecated"|default false)}}**Deprecated.** {{end}}{{nobr .Description}}{{if .DefaultValue}} Default: {{.DefaultValue}}{{end}} |
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
{{if .HasExtensions}}
|
||||
| Extension | Type | Base | Number | Description |
|
||||
| --------- | ---- | ---- | ------ | ----------- |
|
||||
{{range .Extensions -}}
|
||||
| `{{.Name}}` | {{.LongType}} | {{.ContainingLongType}} | {{.Number}} | {{nobr .Description}}{{if .DefaultValue}} Default: {{.DefaultValue}}{{end}} |
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
{{end}} <!-- end messages -->
|
||||
|
||||
{{range .Enums}}
|
||||
<a name="{{.FullName}}"></a>
|
||||
|
||||
### {{.LongName}}
|
||||
{{.Description}}
|
||||
|
||||
| Name | Number | Description |
|
||||
| ---- | ------ | ----------- |
|
||||
{{range .Values -}}
|
||||
| {{.Name}} | {{.Number}} | {{nobr .Description}} |
|
||||
{{end}}
|
||||
|
||||
{{end}} <!-- end enums -->
|
||||
|
||||
{{if .HasExtensions}}
|
||||
<a name="{{$file_name}}-extensions"></a>
|
||||
|
||||
### File-level Extensions
|
||||
| Extension | Type | Base | Number | Description |
|
||||
| --------- | ---- | ---- | ------ | ----------- |
|
||||
{{range .Extensions -}}
|
||||
| `{{.Name}}` | {{.LongType}} | {{.ContainingLongType}} | {{.Number}} | {{nobr .Description}}{{if .DefaultValue}} Default: `{{.DefaultValue}}`{{end}} |
|
||||
{{end}}
|
||||
{{end}} <!-- end HasExtensions -->
|
||||
|
||||
{{range .Services}}
|
||||
<a name="{{.FullName}}"></a>
|
||||
|
||||
### {{.Name}}
|
||||
{{.Description}}
|
||||
|
||||
| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint |
|
||||
| ----------- | ------------ | ------------- | ------------| ------- | -------- |
|
||||
{{range .Methods -}}
|
||||
| `{{.Name}}` | [{{.RequestLongType}}](#{{.RequestFullType}}){{if .RequestStreaming}} stream{{end}} | [{{.ResponseLongType}}](#{{.ResponseFullType}}){{if .ResponseStreaming}} stream{{end}} | {{nobr .Description}} | {{with (index .Options "google.api.http")}}{{range .Rules}}{{.Method}}|{{.Pattern}}{{end}}{{end}}|
|
||||
{{end}}
|
||||
{{end}} <!-- end services -->
|
||||
|
||||
{{end}}
|
||||
|
||||
## Scalar Value Types
|
||||
|
||||
| .proto Type | Notes | C++ | Java | Python | Go | C# | PHP | Ruby |
|
||||
| ----------- | ----- | --- | ---- | ------ | -- | -- | --- | ---- |
|
||||
{{range .Scalars -}}
|
||||
| <a name="{{.ProtoType}}" /> {{.ProtoType}} | {{.Notes}} | {{.CppType}} | {{.JavaType}} | {{.PythonType}} | {{.GoType}} | {{.CSharp}} | {{.PhpType}} | {{.RubyType}} |
|
||||
{{end}}
|
@ -1,20 +0,0 @@
|
||||
<!--
|
||||
order: false
|
||||
parent:
|
||||
order: 2
|
||||
-->
|
||||
|
||||
# Quick Start
|
||||
|
||||
This repository contains reference documentation on how to install and run an Ethermint full node.
|
||||
|
||||
1. [Installation](./installation)
|
||||
1. [Build and Configuration](./binary)
|
||||
1. [Run a Node](./run_node)
|
||||
1. [Interacting with the Node](./interact_node)
|
||||
|
||||
After going through the Quick Start contents, head over to the [basics](./../basics/README) to learn more.
|
||||
|
||||
## Next {hide}
|
||||
|
||||
Learn how to [install](./../quickstart/installation) Ethermint {hide}
|
@ -1,194 +0,0 @@
|
||||
<!--
|
||||
order: 2
|
||||
-->
|
||||
|
||||
# `ethermintd`
|
||||
|
||||
`ethermintd` is the all-in-one command-line interface. It supports wallet management, queries and transaction operations {synopsis}
|
||||
|
||||
## Pre-requisite Readings
|
||||
|
||||
- [Installation](./installation.md) {prereq}
|
||||
|
||||
## Build and Configuration
|
||||
|
||||
### Using `ethermintd`
|
||||
|
||||
After you have obtained the latest `ethermintd` binary, run:
|
||||
|
||||
```bash
|
||||
ethermintd [command]
|
||||
```
|
||||
|
||||
Check the version you are running using
|
||||
|
||||
```bash
|
||||
ethermintd version
|
||||
```
|
||||
|
||||
There is also a `-h`, `--help` command available
|
||||
|
||||
```bash
|
||||
ethermintd -h
|
||||
```
|
||||
|
||||
::: tip
|
||||
You can also enable auto-completion with the `ethermintd completion` command. For example, at the start of a bash session, run `. <(ethermintd completion)`, and all `ethermintd` subcommands will be auto-completed.
|
||||
:::
|
||||
|
||||
### Config and data directory
|
||||
|
||||
By default, your config and data are stored in the folder located at the `~/.ethermintd` directory.
|
||||
|
||||
```bash
|
||||
. # ~/.ethermintd
|
||||
├── data/ # Contains the databases used by the node.
|
||||
└── config/
|
||||
├── app.toml # Application-related configuration file.
|
||||
├── config.toml # Tendermint-related configuration file.
|
||||
├── genesis.json # The genesis file.
|
||||
├── node_key.json # Private key to use for node authentication in the p2p protocol.
|
||||
└── priv_validator_key.json # Private key to use as a validator in the consensus protocol.
|
||||
```
|
||||
|
||||
To specify the `ethermintd` config and data storage directory; you can update it using the global flag `--home <directory>`
|
||||
|
||||
### Configuring the Node
|
||||
|
||||
The Cosmos SDK automatically generates two configuration files inside `~/.ethermintd/config`:
|
||||
|
||||
- `config.toml`: used to configure the Tendermint, learn more on [Tendermint's documentation](https://docs.tendermint.com/master/nodes/configuration.html),
|
||||
- `app.toml`: generated by the Cosmos SDK, and used to configure your app, such as state pruning strategies, telemetry, gRPC and REST servers configuration, state sync, JSON-RPC, etc.
|
||||
|
||||
Both files are heavily commented, please refer to them directly to tweak your node.
|
||||
|
||||
One example config to tweak is the `minimum-gas-prices` field inside `app.toml`, which defines the minimum amount the validator node is willing to accept for processing a transaction. It is am anti spam mechanism and it will reject incoming transactions with less than the minimum gas prices.
|
||||
|
||||
If it's empty, make sure to edit the field with some value, for example `10token`, or else the node will halt on startup.
|
||||
|
||||
```toml
|
||||
# The minimum gas prices a validator is willing to accept for processing a
|
||||
# transaction. A transaction's fees must meet the minimum of any denomination
|
||||
# specified in this config (e.g. 0.25token1;0.0001token2).
|
||||
minimum-gas-prices = "0aphoton"
|
||||
```
|
||||
|
||||
### Pruning of State
|
||||
|
||||
There are four strategies for pruning state. These strategies apply only to state and do not apply to block storage.
|
||||
To set pruning, adjust the `pruning` parameter in the `~/.ethermintd/config/app.toml` file.
|
||||
The following pruning state settings are available:
|
||||
|
||||
- `everything`: Prune all saved states other than the current state.
|
||||
- `nothing`: Save all states and delete nothing.
|
||||
- `default`: Save the last 100 states and the state of every 10,000th block.
|
||||
- `custom`: Specify pruning settings with the `pruning-keep-recent`, `pruning-keep-every`, and `pruning-interval` parameters.
|
||||
|
||||
By default, every node is in `default` mode which is the recommended setting for most environments.
|
||||
If you would like to change your nodes pruning strategy then you must do so when the node is initialized. Passing a flag when starting `ethermint` will always override settings in the `app.toml` file, if you would like to change your node to the `everything` mode then you can pass the `---pruning everything` flag when you call `ethermintd start`.
|
||||
|
||||
::: warning
|
||||
**IMPORTANT**:
|
||||
When you are pruning state you will not be able to query the heights that are not in your store.
|
||||
:::
|
||||
|
||||
### Client configuration
|
||||
|
||||
We can view the default client config setting by using `ethermintd config` command:
|
||||
|
||||
```bash
|
||||
ethermintd config
|
||||
{
|
||||
"chain-id": "",
|
||||
"keyring-backend": "os",
|
||||
"output": "text",
|
||||
"node": "tcp://localhost:26657",
|
||||
"broadcast-mode": "sync"
|
||||
}
|
||||
```
|
||||
|
||||
We can make changes to the default settings upon our choices, so it allows users to set the configuration beforehand all at once, so it would be ready with the same config afterward.
|
||||
|
||||
For example, the chain identifier can be changed to `ethermint_9000-1` from a blank name by using:
|
||||
|
||||
```bash
|
||||
ethermintd config "chain-id" ethermint_9000-1
|
||||
ethermintd config
|
||||
{
|
||||
"chain-id": "ethermint_9000-1",
|
||||
"keyring-backend": "os",
|
||||
"output": "text",
|
||||
"node": "tcp://localhost:26657",
|
||||
"broadcast-mode": "sync"
|
||||
}
|
||||
```
|
||||
|
||||
Other values can be changed in the same way.
|
||||
|
||||
Alternatively, we can directly make the changes to the config values in one place at client.toml. It is under the path of `.ethermint/config/client.toml` in the folder where we installed ethermint:
|
||||
|
||||
```toml
|
||||
############################################################################
|
||||
### Client Configuration ###
|
||||
|
||||
############################################################################
|
||||
|
||||
# The network chain ID
|
||||
|
||||
chain-id = "ethermint_9000-1"
|
||||
|
||||
# The keyring's backend, where the keys are stored (os|file|kwallet|pass|test|memory)
|
||||
|
||||
keyring-backend = "os"
|
||||
|
||||
# CLI output format (text|json)
|
||||
|
||||
output = "number"
|
||||
|
||||
# <host>:<port> to Tendermint RPC interface for this chain
|
||||
|
||||
node = "tcp://localhost:26657"
|
||||
|
||||
# Transaction broadcasting mode (sync|async|block)
|
||||
|
||||
broadcast-mode = "sync"
|
||||
```
|
||||
|
||||
After the necessary changes are made in the `client.toml`, then save. For example, if we directly change the chain-id from `ethermint_9000-1` to `etherminttest_9000-1`, and output to number, it would change instantly as shown below.
|
||||
|
||||
```bash
|
||||
ethermintd config
|
||||
{
|
||||
"chain-id": "etherminttest_9000-1",
|
||||
"keyring-backend": "os",
|
||||
"output": "number",
|
||||
"node": "tcp://localhost:26657",
|
||||
"broadcast-mode": "sync"
|
||||
}
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
A list of commonly used flags of `ethermintd` is listed below:
|
||||
|
||||
| Option | Description | Type | Default Value |
|
||||
|---------------------|-------------------------------|--------------|-----------------|
|
||||
| `--chain-id` | Full Chain ID | String | --- |
|
||||
| `--home` | Directory for config and data | string | `~/.ethermintd` |
|
||||
| `--keyring-backend` | Select keyring's backend | os/file/test | os |
|
||||
| `--output` | Output format | string | "text" |
|
||||
|
||||
## Command list
|
||||
|
||||
A list of commonly used `ethermintd` commands. You can obtain the full list by using the `ethermintd -h` command.
|
||||
|
||||
| Command | Description | Subcommands (example) |
|
||||
|--------------|--------------------------|---------------------------------------------------------------------------|
|
||||
| `keys` | Keys management | `list`, `show`, `add`, `add --recover`, `delete` |
|
||||
| `tx` | Transactions subcommands | `bank send`, `ibc-transfer transfer`, `distribution withdraw-all-rewards` |
|
||||
| `query` | Query subcommands | `bank balance`, `staking validators`, `gov proposals` |
|
||||
| `tendermint` | Tendermint subcommands | `show-address`, `show-node-id`, `version` |
|
||||
| `config` | Client configuration | |
|
||||
| `init` | Initialize full node | |
|
||||
| `start` | Run full node | |
|
||||
| `version` | Ethermint version | |
|
@ -1,53 +0,0 @@
|
||||
<!--
|
||||
order: 1
|
||||
-->
|
||||
|
||||
# Installation
|
||||
|
||||
Build and install the Ethermint binaries from source or using Docker. {synopsis}
|
||||
|
||||
## Pre-requisites
|
||||
|
||||
- [Install Go 1.17+](https://golang.org/dl/) {prereq}
|
||||
- [Install jq](https://stedolan.github.io/jq/download/) {prereq}
|
||||
|
||||
## Install Binaries
|
||||
|
||||
### GitHub
|
||||
|
||||
Clone and build Ethermint using `git`:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/tharsis/ethermint.git
|
||||
cd ethermint
|
||||
make install
|
||||
```
|
||||
|
||||
Check that the binaries have been successfully installed:
|
||||
|
||||
```bash
|
||||
ethermintd version
|
||||
```
|
||||
|
||||
### Docker
|
||||
|
||||
You can build Ethermint using Docker by running:
|
||||
|
||||
```bash
|
||||
make docker-build
|
||||
```
|
||||
|
||||
This will install the binaries on the `./build` directory. Now, check that the binaries have been
|
||||
successfully installed:
|
||||
|
||||
```bash
|
||||
ethermintd version
|
||||
```
|
||||
|
||||
### Releases
|
||||
|
||||
You can also download a specific release available on the Ethermint [repository](https://github.com/tharsis/ethermint/releases) or via command line:
|
||||
|
||||
```bash
|
||||
go install github.com/tharsis/ethermint@latest
|
||||
```
|
@ -1,223 +0,0 @@
|
||||
<!--
|
||||
order: 4
|
||||
-->
|
||||
|
||||
# Interacting with the Node
|
||||
|
||||
There are multiple ways to interact with a node: using the CLI, using gRPC or using the REST endpoints. {synopsis}
|
||||
|
||||
## Using the CLI
|
||||
|
||||
Now that your very own node is running, it is time to try sending tokens from the first account you created to a second account. In a new terminal window, start by running the following query command:
|
||||
|
||||
```bash
|
||||
ethermintd query bank balances $MY_VALIDATOR_ADDRESS --chain-id=ethermint_9000-1
|
||||
```
|
||||
|
||||
You should see the current balance of the account you created, equal to the original balance of tokens you granted it minus the amount you delegated via the `gentx`. Now, create a second account:
|
||||
|
||||
```bash
|
||||
ethermintd keys add recipient --keyring-backend=file
|
||||
|
||||
# Put the generated address in a variable for later use.
|
||||
RECIPIENT=$(ethermintd keys show recipient -a --keyring-backend=file)
|
||||
```
|
||||
|
||||
The command above creates a local key-pair that is not yet registered on the chain. An account is created the first time it receives tokens from another account. Now, run the following command to send tokens to the `recipient` account:
|
||||
|
||||
```bash
|
||||
ethermintd tx bank send $MY_VALIDATOR_ADDRESS $RECIPIENT 1000000aphoton --chain-id=ethermint_9000-1 --keyring-backend=file
|
||||
|
||||
# Check that the recipient account did receive the tokens.
|
||||
ethermintd query bank balances $RECIPIENT --chain-id=ethermint_9000-1
|
||||
```
|
||||
|
||||
Finally, delegate some of the stake tokens sent to the `recipient` account to the validator:
|
||||
|
||||
```bash
|
||||
ethermintd tx staking delegate $(ethermintd keys show my_validator --bech val -a --keyring-backend=file) 500aphoton --from=recipient --chain-id=ethermint_9000-1 --keyring-backend=file
|
||||
|
||||
# Query the total delegations to `validator`.
|
||||
ethermintd query staking delegations-to $(ethermintd keys show my_validator --bech val -a --keyring-backend=file) --chain-id=ethermint_9000-1
|
||||
```
|
||||
|
||||
You should see two delegations, the first one made from the `gentx`, and the second one you just performed from the `recipient` account.
|
||||
|
||||
## Using gRPC
|
||||
|
||||
The Protobuf ecosystem developed tools for different use cases, including code-generation from `*.proto` files into various languages. These tools allow the building of clients easily. Often, the client connection (i.e. the transport) can be plugged and replaced very easily. Let's explore one of the most popular transport: gRPC.
|
||||
|
||||
Since the code generation library largely depends on your own tech stack, we will only present three alternatives:
|
||||
|
||||
- `grpcurl` for generic debugging and testing
|
||||
- programmatically via Go
|
||||
- CosmJS for JavaScript/TypeScript developers
|
||||
|
||||
### grpcurl
|
||||
|
||||
[grpcurl](https://github.com/fullstorydev/grpcurl) is like `curl` but for gRPC. It is also available as a Go library, but we will use it only as a CLI command for debugging and testing purposes. Follow the instructions in the previous link to install it.
|
||||
|
||||
Assuming you have a local node running (either a localnet, or connected a live network), you should be able to run the following command to list the Protobuf services available (you can replace `localhost:9000` by the gRPC server endpoint of another node, which is configured under the `grpc.address` field inside [`app.toml`](/run-node.md#configuring-the-node-using-apptoml)):
|
||||
|
||||
```bash
|
||||
grpcurl -plaintext localhost:9090 list
|
||||
```
|
||||
|
||||
You should see a list of gRPC services, like `cosmos.bank.v1beta1.Query`. This is called reflection, which is a Protobuf endpoint returning a description of all available endpoints. Each of these represents a different Protobuf service, and each service exposes multiple RPC methods you can query against.
|
||||
|
||||
In order to get a description of the service you can run the following command:
|
||||
|
||||
```bash
|
||||
# Service we want to inspect
|
||||
grpcurl \
|
||||
localhost:9090 \
|
||||
describe cosmos.bank.v1beta1.Query
|
||||
```
|
||||
|
||||
It's also possible to execute an RPC call to query the node for information:
|
||||
|
||||
```bash
|
||||
grpcurl \
|
||||
-plaintext
|
||||
-d '{"address":"$MY_VALIDATOR"}' \
|
||||
localhost:9090 \
|
||||
cosmos.bank.v1beta1.Query/AllBalances
|
||||
```
|
||||
|
||||
#### Query for historical state using grpcurl
|
||||
|
||||
You may also query for historical data by passing some [gRPC metadata](https://github.com/grpc/grpc-go/blob/master/Documentation/grpc-metadata.md) to the query: the `x-cosmos-block-height` metadata should contain the block to query. Using grpcurl as above, the command looks like:
|
||||
|
||||
```bash
|
||||
grpcurl \
|
||||
-plaintext \
|
||||
-H "x-cosmos-block-height: 279256" \
|
||||
-d '{"address":"$MY_VALIDATOR"}' \
|
||||
localhost:9090 \
|
||||
cosmos.bank.v1beta1.Query/AllBalances
|
||||
```
|
||||
|
||||
Assuming the state at that block has not yet been pruned by the node, this query should return a non-empty response.
|
||||
|
||||
### Programmatically via Go
|
||||
|
||||
The following snippet shows how to query the state using gRPC inside a Go program. The idea is to create a gRPC connection, and use the Protobuf-generated client code to query the gRPC server.
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx"
|
||||
)
|
||||
|
||||
func queryState() error {
|
||||
myAddress, err := sdk.AccAddressFromBech32("eth...")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create a connection to the gRPC server.
|
||||
grpcConn := grpc.Dial(
|
||||
"127.0.0.1:9090", // your gRPC server address.
|
||||
grpc.WithInsecure(), // The SDK doesn't support any transport security mechanism.
|
||||
)
|
||||
defer grpcConn.Close()
|
||||
|
||||
// This creates a gRPC client to query the x/bank service.
|
||||
bankClient := banktypes.NewQueryClient(grpcConn)
|
||||
bankRes, err := bankClient.Balance(
|
||||
context.Background(),
|
||||
&banktypes.QueryBalanceRequest{Address: myAddress, Denom: "eth"},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(bankRes.GetBalance()) // Prints the account balance
|
||||
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
#### Query for historical state using Go
|
||||
|
||||
Querying for historical blocks is done by adding the block height metadata in the gRPC request.
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/metadata"
|
||||
|
||||
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx"
|
||||
)
|
||||
|
||||
func queryState() error {
|
||||
// --snip--
|
||||
|
||||
var header metadata.MD
|
||||
bankRes, err = bankClient.Balance(
|
||||
metadata.AppendToOutgoingContext(context.Background(), grpctypes.GRPCBlockHeightHeader, "12"), // Add metadata to request
|
||||
&banktypes.QueryBalanceRequest{Address: myAddress, Denom: denom},
|
||||
grpc.Header(&header), // Retrieve header from response
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
blockHeight = header.Get(grpctypes.GRPCBlockHeightHeader)
|
||||
|
||||
fmt.Println(blockHeight) // Prints the block height (12)
|
||||
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
### CosmJS
|
||||
|
||||
CosmJS documentation can be found at [https://cosmos.github.io/cosmjs](https://cosmos.github.io/cosmjs). As of January 2021, CosmJS documentation is still work in progress.
|
||||
|
||||
## Using the REST Endpoints
|
||||
|
||||
All gRPC services on the Cosmos SDK are made available for more convenient REST-based queries through gRPC-gateway. The format of the URL path is based on the Protobuf service method's full-qualified name, but may contain small customizations so that final URLs look more idiomatic. For example, the REST endpoint for the `cosmos.bank.v1beta1.Query/AllBalances` method is `GET /cosmos/bank/v1beta1/balances/{address}`. Request arguments are passed as query parameters.
|
||||
|
||||
As a concrete example, the `curl` command to make balances request is:
|
||||
|
||||
```bash
|
||||
curl \
|
||||
-X GET \
|
||||
-H "Content-Type: application/json" \
|
||||
http://localhost:1317/cosmos/bank/v1beta1/balances/$MY_VALIDATOR
|
||||
```
|
||||
|
||||
Make sure to replace `localhost:1317` with the REST endpoint of your node, configured under the `api.address` field.
|
||||
|
||||
The list of all available REST endpoints is available as a Swagger specification file, it can be viewed at `localhost:1317/swagger`. Make sure that the `api.swagger` field is set to true in your [`app.toml`](/run-node.md#configuring-the-node-using-apptoml) file.
|
||||
|
||||
### Query for historical state using REST
|
||||
|
||||
Querying for historical state is done using the HTTP header `x-cosmos-block-height`. For example, a curl command would look like:
|
||||
|
||||
```bash
|
||||
curl \
|
||||
-X GET \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "x-cosmos-block-height: 279256"
|
||||
http://localhost:1317/cosmos/bank/v1beta1/balances/$MY_VALIDATOR
|
||||
```
|
||||
|
||||
Assuming the state at that block has not yet been pruned by the node, this query should return a non-empty response.
|
||||
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
|
||||
[CORS policies](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) are not enabled by default to help with security. If you would like to use the rest-server in a public environment we recommend you provide a reverse proxy, this can be done with [nginx](https://www.nginx.com/). For testing and development purposes there is an `enabled-unsafe-cors` field inside [`app.toml`](/run-node.md#configuring-the-node-using-apptoml).
|
||||
|
||||
## Next {hide}
|
||||
|
||||
Sending transactions using gRPC and REST requires some additional steps: generating the transaction, signing it, and finally broadcasting it. Read about [generating and signing transactions](./txs.md). {hide}
|
@ -1,122 +0,0 @@
|
||||
<!--
|
||||
order: 3
|
||||
-->
|
||||
|
||||
# Run a Node
|
||||
|
||||
Configure and run an Ethermint node {synopsis}
|
||||
|
||||
## Pre-requisite Readings
|
||||
|
||||
- [Installation](./installation.md) {prereq}
|
||||
- [`ethermintd`](./binary.md) {prereq}
|
||||
|
||||
## Automated deployment
|
||||
|
||||
Run the local node by running the `init.sh` script in the base directory of the repository.
|
||||
|
||||
::: warning
|
||||
The script below will remove any pre-existing binaries installed. Use the manual deploy if you want
|
||||
to keep your binaries and configuration files.
|
||||
:::
|
||||
|
||||
```bash
|
||||
./init.sh
|
||||
```
|
||||
|
||||
## Manual deployment
|
||||
|
||||
The instructions for setting up a brand new full node from scratch are the the same as running a
|
||||
[single node local testnet](./../guides/localnet/single_node.md#manual-localnet).
|
||||
|
||||
## Start node
|
||||
|
||||
To start your node, just type:
|
||||
|
||||
```bash
|
||||
ethermintd start --json-rpc.enable=true --json-rpc.api="eth,web3,net"
|
||||
```
|
||||
|
||||
## Key Management
|
||||
|
||||
To run a node with the same key every time: replace `ethermintd keys add $KEY` in `./init.sh` with:
|
||||
|
||||
```bash
|
||||
echo "your mnemonic here" | ethermintd keys add $KEY --recover
|
||||
```
|
||||
|
||||
::: tip
|
||||
Ethermint currently only supports 24 word mnemonics.
|
||||
:::
|
||||
|
||||
You can generate a new key/mnemonic with:
|
||||
|
||||
```bash
|
||||
ethermintd keys add $KEY
|
||||
```
|
||||
|
||||
To export your ethermint key as an Ethereum private key (for use with [Metamask](./../guides/keys-wallets/metamask) for example):
|
||||
|
||||
```bash
|
||||
ethermintd keys unsafe-export-eth-key $KEY
|
||||
```
|
||||
|
||||
For more about the available key commands, use the `--help` flag
|
||||
|
||||
```bash
|
||||
ethermintd keys -h
|
||||
```
|
||||
|
||||
### Keyring backend options
|
||||
|
||||
The instructions above include commands to use `test` as the `keyring-backend`. This is an unsecured
|
||||
keyring that doesn't require entering a password and should not be used in production. Otherwise,
|
||||
Ethermint supports using a file or OS keyring backend for key storage. To create and use a file
|
||||
stored key instead of defaulting to the OS keyring, add the flag `--keyring-backend file` to any
|
||||
relevant command and the password prompt will occur through the command line. This can also be saved
|
||||
as a CLI config option with:
|
||||
|
||||
```bash
|
||||
ethermintd config keyring-backend file
|
||||
```
|
||||
|
||||
:::tip
|
||||
For more information about the Keyring and its backend options, click [here](./../guides/keys-wallets/keyring).
|
||||
:::
|
||||
|
||||
## Clearing data from chain
|
||||
|
||||
### Reset Data
|
||||
|
||||
Alternatively, you can **reset** the blockchain database, remove the node's address book files, and reset the `priv_validator.json` to the genesis state.
|
||||
|
||||
::: danger
|
||||
If you are running a **validator node**, always be careful when doing `ethermintd unsafe-reset-all`. You should never use this command if you are not switching `chain-id`.
|
||||
:::
|
||||
|
||||
::: danger
|
||||
**IMPORTANT**: Make sure that every node has a unique `priv_validator.json`. **Do not** copy the `priv_validator.json` from an old node to multiple new nodes. Running two nodes with the same `priv_validator.json` will cause you to double sign!
|
||||
:::
|
||||
|
||||
First, remove the outdated files and reset the data.
|
||||
|
||||
```bash
|
||||
rm $HOME/.ethermintd/config/addrbook.json $HOME/.ethermintd/config/genesis.json
|
||||
ethermintd unsafe-reset-all
|
||||
```
|
||||
|
||||
Your node is now in a pristine state while keeping the original `priv_validator.json` and `config.toml`. If you had any sentry nodes or full nodes setup before, your node will still try to connect to them, but may fail if they haven't also been upgraded.
|
||||
|
||||
### Delete Data
|
||||
|
||||
Data for the Daemon and CLI binaries should be stored at `~/.ethermintd`, respectively by default. To **delete** the existing binaries and configuration, run:
|
||||
|
||||
```bash
|
||||
rm -rf ~/.ethermintd
|
||||
```
|
||||
|
||||
To clear all data except key storage (if keyring backend chosen) and then you can rerun the full node installation commands from above to start the node again.
|
||||
|
||||
## Next {hide}
|
||||
|
||||
Learn about running a Ethermint [testnet](./testnet.md) {hide}
|
@ -1,13 +0,0 @@
|
||||
<!--
|
||||
order: false
|
||||
parent:
|
||||
order: 5
|
||||
-->
|
||||
|
||||
# Testnet
|
||||
|
||||
This section contains different documents for how to access and join the Ethermint testnets.
|
||||
|
||||
1. [Join Testnet](./join)
|
||||
1. [Faucet](./faucet)
|
||||
1. [Cloud Providers](./cloud_providers)
|
@ -1,79 +0,0 @@
|
||||
<!--
|
||||
order: 3
|
||||
-->
|
||||
|
||||
# Deploy Node on Cloud
|
||||
|
||||
Learn how to deploy a node to different cloud providers. {synopsis}
|
||||
|
||||
## Digital Ocean
|
||||
|
||||
### Account Setup
|
||||
|
||||
Head over to [Digital Ocean](https://www.digitalocean.com/) and create an account.
|
||||
|
||||
DigitalOcean will want a public key that it can place on any Droplets we start, so that we can access them with a key that we know only we have.
|
||||
|
||||
Let's create an SSH keypair now using `ssh-keygen -t rsa -b 4096`
|
||||
|
||||
This will ask you for a file where you want to save the key which you can call something like - `digital-ocean-key`.
|
||||
|
||||
It'll also ask for a passphrase - feel free to set one if you wish or you could leave it empty. If you created it in the same folder as we've been working out of, you'll see two files - one called `digital-ocean-key` and one called `digital-ocean-key.pub` - these are respectively your private and public keys.
|
||||
|
||||
In your DigitalOcean account, on the bottom left hand side, there is a link for `'Security'`. Follow this link, and the next page will have an option to add an SSH key
|
||||
|
||||
Click `'Add an SSH key'` and you'll be presented with a dialog to enter your key. Simply copy the contents of your `digital-ocean-key.pub` into the large text box (you can get the contents printed to the terminal with `cat digital-ocean-key.pub`).
|
||||
|
||||
### Create Droplet
|
||||
|
||||
Once you've added your SSH key. click on the `'Droplets'` link on the left, and then on the next page click `'Create Droplet'`.
|
||||
|
||||
On this page, you'll be presented with a number of options for configuring your DigitalOcean Droplet, including the distribution, the plan, the size/cost per month, region, and authentication. Feel free to choose whichever settings work best for you.
|
||||
|
||||
Under `'Authentication'`, select `'SSH Key'`, and select which keys you would like to use (like the one you created in the last step). You can also name your Droplet if you wish. When you're finished, click `'Create Droplet'` at the bottom.
|
||||
|
||||
Wait a minute for your Droplet to start up. It'll appear under the `'Droplets'` panel with a green dot next to it when it is up and ready. At this point, we're ready to connect to it.
|
||||
|
||||
### Deploy to Droplet
|
||||
|
||||
#### Connect to Droplet
|
||||
|
||||
Click on the started Droplet, and you'll see details about it. At the moment, we're interested in the IP address - this is the address that the Droplet is at on the internet.
|
||||
|
||||
To access it, we'll need to connect to it using our previously created private key. From the same folder as that private key, run:
|
||||
|
||||
```bash
|
||||
ssh -i digital-ocean-key root@<DROPLET_IP_ADDRESS>
|
||||
```
|
||||
|
||||
Now you are connected to the droplet.
|
||||
|
||||
#### Install Ethermint
|
||||
|
||||
Clone and build Ethermint in the droplet using `git`:
|
||||
|
||||
```bash
|
||||
go install https://github.com/tharsis/ethermint.git
|
||||
```
|
||||
|
||||
Check that the binaries have been successfully installed:
|
||||
|
||||
```bash
|
||||
ethermintd -h
|
||||
```
|
||||
|
||||
### Copy the Genesis File
|
||||
|
||||
To connect the node to the existing testnet, fetch the testnet's `genesis.json` file and copy it into the new droplets config directory (i.e `$HOME/.ethermintd/config/genesis.json`).
|
||||
|
||||
To do this ssh into both the testnet droplet and the new node droplet.
|
||||
|
||||
On your local machine copy the genesis.json file from the testnet droplet to the new droplet using:
|
||||
|
||||
```bash
|
||||
scp -3 root@<TESTNET_IP_ADDRESS>:$HOME/.ethermintd/config/genesis.json root@<NODE_IP_ADDRESS>:$HOME/.ethermintd/config/genesis.json
|
||||
```
|
||||
|
||||
### Start the Node
|
||||
|
||||
Once the genesis file is copied over run `ethermind start` inside the node droplet.
|
@ -1,32 +0,0 @@
|
||||
<!--
|
||||
order: 2
|
||||
-->
|
||||
|
||||
# Faucet
|
||||
|
||||
Check how to obtain testnet tokens from the Ethermint faucet website {synopsis}
|
||||
|
||||
## Requesting tokens
|
||||
|
||||
You can request tokens for the testnet by using the Ethermint [faucet](https://ethermint.io/faucet).
|
||||
Simply fill in your address on the input field in bech32 (`ethm1...`) or hex (`0x...`) format.
|
||||
|
||||
::: warning
|
||||
If you use your bech32 address, make sure you input the [account address](./../basics/accounts#addresses-and-public-keys) (`ethm1...`) and **NOT** the validator operator address (`ethmvaloper1...`)
|
||||
:::
|
||||
|
||||
<!-- TODO: update with final website design -->
|
||||
![faucet site](./img/faucet_web_page.png)
|
||||
|
||||
## Rate limits
|
||||
|
||||
To prevent the faucet account from draining the available funds, the Ethermint testnet faucet
|
||||
imposes a maximum number of request for a period of time. By default the faucet service accepts 1
|
||||
request per day per address. All addresses **must** be authenticated using
|
||||
[Auth0](https://auth0.com/) before requesting tokens.
|
||||
|
||||
<!-- TODO: add screenshots of authentication window -->
|
||||
|
||||
## Amount
|
||||
|
||||
For each request, the faucet transfers $1 ~ * ~ 10^{18}$ aphotons (i.e 1 Photon) to the given address.
|
Before Width: | Height: | Size: 90 KiB |
@ -1,105 +0,0 @@
|
||||
<!--
|
||||
order: 1
|
||||
-->
|
||||
|
||||
# Joining a Testnet
|
||||
|
||||
This document outlines the steps to join an existing testnet {synopsis}
|
||||
|
||||
## Install `ethermintd`
|
||||
|
||||
Follow the [installation](./../quickstart/installation) document to install the Ethermint binary `ethermintd`.
|
||||
|
||||
:::warning
|
||||
Make sure you have the right version of `ethermintd` installed
|
||||
:::
|
||||
|
||||
## Initialize Node
|
||||
|
||||
We need to initialize the node to create all the necessary validator and node configuration files:
|
||||
|
||||
```bash
|
||||
ethermintd init <your_custom_moniker>
|
||||
```
|
||||
|
||||
::: danger
|
||||
Monikers can contain only ASCII characters. Using Unicode characters will render your node unreachable.
|
||||
:::
|
||||
|
||||
By default, the `init` command creates your `~/.ethermintd` directory with subfolders `config/` and `data/`.
|
||||
In the `config` directory, the most important files for configuration are `app.toml` and `config.toml`.
|
||||
|
||||
## Genesis & Seeds
|
||||
|
||||
### Copy the Genesis File
|
||||
|
||||
Check the genesis file from the [`testnets`](https://github.com/tharsis/testnets) repository and copy it over to the `config` directory: `~/.ethermintd/config/genesis.json`.
|
||||
|
||||
Then verify the correctness of the genesis configuration file:
|
||||
|
||||
```bash
|
||||
ethermintd validate-genesis
|
||||
```
|
||||
|
||||
### Add Seed Nodes
|
||||
|
||||
Your node needs to know how to find peers. You'll need to add healthy seed nodes to `$HOME/.ethermintd/config/config.toml`. The [`testnets`](https://github.com/tharsis/testnets) repo contains links to some seed nodes.
|
||||
|
||||
Edit the file located in `~/.ethermintd/config/config.toml` and the `seeds` to the following:
|
||||
|
||||
```toml
|
||||
#######################################################
|
||||
### P2P Configuration Options ###
|
||||
#######################################################
|
||||
[p2p]
|
||||
|
||||
# ...
|
||||
|
||||
# Comma separated list of seed nodes to connect to
|
||||
seeds = ""
|
||||
```
|
||||
|
||||
:::tip
|
||||
For more information on seeds and peers, you can the Tendermint [P2P documentation](https://docs.tendermint.com/master/spec/p2p/peer.html).
|
||||
:::
|
||||
|
||||
### Start testnet
|
||||
|
||||
The final step is to [start the nodes](./../quickstart/run_node#start-node). Once enough voting power (+2/3) from the genesis validators is up-and-running, the testnet will start producing blocks.
|
||||
|
||||
```bash
|
||||
ethermintd start
|
||||
```
|
||||
|
||||
## Upgrading Your Node
|
||||
|
||||
> NOTE: These instructions are for full nodes that have ran on previous versions of and would like to upgrade to the latest testnet.
|
||||
|
||||
### Reset Data
|
||||
|
||||
:::warning
|
||||
If the version <new_version> you are upgrading to is not breaking from the previous one, you **should not** reset the data. If this is the case you can skip to [Restart](#restart)
|
||||
:::
|
||||
|
||||
First, remove the outdated files and reset the data.
|
||||
|
||||
```bash
|
||||
rm $HOME/.ethermintd/config/addrbook.json $HOME/.ethermintd/config/genesis.json
|
||||
ethermintd unsafe-reset-all
|
||||
```
|
||||
|
||||
Your node is now in a pristine state while keeping the original `priv_validator.json` and `config.toml`. If you had any sentry nodes or full nodes setup before,
|
||||
your node will still try to connect to them, but may fail if they haven't also
|
||||
been upgraded.
|
||||
|
||||
::: danger Warning
|
||||
Make sure that every node has a unique `priv_validator.json`. Do not copy the `priv_validator.json` from an old node to multiple new nodes. Running two nodes with the same `priv_validator.json` will cause you to double sign.
|
||||
:::
|
||||
|
||||
### Restart
|
||||
|
||||
To restart your node, just type:
|
||||
|
||||
```bash
|
||||
ethermintd start
|
||||
```
|
@ -1,2 +0,0 @@
|
||||
release/v0.5.x v0.5
|
||||
main main
|