├── docs ├── index.md ├── .gitignore ├── introduction │ └── what-is-empowerchain.md ├── README.md ├── package.json └── .vitepress │ └── config.js ├── .gitignore ├── chain ├── .gitignore ├── x │ └── proofofexistence │ │ ├── types │ │ ├── types.go │ │ ├── errors.go │ │ ├── key_stored_proof.go │ │ ├── keys.go │ │ ├── expected_keepers.go │ │ ├── codec.go │ │ ├── genesis.go │ │ ├── params.go │ │ ├── genesis_test.go │ │ ├── message_create_proof.go │ │ ├── message_create_proof_test.go │ │ ├── query.pb.gw.go │ │ ├── params.pb.go │ │ ├── genesis.pb.go │ │ └── proof.pb.go │ │ ├── simulation │ │ ├── simap.go │ │ └── create.go │ │ ├── spec │ │ ├── README.md │ │ ├── 02_state.md │ │ └── 01_concepts.md │ │ ├── keeper │ │ ├── grpc_query.go │ │ ├── msg_server.go │ │ ├── keeper.go │ │ ├── msg_server_test.go │ │ ├── grpc_query_test.go │ │ ├── proof.go │ │ └── proof_test.go │ │ ├── genesis.go │ │ ├── client │ │ └── cli │ │ │ ├── tx.go │ │ │ ├── query.go │ │ │ ├── query_stored_proof.go │ │ │ ├── tx_create.go │ │ │ └── query_stored_proof_test.go │ │ ├── genesis_test.go │ │ ├── module_simulation.go │ │ └── module.go ├── tools │ └── tools.go ├── testutil │ ├── sample │ │ └── sample.go │ ├── keeper │ │ └── proofofexistence.go │ ├── nullify │ │ └── nullify.go │ └── network │ │ └── network.go ├── proto │ └── empowerchain │ │ └── proofofexistence │ │ ├── genesis.proto │ │ ├── tx.proto │ │ ├── proof.proto │ │ └── query.proto ├── scripts │ ├── test │ │ └── smoke.sh │ ├── serve_env.sh │ ├── protocgen.sh │ ├── generate-docs.sh │ └── serve.sh ├── README.md ├── cmd │ └── empowerd │ │ ├── main.go │ │ └── cmd │ │ ├── testnet_test.go │ │ ├── genaccounts_test.go │ │ ├── genaccounts.go │ │ ├── root.go │ │ └── testnet.go ├── app │ ├── genesis.go │ ├── params │ │ ├── config.go │ │ └── encoding.go │ └── export.go ├── Earthfile ├── .golangci.yml └── Makefile ├── Whitepaper.pdf ├── testnets ├── README.md ├── altruistic-1 │ ├── gentx │ │ ├── gentx-example.json │ │ ├── zuka.json │ │ ├── munris-gentx.json │ │ ├── yefu-gentx.json │ │ ├── [NODERS]TEAM.json │ │ ├── gentx-PPNV_Service.json │ │ ├── zenchainlabs-gentx.json │ │ ├── gentx-52450b21f346a4cf76334374c9d8012b2867b842.json │ │ ├── 𝑵𝒐𝒅𝒆𝒔𝑩𝒍𝒐𝒄𝒌𝒔.json │ │ ├── n0ok[MC].json │ │ ├── gentx-Stake-Take.json │ │ ├── polkachu.json │ │ ├── gentx-220fb60b083bc4d443ce2a7a5363f4813dd4aef4.json │ │ ├── gentx-Validatorrun.json │ │ ├── EZStaking.io-gentx.json │ │ ├── gentx-2a2932e780a681ddf980594f7eacf5a33081edaf.json │ │ ├── gentx-4a38efbae54fd1357329bd583186a68ccd6d85f9.json │ │ ├── gentx-bfb56f4cb8361c49a2ac107251f92c0ea5a1c251.json │ │ ├── gentx-56d05d4ae0e1440ad7c68e52cc841c424d59badd.json │ │ ├── gentx-225ad85c594d03942a026b90f4dab43f90230ea0.json │ │ ├── gentx-6a675d4f66bfe049321c3861bcfd19bd09fefbde.json │ │ └── gentx-333de3fc2eba7eead24e0c5f53d665662b2ba001.json │ ├── gentx-checker.js │ └── README.md └── gentx-RuesValidator.json ├── .github └── workflows │ ├── lint.yml │ ├── test.yml │ ├── build.yml │ ├── testnets.yml │ └── codeql-analysis.yml └── README.md /docs/index.md: -------------------------------------------------------------------------------- 1 | # EmpowerChain Docs 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vscode/ 3 | .DS_Store -------------------------------------------------------------------------------- /chain/.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | release/ 3 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .vite 3 | dist -------------------------------------------------------------------------------- /chain/x/proofofexistence/types/types.go: -------------------------------------------------------------------------------- 1 | package types 2 | -------------------------------------------------------------------------------- /docs/introduction/what-is-empowerchain.md: -------------------------------------------------------------------------------- 1 | # What is EmpowerChain? 2 | 3 | TODO -------------------------------------------------------------------------------- /Whitepaper.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruesandora/empowerchain-1/HEAD/Whitepaper.pdf -------------------------------------------------------------------------------- /testnets/README.md: -------------------------------------------------------------------------------- 1 | # testnets 2 | ![testnets](https://user-images.githubusercontent.com/104348282/192093481-8f43d091-375a-4529-a970-4eb80b9e0e16.png) 3 | -------------------------------------------------------------------------------- /chain/tools/tools.go: -------------------------------------------------------------------------------- 1 | //go:build tools 2 | // +build tools 3 | 4 | // This file uses the recommended method for tracking developer tools in a Go 5 | // module. 6 | // 7 | // REF: https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module 8 | package tools 9 | 10 | import ( 11 | _ "github.com/golangci/golangci-lint/cmd/golangci-lint" 12 | ) 13 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # EmpowerChain docs 2 | 3 | The EmpowerChain docs are located here. 4 | 5 | The docs are written in markdown and rendered using Vitepress. 6 | 7 | ### Run doc site locally 8 | 9 | ```shell 10 | $ yarn docs:dev 11 | ``` 12 | 13 | ### Build 14 | 15 | Built docs are located in `docs/.vitepress/dist` 16 | 17 | ```shell 18 | $ yarn docs:build 19 | ``` 20 | -------------------------------------------------------------------------------- /chain/testutil/sample/sample.go: -------------------------------------------------------------------------------- 1 | package sample 2 | 3 | import ( 4 | "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" 5 | sdk "github.com/cosmos/cosmos-sdk/types" 6 | ) 7 | 8 | // AccAddress returns a sample account address 9 | func AccAddress() string { 10 | pk := ed25519.GenPrivKey().PubKey() 11 | addr := pk.Address() 12 | return sdk.AccAddress(addr).String() 13 | } 14 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/types/errors.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | // DONTCOVER 4 | 5 | import ( 6 | sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" 7 | ) 8 | 9 | // x/proofofexistence module sentinel errors 10 | var ( 11 | ErrInvalidHash = sdkerrors.Register(ModuleName, 2, "invalid hash") 12 | ErrHashExists = sdkerrors.Register(ModuleName, 3, "hash already registered") 13 | ) 14 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "empowerchain-docs", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "docs:dev": "vitepress dev .", 8 | "docs:build": "vitepress build .", 9 | "docs:serve": "vitepress serve ." 10 | }, 11 | "devDependencies": { 12 | "vitepress": "^1.0.0-alpha.13", 13 | "vue": "^3.2.39" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /docs/.vitepress/config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | title: 'EmpowerChain Docs', 3 | description: 'Documentation for everything EmpowerChain.', 4 | themeConfig: { 5 | sidebar: [ 6 | { 7 | text: 'Introduction', 8 | items: [ 9 | { text: 'What is EmpowerChain?', link: '/introduction/what-is-empowerchain' }, 10 | ] 11 | }, 12 | ] 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /chain/proto/empowerchain/proofofexistence/genesis.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package empowerchain.empowerchain.proofofexistence; 3 | 4 | import "gogoproto/gogo.proto"; 5 | import "empowerchain/proofofexistence/proof.proto"; 6 | 7 | option go_package = "github.com/empowerchain/empowerchain/x/proofofexistence/types"; 8 | 9 | // GenesisState defines the proofofexistence module's genesis state. 10 | message GenesisState { 11 | repeated Proof proofList = 1 [(gogoproto.nullable) = false]; 12 | } 13 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: "Lint" 2 | 3 | on: 4 | workflow_dispatch: 5 | pull_request: 6 | push: 7 | branches: 8 | - main 9 | paths: 10 | - 'chain/**' 11 | 12 | jobs: 13 | lint: 14 | name: Lint 15 | runs-on: ubuntu-20.04 16 | steps: 17 | - uses: actions/checkout@v3 18 | 19 | - uses: earthly/actions/setup-earthly@v1 20 | with: 21 | version: v0.6.22 22 | 23 | - run: earthly --ci +lint 24 | working-directory: ./chain 25 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/simulation/simap.go: -------------------------------------------------------------------------------- 1 | package simulation 2 | 3 | import ( 4 | sdk "github.com/cosmos/cosmos-sdk/types" 5 | simtypes "github.com/cosmos/cosmos-sdk/types/simulation" 6 | ) 7 | 8 | // FindAccount find a specific address from an account list 9 | func FindAccount(accs []simtypes.Account, address string) (simtypes.Account, bool) { 10 | creator, err := sdk.AccAddressFromBech32(address) 11 | if err != nil { 12 | panic(err) 13 | } 14 | return simtypes.FindAccount(accs, creator) 15 | } 16 | -------------------------------------------------------------------------------- /chain/scripts/test/smoke.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | make serve 5 | 6 | source scripts/serve_env.sh 7 | 8 | empowerd --home $CHAIN_DIR --node tcp://:$RPC_PORT tx proofofexistence create ipZS+n+DPPkPp+mQRdHJLBlqvQGsevJhXhMHgOT/iO0= --from alice --keyring-backend test --chain-id $CHAIN_ID -b block --yes 9 | empowerd --home $CHAIN_DIR --node tcp://:$RPC_PORT q proofofexistence show-stored-proof ipZS+n+DPPkPp+mQRdHJLBlqvQGsevJhXhMHgOT/iO0= 10 | 11 | echo "Tests completed successfully!" 12 | 13 | make kill 14 | 15 | echo "Serve killed" -------------------------------------------------------------------------------- /chain/x/proofofexistence/types/key_stored_proof.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import "encoding/binary" 4 | 5 | var _ binary.ByteOrder 6 | 7 | const ( 8 | // ProofKeyPrefix is the prefix to retrieve all Proof 9 | ProofKeyPrefix = "Proof/value/" 10 | ) 11 | 12 | // ProofKey returns the store key to retrieve a Proof from the index fields 13 | func ProofKey( 14 | hash string, 15 | ) []byte { 16 | var key []byte 17 | 18 | hashBytes := []byte(hash) 19 | key = append(key, hashBytes...) 20 | key = append(key, []byte("/")...) 21 | 22 | return key 23 | } 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EmpowerChain 2 | 3 | This is where the code for anything related to EmpowerChain is located. Documentation is being built right now. 4 | 5 | In the meantime, take a look at our [whitepaper](https://github.com/empowerchain/empowerchain/blob/main/Whitepaper.pdf), [website](https://empowerchain.io) and [@empowerchain_io on twitter](https://twitter.com/empowerchain_io). 6 | 7 | # ./chain 8 | 9 | In the chain folder is where the actual blockchain-code is located. 10 | 11 | # ./docs 12 | 13 | In the docs folder you will find the documentation and doc site for https://docs.empowerchain.io -------------------------------------------------------------------------------- /chain/x/proofofexistence/types/keys.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | const ( 4 | // ModuleName defines the module name 5 | ModuleName = "proofofexistence" 6 | 7 | // StoreKey defines the primary module store key 8 | StoreKey = ModuleName 9 | 10 | // RouterKey is the message route for slashing 11 | RouterKey = ModuleName 12 | 13 | // QuerierRoute defines the module's query routing key 14 | QuerierRoute = ModuleName 15 | 16 | // MemStoreKey defines the in-memory store key 17 | MemStoreKey = "mem_proofofexistence" 18 | ) 19 | 20 | func KeyPrefix(p string) []byte { 21 | return []byte(p) 22 | } 23 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: "Test" 2 | 3 | on: 4 | workflow_dispatch: 5 | pull_request: 6 | push: 7 | branches: 8 | - main 9 | paths: 10 | - 'chain/**' 11 | 12 | jobs: 13 | test: 14 | name: Test EmpowerChain 15 | runs-on: ubuntu-20.04 16 | steps: 17 | - uses: actions/checkout@v3 18 | 19 | - uses: earthly/actions/setup-earthly@v1 20 | with: 21 | version: v0.6.22 22 | 23 | - run: earthly --ci +test 24 | working-directory: ./chain 25 | 26 | - run: earthly --ci +smoketest 27 | working-directory: ./chain 28 | -------------------------------------------------------------------------------- /chain/proto/empowerchain/proofofexistence/tx.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package empowerchain.empowerchain.proofofexistence; 3 | 4 | option go_package = "github.com/empowerchain/empowerchain/x/proofofexistence/types"; 5 | 6 | // Msg defines the Msg service. 7 | service Msg { 8 | rpc CreateProof(MsgCreateProof) returns (MsgCreateProofResponse); 9 | } 10 | 11 | message MsgCreateProof { 12 | // reporter is the address of the signer 13 | string reporter = 1; 14 | 15 | // hash is the SHA-256 hash as a Base64 encoded string 16 | string hash = 2; 17 | } 18 | 19 | message MsgCreateProofResponse { 20 | } -------------------------------------------------------------------------------- /chain/x/proofofexistence/spec/README.md: -------------------------------------------------------------------------------- 1 | # `proofofexistence` 2 | 3 | ## Abstract 4 | 5 | This document specifies the proofofexistence module in EmpowerChain. 6 | 7 | The module enables uploading a proof of existence of any document or piece of data, by hashing the data and uploading it to be stored on-chain. 8 | The combination of Blockchain immutability and hashing integrity allows for anyone to prove later that a piece of data: 9 | 1. The data existed at least at the time it was added on-chain 10 | 2. It has not changed since then 11 | 12 | ## Contents 13 | 14 | 1. **[Concepts](01_concepts.md)** 15 | 2. **[State](02_state.md)** -------------------------------------------------------------------------------- /chain/README.md: -------------------------------------------------------------------------------- 1 | ## Development 2 | 3 | ### Requirements 4 | 5 | - Go 1.18 6 | 7 | ### Build 8 | 9 | To run a basic build: 10 | ```shell 11 | $ make build 12 | ``` 13 | 14 | To install the `empowerd` executable: 15 | ```shell 16 | $ make install 17 | ``` 18 | 19 | ### Run locally 20 | 21 | To spin up a local chain: 22 | ```shell 23 | $ make serve 24 | ``` 25 | 26 | To kill the running instance: 27 | ```shell 28 | $ make kill 29 | ``` 30 | 31 | ### Test 32 | 33 | To run unit tests: 34 | ```shell 35 | $ make test 36 | ``` 37 | 38 | To run a basic smoke test (spins up the chain and runs a couple of commands against it) 39 | ```shell 40 | $ make smoketest 41 | ``` -------------------------------------------------------------------------------- /chain/cmd/empowerd/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/cosmos/cosmos-sdk/server" 7 | "github.com/empowerchain/empowerchain/app" 8 | "github.com/empowerchain/empowerchain/app/params" 9 | "github.com/empowerchain/empowerchain/cmd/empowerd/cmd" 10 | 11 | svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" 12 | ) 13 | 14 | func main() { 15 | params.SetAddressPrefixes() 16 | 17 | rootCmd, _ := cmd.NewRootCmd() 18 | 19 | if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil { 20 | switch e := err.(type) { 21 | case server.ErrorCode: 22 | os.Exit(e.Code) 23 | 24 | default: 25 | os.Exit(1) 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/types/expected_keepers.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | sdk "github.com/cosmos/cosmos-sdk/types" 5 | "github.com/cosmos/cosmos-sdk/x/auth/types" 6 | ) 7 | 8 | // AccountKeeper defines the expected account keeper used for simulations (noalias) 9 | type AccountKeeper interface { 10 | GetAccount(ctx sdk.Context, addr sdk.AccAddress) types.AccountI 11 | // Methods imported from account should be defined here 12 | } 13 | 14 | // BankKeeper defines the expected interface needed to retrieve account balances. 15 | type BankKeeper interface { 16 | SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins 17 | // Methods imported from bank should be defined here 18 | } 19 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/types/codec.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "github.com/cosmos/cosmos-sdk/codec" 5 | cdctypes "github.com/cosmos/cosmos-sdk/codec/types" 6 | sdk "github.com/cosmos/cosmos-sdk/types" 7 | "github.com/cosmos/cosmos-sdk/types/msgservice" 8 | ) 9 | 10 | func RegisterCodec(cdc *codec.LegacyAmino) { 11 | cdc.RegisterConcrete(&MsgCreateProof{}, "proofofexistence/CreateProof", nil) 12 | } 13 | 14 | func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { 15 | registry.RegisterImplementations((*sdk.Msg)(nil), 16 | &MsgCreateProof{}, 17 | ) 18 | 19 | msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) 20 | } 21 | 22 | var ( 23 | Amino = codec.NewLegacyAmino() 24 | ModuleCdc = codec.NewProtoCodec(cdctypes.NewInterfaceRegistry()) 25 | ) 26 | -------------------------------------------------------------------------------- /chain/scripts/serve_env.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | BINARY=empowerd 4 | CHAIN_ID=empowerchain-local-1 5 | HOME=/tmp 6 | CHAIN_DIR=$HOME/$CHAIN_ID 7 | LOG_FILE_PATH=$CHAIN_DIR/$CHAIN_ID.log 8 | ALICE_MNEMONIC="clock post desk civil pottery foster expand merit dash seminar song memory figure uniform spice circle try happy obvious trash crime hybrid hood cushion" 9 | BOB_MNEMONIC="angry twist harsh drastic left brass behave host shove marriage fall update business leg direct reward object ugly security warm tuna model broccoli choice" 10 | VALIDATOR_MNEMONIC="banner spread envelope side kite person disagree path silver will brother under couch edit food venture squirrel civil budget number acquire point work mass" 11 | P2P_PORT=16656 12 | RPC_PORT=16657 13 | REST_PORT=1316 14 | ROSETTA_PORT=8080 15 | GRPC_PORT=8090 16 | GRPC_WEB=8091 -------------------------------------------------------------------------------- /chain/app/genesis.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/cosmos/cosmos-sdk/codec" 7 | ) 8 | 9 | // The genesis state of the blockchain is represented here as a map of raw json 10 | // messages key'd by a identifier string. 11 | // The identifier is used to determine which module genesis information belongs 12 | // to so it may be appropriately routed during init chain. 13 | // Within this application default genesis information is retrieved from 14 | // the ModuleBasicManager which populates json from each BasicModule 15 | // object provided to it during init. 16 | type GenesisState map[string]json.RawMessage 17 | 18 | // NewDefaultGenesisState generates the default state for the application. 19 | func NewDefaultGenesisState(cdc codec.JSONCodec) GenesisState { 20 | return ModuleBasics.DefaultGenesis(cdc) 21 | } 22 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/spec/02_state.md: -------------------------------------------------------------------------------- 1 | # State 2 | 3 | The `proofofexistence` module keeps track of the proofs of existence uploaded to the chain. 4 | 5 | ## Proof 6 | 7 | A Proof consists of a hash, a timestamp and a reporter address. This gives you enough information to prove that 8 | a hash existed at a specific point in time. You can prove you knew the hash at said time (if you can also prove 9 | that you are the owner of the reporter address). 10 | 11 | - Proof `0x01 | hash | -> ProtocolBuffer(Proof)` 12 | 13 | The hash is not made on-chain to avoid the privacy issues that would entail. Instead, the hash is just checked to 14 | be a valid SHA-256 hash. 15 | 16 | The timestamp is simply taken from current block's header (i.e. the time of the block). 17 | 18 | The reporter address is the address of the account that is creating the transaction. -------------------------------------------------------------------------------- /chain/proto/empowerchain/proofofexistence/proof.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package empowerchain.empowerchain.proofofexistence; 3 | 4 | import "google/protobuf/timestamp.proto"; 5 | import "gogoproto/gogo.proto"; 6 | 7 | option go_package = "github.com/empowerchain/empowerchain/x/proofofexistence/types"; 8 | 9 | message Proof { 10 | // Hash is the SHA-256 hash of the data of which is being made a proof for. 11 | // The hash needs to be sent as a Base64 encoded string. 12 | string hash = 1; 13 | 14 | // Timestamp is the time the proof was added on-chain (block time) 15 | google.protobuf.Timestamp timestamp = 2 [ 16 | (gogoproto.stdtime) = true, 17 | (gogoproto.nullable) = false, 18 | (gogoproto.moretags) = "yaml:\"timestamp\"" 19 | ]; 20 | 21 | // Reporter is the account address that created the proof 22 | string reporter = 3; 23 | } 24 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/keeper/grpc_query.go: -------------------------------------------------------------------------------- 1 | package keeper 2 | 3 | import ( 4 | "context" 5 | 6 | sdk "github.com/cosmos/cosmos-sdk/types" 7 | "github.com/empowerchain/empowerchain/x/proofofexistence/types" 8 | "google.golang.org/grpc/codes" 9 | "google.golang.org/grpc/status" 10 | ) 11 | 12 | type Querier struct { 13 | Keeper 14 | } 15 | 16 | var _ types.QueryServer = Querier{} 17 | 18 | func (k Querier) Proof(c context.Context, req *types.QueryGetProofRequest) (*types.QueryGetProofResponse, error) { 19 | if req == nil { 20 | return nil, status.Error(codes.InvalidArgument, "invalid request") 21 | } 22 | ctx := sdk.UnwrapSDKContext(c) 23 | 24 | val, found := k.GetProof( 25 | ctx, 26 | req.Hash, 27 | ) 28 | if !found { 29 | return nil, status.Error(codes.NotFound, "not found") 30 | } 31 | 32 | return &types.QueryGetProofResponse{Proof: val}, nil 33 | } 34 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/keeper/msg_server.go: -------------------------------------------------------------------------------- 1 | package keeper 2 | 3 | import ( 4 | "context" 5 | 6 | sdk "github.com/cosmos/cosmos-sdk/types" 7 | "github.com/empowerchain/empowerchain/x/proofofexistence/types" 8 | ) 9 | 10 | type msgServer struct { 11 | Keeper 12 | } 13 | 14 | // NewMsgServerImpl returns an implementation of the MsgServer interface 15 | // for the provided Keeper. 16 | func NewMsgServerImpl(keeper Keeper) types.MsgServer { 17 | return &msgServer{Keeper: keeper} 18 | } 19 | 20 | var _ types.MsgServer = msgServer{} 21 | 22 | func (k msgServer) CreateProof(goCtx context.Context, msg *types.MsgCreateProof) (*types.MsgCreateProofResponse, error) { 23 | ctx := sdk.UnwrapSDKContext(goCtx) 24 | 25 | if err := k.CreateNewProof(ctx, msg.Hash, msg.Reporter); err != nil { 26 | return nil, err 27 | } 28 | 29 | return &types.MsgCreateProofResponse{}, nil 30 | } 31 | -------------------------------------------------------------------------------- /chain/proto/empowerchain/proofofexistence/query.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package empowerchain.empowerchain.proofofexistence; 3 | 4 | import "gogoproto/gogo.proto"; 5 | import "google/api/annotations.proto"; 6 | import "cosmos/base/query/v1beta1/pagination.proto"; 7 | import "empowerchain/proofofexistence/proof.proto"; 8 | 9 | option go_package = "github.com/empowerchain/empowerchain/x/proofofexistence/types"; 10 | 11 | // Query defines the gRPC querier service. 12 | service Query { 13 | // Queries a Proof by hash. 14 | rpc Proof(QueryGetProofRequest) returns (QueryGetProofResponse) { 15 | option (google.api.http).get = "/empowerchain/empowerchain/proofofexistence/proof/{hash}"; 16 | } 17 | } 18 | 19 | message QueryGetProofRequest { 20 | string hash = 1; 21 | 22 | } 23 | 24 | message QueryGetProofResponse { 25 | Proof proof = 1 [(gogoproto.nullable) = false]; 26 | } 27 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/types/genesis.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | // DefaultIndex is the default capability global index 8 | const DefaultIndex uint64 = 1 9 | 10 | // DefaultGenesis returns the default Capability genesis state 11 | func DefaultGenesis() *GenesisState { 12 | return &GenesisState{ 13 | ProofList: []Proof{}, 14 | } 15 | } 16 | 17 | // Validate performs basic genesis state validation returning an error upon any 18 | // failure. 19 | func (gs GenesisState) Validate() error { 20 | // Check for duplicated index in proof 21 | proofIndexMap := make(map[string]struct{}) 22 | 23 | for _, elem := range gs.ProofList { 24 | index := string(ProofKey(elem.Hash)) 25 | if _, ok := proofIndexMap[index]; ok { 26 | return fmt.Errorf("duplicated index for proof") 27 | } 28 | proofIndexMap[index] = struct{}{} 29 | } 30 | 31 | return nil 32 | } 33 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/genesis.go: -------------------------------------------------------------------------------- 1 | package proofofexistence 2 | 3 | import ( 4 | sdk "github.com/cosmos/cosmos-sdk/types" 5 | "github.com/empowerchain/empowerchain/x/proofofexistence/keeper" 6 | "github.com/empowerchain/empowerchain/x/proofofexistence/types" 7 | ) 8 | 9 | // InitGenesis initializes the capability module's state from a provided genesis 10 | // state. 11 | func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) { 12 | // Set all the proof 13 | for _, elem := range genState.ProofList { 14 | if err := k.SetProof(ctx, elem); err != nil { 15 | panic(err) 16 | } 17 | } 18 | } 19 | 20 | // ExportGenesis returns the capability module's exported genesis. 21 | func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { 22 | genesis := types.DefaultGenesis() 23 | 24 | genesis.ProofList = k.GetAllProof(ctx) 25 | 26 | return genesis 27 | } 28 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/keeper/keeper.go: -------------------------------------------------------------------------------- 1 | package keeper 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/tendermint/tendermint/libs/log" 7 | 8 | "github.com/cosmos/cosmos-sdk/codec" 9 | storetypes "github.com/cosmos/cosmos-sdk/store/types" 10 | sdk "github.com/cosmos/cosmos-sdk/types" 11 | "github.com/empowerchain/empowerchain/x/proofofexistence/types" 12 | ) 13 | 14 | type ( 15 | Keeper struct { 16 | cdc codec.BinaryCodec 17 | storeKey storetypes.StoreKey 18 | memKey storetypes.StoreKey 19 | } 20 | ) 21 | 22 | func NewKeeper( 23 | cdc codec.BinaryCodec, 24 | storeKey, 25 | memKey storetypes.StoreKey, 26 | 27 | ) *Keeper { 28 | return &Keeper{ 29 | cdc: cdc, 30 | storeKey: storeKey, 31 | memKey: memKey, 32 | } 33 | } 34 | 35 | func (k Keeper) Logger(ctx sdk.Context) log.Logger { 36 | return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) 37 | } 38 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/client/cli/tx.go: -------------------------------------------------------------------------------- 1 | package cli 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | 7 | "github.com/spf13/cobra" 8 | 9 | "github.com/cosmos/cosmos-sdk/client" 10 | // "github.com/cosmos/cosmos-sdk/client/flags" 11 | "github.com/empowerchain/empowerchain/x/proofofexistence/types" 12 | ) 13 | 14 | var ( 15 | DefaultRelativePacketTimeoutTimestamp = uint64((time.Duration(10) * time.Minute).Nanoseconds()) 16 | ) 17 | 18 | // GetTxCmd returns the transaction commands for this module 19 | func GetTxCmd() *cobra.Command { 20 | cmd := &cobra.Command{ 21 | Use: types.ModuleName, 22 | Short: fmt.Sprintf("%s transactions subcommands", types.ModuleName), 23 | DisableFlagParsing: true, 24 | SuggestionsMinimumDistance: 2, 25 | RunE: client.ValidateCmd, 26 | } 27 | 28 | cmd.AddCommand(CmdCreate()) 29 | 30 | return cmd 31 | } 32 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: "Build" 2 | 3 | on: 4 | workflow_dispatch: 5 | pull_request: 6 | push: 7 | branches: 8 | - main 9 | paths: 10 | - 'chain/**' 11 | 12 | jobs: 13 | build: 14 | name: Build EmpowerChain 15 | runs-on: ubuntu-20.04 16 | strategy: 17 | matrix: 18 | arch: [amd64] 19 | targetos: [darwin, linux] 20 | include: 21 | - targetos: darwin 22 | arch: arm64 23 | steps: 24 | - uses: actions/checkout@v3 25 | 26 | - uses: earthly/actions/setup-earthly@v1 27 | with: 28 | version: v0.6.22 29 | 30 | - run: earthly --ci --output +build 31 | working-directory: ./chain 32 | 33 | - uses: actions/upload-artifact@v3 34 | with: 35 | name: empowerd ${{ matrix.targetos }} ${{ matrix.arch }} 36 | path: chain/build/empowerd 37 | if-no-files-found: error 38 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/client/cli/query.go: -------------------------------------------------------------------------------- 1 | package cli 2 | 3 | import ( 4 | "fmt" 5 | // "strings" 6 | 7 | "github.com/spf13/cobra" 8 | 9 | "github.com/cosmos/cosmos-sdk/client" 10 | // "github.com/cosmos/cosmos-sdk/client/flags" 11 | // sdk "github.com/cosmos/cosmos-sdk/types" 12 | 13 | "github.com/empowerchain/empowerchain/x/proofofexistence/types" 14 | ) 15 | 16 | // GetQueryCmd returns the cli query commands for this module 17 | func GetQueryCmd(queryRoute string) *cobra.Command { 18 | // Group proofofexistence queries under a subcommand 19 | cmd := &cobra.Command{ 20 | Use: types.ModuleName, 21 | Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), 22 | DisableFlagParsing: true, 23 | SuggestionsMinimumDistance: 2, 24 | RunE: client.ValidateCmd, 25 | } 26 | 27 | cmd.AddCommand(CmdShowProof()) 28 | 29 | return cmd 30 | } 31 | -------------------------------------------------------------------------------- /chain/app/params/config.go: -------------------------------------------------------------------------------- 1 | package params 2 | 3 | import ( 4 | sdk "github.com/cosmos/cosmos-sdk/types" 5 | ) 6 | 7 | const ( 8 | HumanCoinUnit = "mpwr" 9 | BaseCoinUnit = "umpwr" 10 | OsmoExponent = 6 11 | 12 | DefaultBondDenom = BaseCoinUnit 13 | 14 | Bech32AccountPrefix = "empower" 15 | ) 16 | 17 | func SetAddressPrefixes() { 18 | accountPubKeyPrefix := Bech32AccountPrefix + "pub" 19 | validatorAddressPrefix := Bech32AccountPrefix + "valoper" 20 | validatorPubKeyPrefix := Bech32AccountPrefix + "valoperpub" 21 | consNodeAddressPrefix := Bech32AccountPrefix + "valcons" 22 | consNodePubKeyPrefix := Bech32AccountPrefix + "valconspub" 23 | 24 | config := sdk.GetConfig() 25 | config.SetBech32PrefixForAccount(Bech32AccountPrefix, accountPubKeyPrefix) 26 | config.SetBech32PrefixForValidator(validatorAddressPrefix, validatorPubKeyPrefix) 27 | config.SetBech32PrefixForConsensusNode(consNodeAddressPrefix, consNodePubKeyPrefix) 28 | config.Seal() 29 | } 30 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/keeper/msg_server_test.go: -------------------------------------------------------------------------------- 1 | package keeper_test 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | sdk "github.com/cosmos/cosmos-sdk/types" 8 | keepertest "github.com/empowerchain/empowerchain/testutil/keeper" 9 | "github.com/empowerchain/empowerchain/x/proofofexistence/keeper" 10 | "github.com/empowerchain/empowerchain/x/proofofexistence/types" 11 | "github.com/stretchr/testify/require" 12 | ) 13 | 14 | func setupMsgServer(t testing.TB) (types.MsgServer, keeper.Keeper, context.Context) { 15 | k, ctx := keepertest.ProofofexistenceKeeper(t) 16 | return keeper.NewMsgServerImpl(*k), *k, sdk.WrapSDKContext(ctx) 17 | } 18 | 19 | func TestCreateProof(t *testing.T) { 20 | msgServer, _, ctx := setupMsgServer(t) 21 | _, err := msgServer.CreateProof(ctx, &types.MsgCreateProof{ 22 | Reporter: "empower10m8qakrveaxvcr5085c73de30ff5umdem2ua5u", 23 | Hash: "cZiMTY4IA7pFGfCyhkwTMcFKGJC/hpTiUTeRd7/ttcM=", 24 | }) 25 | require.NoError(t, err) 26 | } 27 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/client/cli/query_stored_proof.go: -------------------------------------------------------------------------------- 1 | package cli 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/cosmos/cosmos-sdk/client" 7 | "github.com/cosmos/cosmos-sdk/client/flags" 8 | "github.com/empowerchain/empowerchain/x/proofofexistence/types" 9 | "github.com/spf13/cobra" 10 | ) 11 | 12 | func CmdShowProof() *cobra.Command { 13 | cmd := &cobra.Command{ 14 | Use: "show-stored-proof [hash]", 15 | Short: "shows a Proof", 16 | Args: cobra.ExactArgs(1), 17 | RunE: func(cmd *cobra.Command, args []string) (err error) { 18 | clientCtx := client.GetClientContextFromCmd(cmd) 19 | 20 | queryClient := types.NewQueryClient(clientCtx) 21 | 22 | argHash := args[0] 23 | 24 | params := &types.QueryGetProofRequest{ 25 | Hash: argHash, 26 | } 27 | 28 | res, err := queryClient.Proof(context.Background(), params) 29 | if err != nil { 30 | return err 31 | } 32 | 33 | return clientCtx.PrintProto(res) 34 | }, 35 | } 36 | 37 | flags.AddQueryFlagsToCmd(cmd) 38 | 39 | return cmd 40 | } 41 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/simulation/create.go: -------------------------------------------------------------------------------- 1 | package simulation 2 | 3 | import ( 4 | "math/rand" 5 | 6 | "github.com/cosmos/cosmos-sdk/baseapp" 7 | sdk "github.com/cosmos/cosmos-sdk/types" 8 | simtypes "github.com/cosmos/cosmos-sdk/types/simulation" 9 | "github.com/empowerchain/empowerchain/x/proofofexistence/keeper" 10 | "github.com/empowerchain/empowerchain/x/proofofexistence/types" 11 | ) 12 | 13 | func SimulateMsgCreate( 14 | ak types.AccountKeeper, 15 | bk types.BankKeeper, 16 | k keeper.Keeper, 17 | ) simtypes.Operation { 18 | return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, 19 | ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { 20 | simAccount, _ := simtypes.RandomAcc(r, accs) 21 | msg := &types.MsgCreateProof{ 22 | Reporter: simAccount.Address.String(), 23 | } 24 | 25 | // TODO: Handling the CreateProof simulation 26 | 27 | return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "CreateProof simulation not implemented"), nil, nil 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/types/params.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" 5 | "gopkg.in/yaml.v2" 6 | ) 7 | 8 | var _ paramtypes.ParamSet = (*Params)(nil) 9 | 10 | // ParamKeyTable the param key table for launch module 11 | func ParamKeyTable() paramtypes.KeyTable { 12 | return paramtypes.NewKeyTable().RegisterParamSet(&Params{}) 13 | } 14 | 15 | // NewParams creates a new Params instance 16 | func NewParams() Params { 17 | return Params{} 18 | } 19 | 20 | // DefaultParams returns a default set of parameters 21 | func DefaultParams() Params { 22 | return NewParams() 23 | } 24 | 25 | // ParamSetPairs get the params.ParamSet 26 | func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { 27 | return paramtypes.ParamSetPairs{} 28 | } 29 | 30 | // Validate validates the set of params 31 | func (p Params) Validate() error { 32 | return nil 33 | } 34 | 35 | // String implements the Stringer interface. 36 | func (p Params) String() string { 37 | out, _ := yaml.Marshal(p) 38 | return string(out) 39 | } 40 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/client/cli/tx_create.go: -------------------------------------------------------------------------------- 1 | package cli 2 | 3 | import ( 4 | "strconv" 5 | 6 | "github.com/cosmos/cosmos-sdk/client" 7 | "github.com/cosmos/cosmos-sdk/client/flags" 8 | "github.com/cosmos/cosmos-sdk/client/tx" 9 | "github.com/empowerchain/empowerchain/x/proofofexistence/types" 10 | "github.com/spf13/cobra" 11 | ) 12 | 13 | var _ = strconv.Itoa(0) 14 | 15 | func CmdCreate() *cobra.Command { 16 | cmd := &cobra.Command{ 17 | Use: "create [hash]", 18 | Short: "Broadcast message create", 19 | Args: cobra.ExactArgs(1), 20 | RunE: func(cmd *cobra.Command, args []string) (err error) { 21 | argHash := args[0] 22 | 23 | clientCtx, err := client.GetClientTxContext(cmd) 24 | if err != nil { 25 | return err 26 | } 27 | 28 | msg := types.NewMsgCreateProof( 29 | clientCtx.GetFromAddress().String(), 30 | argHash, 31 | ) 32 | if err := msg.ValidateBasic(); err != nil { 33 | return err 34 | } 35 | return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) 36 | }, 37 | } 38 | 39 | flags.AddTxFlagsToCmd(cmd) 40 | 41 | return cmd 42 | } 43 | -------------------------------------------------------------------------------- /chain/Earthfile: -------------------------------------------------------------------------------- 1 | VERSION 0.6 2 | FROM earthly/dind:ubuntu 3 | WORKDIR /empowerchain 4 | 5 | docker: 6 | RUN apt-get update -yq \ 7 | && apt-get install --no-install-recommends -yq \ 8 | wget gnupg ca-certificates gcc g++ make 9 | RUN wget -qO- https://go.dev/dl/go1.18.6.linux-amd64.tar.gz | tar -v -C /usr/local -xz 10 | ENV PATH $PATH:/usr/local/go/bin:/root/go/bin 11 | 12 | build: 13 | ARG EARTHLY_GIT_HASH 14 | ARG EARTHLY_GIT_SHORT_HASH 15 | ARG VERSION=dev-$EARTHLY_GIT_SHORT_HASH 16 | FROM +docker 17 | COPY Makefile . 18 | COPY go.mod . 19 | COPY go.sum . 20 | COPY app app 21 | COPY cmd cmd 22 | COPY proto proto 23 | COPY scripts scripts 24 | COPY testutil testutil 25 | COPY x x 26 | RUN make VERSION=$VERSION COMMIT=$EARTHLY_GIT_HASH build 27 | SAVE ARTIFACT build/empowerd AS LOCAL build/empowerd 28 | SAVE ARTIFACT go.mod AS LOCAL go.mod 29 | SAVE ARTIFACT go.sum AS LOCAL go.sum 30 | 31 | test: 32 | FROM +build 33 | RUN make test 34 | 35 | smoketest: 36 | FROM +build 37 | RUN make smoketest 38 | 39 | lint: 40 | FROM +build 41 | RUN make lint 42 | -------------------------------------------------------------------------------- /testnets/altruistic-1/gentx/gentx-example.json: -------------------------------------------------------------------------------- 1 | {"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgCreateValidator","description":{"moniker":"DragonDev","identity":"","website":"","security_contact":"","details":""},"commission":{"rate":"0.050000000000000000","max_rate":"0.200000000000000000","max_change_rate":"0.100000000000000000"},"min_self_delegation":"1","delegator_address":"empower19ydlc2zt44tvj0xgl33mx99fzcsxa7px9j0h3z","validator_address":"empowervaloper19ydlc2zt44tvj0xgl33mx99fzcsxa7pxaf3clh","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"s/XsNkiBeZc7pR0CB4YFk+gQtK6RrbgEZANevizxgGc="},"value":{"denom":"umpwr","amount":"1000000"}}],"memo":"4b788452134054f82d1f39d5adcd41a96f92d1b6@65.109.27.156:26656","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A2/Qat+/IJNAAobKmIO4Z5f4hFqaiTOkH3U9zDw4B4Q0"},"mode_info":{"single":{"mode":"SIGN_MODE_DIRECT"}},"sequence":"0"}],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":["ldGniVa9PtCbzmBqnl3Qkf9gzw5zCR/5lAyFmm4fWgZ+gs+yISKHCxSviYX+i94Bv3C7iFHfeOI1L5BsHQu2Jg=="]} 2 | -------------------------------------------------------------------------------- /testnets/altruistic-1/gentx/zuka.json: -------------------------------------------------------------------------------- 1 | {"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgCreateValidator","description":{"moniker":"zuka","identity":"672671D0995AFC73","website":"","security_contact":"","details":"Discord: Zuka:5870"},"commission":{"rate":"0.050000000000000000","max_rate":"0.200000000000000000","max_change_rate":"0.010000000000000000"},"min_self_delegation":"1","delegator_address":"empower19u539q85fun7nax92w853gcqtl74kr0en27rkd","validator_address":"empowervaloper19u539q85fun7nax92w853gcqtl74kr0et3qvcc","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"cPEZqjNBZfQOUzYFcLu96F0s6TITsIkW5iwtbf8htn0="},"value":{"denom":"umpwr","amount":"1000000"}}],"memo":"ed83872f2781b2bdb282fc2fd790527bcb6ffe9f@192.168.3.17:26656","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A4YnSwcEVVcSNTM83gPEKQtfKWiWh4/w9OcMGR3ckhl1"},"mode_info":{"single":{"mode":"SIGN_MODE_DIRECT"}},"sequence":"0"}],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":["zq8sLr98iLt5yPS492TcL5CUE/sjBzxUQequ/PFzlGhF7EF9pzJG2GVT7GFsYESWREy2NcA2t7SeXAhgQCku0A=="]} 2 | -------------------------------------------------------------------------------- /testnets/altruistic-1/gentx/munris-gentx.json: -------------------------------------------------------------------------------- 1 | {"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgCreateValidator","description":{"moniker":"Munris","identity":"E781A7FB7A3511B4","website":"https://munris.tech","security_contact":"","details":""},"commission":{"rate":"0.050000000000000000","max_rate":"0.200000000000000000","max_change_rate":"0.100000000000000000"},"min_self_delegation":"1","delegator_address":"empower1lln3986rtjt07c2rd6w9476h4fdysqtt5n7j22","validator_address":"empowervaloper1lln3986rtjt07c2rd6w9476h4fdysqttvgqayl","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"43C2SaxBlTs/FhQzaQeQHbVeIE2B+nKnV4i5Ikp/yV0="},"value":{"denom":"umpwr","amount":"1000000"}}],"memo":"edc9aa0bbf1fcd7433fcc3650e3f50ab0becc0b5@65.21.170.3:26656","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AlTrGLYvRJOXpXEfir0PxEuKvnqSViyysz+aKU9UQ7+k"},"mode_info":{"single":{"mode":"SIGN_MODE_DIRECT"}},"sequence":"0"}],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":["M8IrYmXav31MiPB72WmE4Edhha3C0mk3Mv9Ot/YCCTkdfQpYEwYzxsp5I9KTLPG4yaCm0dTVlB8PIZ1Al1z5JA=="]} 2 | -------------------------------------------------------------------------------- /testnets/gentx-RuesValidator.json: -------------------------------------------------------------------------------- 1 | {"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgCreateValidator","description":{"moniker":"RuesValidator","identity":"128462B2F5F8552F","website":"forum.rues.info","security_contact":"github.com/ruesandora","details":"build"},"commission":{"rate":"0.050000000000000000","max_rate":"0.200000000000000000","max_change_rate":"0.100000000000000000"},"min_self_delegation":"1","delegator_address":"empower1hfp33wg3332tsp456xu2l07y30qdqdrgctg5tf","validator_address":"empowervaloper1hfp33wg3332tsp456xu2l07y30qdqdrgqskm9u","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"IESlfDOlvYANVrXllDZD5gdB2RtaQriOYjXhwieqyBE="},"value":{"denom":"umpwr","amount":"1000000"}}],"memo":"74f6551f971f115447f62f7042c903ee01f861e0@38.242.154.10:26656","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AqVu3gBWeSD0SvGFYyuFphrecJPnmEn6SEzBUNrlwKaw"},"mode_info":{"single":{"mode":"SIGN_MODE_DIRECT"}},"sequence":"0"}],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":["xImQJV0vDzFT6cqAX9LeFLzTIl5GH3G8e/9igozxLO01XqxyNLBheBZnHj38m7NX4FEZetn6H2IJGPuNrT68pg=="]} 2 | -------------------------------------------------------------------------------- /chain/app/params/encoding.go: -------------------------------------------------------------------------------- 1 | package params 2 | 3 | import ( 4 | "github.com/cosmos/cosmos-sdk/client" 5 | "github.com/cosmos/cosmos-sdk/codec" 6 | "github.com/cosmos/cosmos-sdk/codec/types" 7 | "github.com/cosmos/cosmos-sdk/std" 8 | "github.com/cosmos/cosmos-sdk/types/module" 9 | "github.com/cosmos/cosmos-sdk/x/auth/tx" 10 | ) 11 | 12 | type EncodingConfig struct { 13 | InterfaceRegistry types.InterfaceRegistry 14 | Codec codec.Codec 15 | TxConfig client.TxConfig 16 | Amino *codec.LegacyAmino 17 | } 18 | 19 | func MakeEncodingConfig(moduleBasics module.BasicManager) EncodingConfig { 20 | amino := codec.NewLegacyAmino() 21 | interfaceRegistry := types.NewInterfaceRegistry() 22 | marshaler := codec.NewProtoCodec(interfaceRegistry) 23 | txCfg := tx.NewTxConfig(marshaler, tx.DefaultSignModes) 24 | 25 | std.RegisterLegacyAminoCodec(amino) 26 | std.RegisterInterfaces(interfaceRegistry) 27 | moduleBasics.RegisterLegacyAminoCodec(amino) 28 | moduleBasics.RegisterInterfaces(interfaceRegistry) 29 | 30 | return EncodingConfig{ 31 | InterfaceRegistry: interfaceRegistry, 32 | Codec: marshaler, 33 | TxConfig: txCfg, 34 | Amino: amino, 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /.github/workflows/testnets.yml: -------------------------------------------------------------------------------- 1 | name: "Gentx checker" 2 | on: 3 | pull_request: 4 | branches: [ "main" ] 5 | paths: 6 | - 'testnets/altruistic-1/gentx/**.json' 7 | 8 | # Allows you to run this workflow manually from the Actions tab 9 | workflow_dispatch: 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | steps: 15 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 16 | - uses: actions/checkout@v3 17 | 18 | - name: Setup Node.js environment 19 | uses: actions/setup-node@v3.4.1 20 | with: 21 | node-version: 14.18.1 22 | 23 | - id: files 24 | name: Check gentx 25 | uses: jitterbit/get-changed-files@v1 26 | with: 27 | format: 'json' 28 | - run: | 29 | readarray -t added_modified_files <<<"$(jq -r '.[]' <<<'${{ steps.files.outputs.added_modified }}')" 30 | if [[ ${#added_modified_files[@]} > 1 ]]; then 31 | echo "More than one file found" 32 | exit 1 33 | fi 34 | for added_modified_file in ${added_modified_files[@]}; do 35 | node testnets/altruistic-1/gentx-checker.js ${added_modified_file} 36 | done 37 | -------------------------------------------------------------------------------- /testnets/altruistic-1/gentx/yefu-gentx.json: -------------------------------------------------------------------------------- 1 | {"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgCreateValidator","description":{"moniker":"YEFU","identity":"23BB80998470934B","website":"https://twitter.com/zhekakrip","security_contact":"yefucryp@gmail.com","details":"validation and staking services"},"commission":{"rate":"0.050000000000000000","max_rate":"0.200000000000000000","max_change_rate":"0.100000000000000000"},"min_self_delegation":"1","delegator_address":"empower1lfc486f0gas5rd2yggwxzchvgq4jfhrmg9f4lw","validator_address":"empowervaloper1lfc486f0gas5rd2yggwxzchvgq4jfhrms7h63m","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"lOd3fvAkG/0X8Cud9RvGju97+XNujRTdIpyhtytug4c="},"value":{"denom":"umpwr","amount":"1000000"}}],"memo":"b22f0708c6f393bf79acc0a6ca23643fe7d58391@65.21.91.50:26656","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A6/KQZuDvXa3MI66C/9gNlsBe6FNA+1gDTKyyMi8o5oz"},"mode_info":{"single":{"mode":"SIGN_MODE_DIRECT"}},"sequence":"0"}],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":["xQdQ8StF62EY9muhOuR4FUJ37tFoeYr7SYpPvgSaQwJ5iYu8LPGCoYvqXSJ+Bweyh30DBMCp1rRNInaZ2RgN9w=="]} 2 | -------------------------------------------------------------------------------- /testnets/altruistic-1/gentx/[NODERS]TEAM.json: -------------------------------------------------------------------------------- 1 | {"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgCreateValidator","description":{"moniker":"[NODERS]TEAM","identity":"B38EBF2F38B998F4","website":"","security_contact":"dudava45@gmailc.com","details":"Tell me what node you set, and I will tell you who you are"},"commission":{"rate":"0.050000000000000000","max_rate":"0.200000000000000000","max_change_rate":"0.100000000000000000"},"min_self_delegation":"1","delegator_address":"empower1lzg0ddk7jqqnqalhueml54yejklad22jtvzrm9","validator_address":"empowervaloper1lzg0ddk7jqqnqalhueml54yejklad22jnhuv4s","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"hevwRQebyjDf5m4U7fOOlqqqAYs0mK5+T0dIDi541PI="},"value":{"denom":"umpwr","amount":"1000000"}}],"memo":"fe32c17373fbaa36d9fd86bc1146bfa125bb4f58@5.9.147.185:26656","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AqYLSMutCDtvZmNiDfwAiDlWQJJJBeluZ3hxPEeTuOuZ"},"mode_info":{"single":{"mode":"SIGN_MODE_DIRECT"}},"sequence":"0"}],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":["w0Z2eUrpjjvZaFaaAu/gpyWrWhVWVQ5I10vGZBVhw4VfaW4WtL1QTFCstOp3+uZcJlXi1mLr9ZJb1zbhiRu9BQ=="]} 2 | -------------------------------------------------------------------------------- /testnets/altruistic-1/gentx/gentx-PPNV_Service.json: -------------------------------------------------------------------------------- 1 | {"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgCreateValidator","description":{"moniker":"PPNV Service","identity":"862C5270EE4D7EB6","website":"https://PPNV.space","security_contact":"","details":"Professional Proof of Stake Network Validator ✅"},"commission":{"rate":"0.050000000000000000","max_rate":"0.200000000000000000","max_change_rate":"0.100000000000000000"},"min_self_delegation":"1","delegator_address":"empower18t634traelzqr40n397puglaxy7vft9cfvv6hg","validator_address":"empowervaloper18t634traelzqr40n397puglaxy7vft9c3hj4ea","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"K6jeFhocgdj6VvkHdwMMbNI9gze9vMbCEvTp3AFGjhc="},"value":{"denom":"umpwr","amount":"1000000"}}],"memo":"1069820cdd9f5332503166b60dc686703b2dccc5@138.201.141.76:26656","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A620Jg8EuwXn5xdxMSLVXi+3mSoE6+vuiFWOnCE0EGkE"},"mode_info":{"single":{"mode":"SIGN_MODE_DIRECT"}},"sequence":"0"}],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":["V1+0eC5zBHzpnIfl06ya2KlN/RpqbcOki6ZkcrYupBIPvwtaYE2rAwnj+WVQaSaZSj18ZQKV4OkRKHImURYhPw=="]} 2 | -------------------------------------------------------------------------------- /testnets/altruistic-1/gentx/zenchainlabs-gentx.json: -------------------------------------------------------------------------------- 1 | {"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgCreateValidator","description":{"moniker":"ZenChainLabs","identity":"C0586A29077BF9AE","website":"https://zenchainlabs.io","security_contact":"support@zenchainlabs.io","details":"Secure and Reliable Blockchain Services"},"commission":{"rate":"0.050000000000000000","max_rate":"0.200000000000000000","max_change_rate":"0.100000000000000000"},"min_self_delegation":"1","delegator_address":"empower1t02v7nyy75kjsuqnnctfkmd64gcygm5pjyv2zt","validator_address":"empowervaloper1t02v7nyy75kjsuqnnctfkmd64gcygm5p2lj9v7","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"h29dPNexTfLMCG7EU1lCyM/Hs0JC0JzKe34cFRbEt/Y="},"value":{"denom":"umpwr","amount":"1000000"}}],"memo":"e8f6d75ab37bf4f08c018f306416df1e138fd21c@95.217.135.41:26656","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AqIgBJAffy5tVP7FpuXL0Bq8ClAUYu9+XA7q+72e/q7p"},"mode_info":{"single":{"mode":"SIGN_MODE_DIRECT"}},"sequence":"0"}],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":["35EcNZM/c+ytBjgU+q4A3xBfCeumqohy81gxzllMlEpKy2EdBdXEY5yVwsK6YdcDp6YYOxMsem0GzfYlXrnd/Q=="]} 2 | -------------------------------------------------------------------------------- /testnets/altruistic-1/gentx/gentx-52450b21f346a4cf76334374c9d8012b2867b842.json: -------------------------------------------------------------------------------- 1 | {"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgCreateValidator","description":{"moniker":"LOALabs","identity":"ACB2261DAB6606BA","website":"https://loalabs.io","security_contact":"dev@loalabs.io","details":"Building Better World Blockchains"},"commission":{"rate":"0.050000000000000000","max_rate":"0.200000000000000000","max_change_rate":"0.100000000000000000"},"min_self_delegation":"1","delegator_address":"empower1l5u9f4d4qfsj0sh4lgqvaz8hchz5nqzmcmeg09","validator_address":"empowervaloper1l5u9f4d4qfsj0sh4lgqvaz8hchz5nqzmqq88ps","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"4ntYn4Mr6hh4nKC8GMudXuQMrCq1vk/yy3AhhuzVJ2M="},"value":{"denom":"umpwr","amount":"1000000"}}],"memo":"52450b21f346a4cf76334374c9d8012b2867b842@167.172.246.201:26656","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AvZ5A3n3LPQzC5vqgXzUuN5quPhIkoDegJ4RyvngkacM"},"mode_info":{"single":{"mode":"SIGN_MODE_DIRECT"}},"sequence":"0"}],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":["Y60+gfKHHEwn5+0t+11gM4vo0cojenkWZCEENJyZlOsOyPZK2KHfTdsICL9zETRADs7iAwEIny60x0zAR0KQCA=="]} 2 | -------------------------------------------------------------------------------- /testnets/altruistic-1/gentx/𝑵𝒐𝒅𝒆𝒔𝑩𝒍𝒐𝒄𝒌𝒔.json: -------------------------------------------------------------------------------- 1 | {"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgCreateValidator","description":{"moniker":"𝑵𝒐𝒅𝒆𝒔𝑩𝒍𝒐𝒄𝒌𝒔","identity":"5328563A4BD384C9","website":"https://nodesblocks.dev","security_contact":"nodesblocks@outlook.com","details":"𝑩𝑬𝑺𝑻 𝑩𝑳𝑶𝑪𝑲𝑺 𝑶𝑹 𝑵𝑶𝑻𝑯𝑰𝑵𝑮"},"commission":{"rate":"0.030000000000000000","max_rate":"0.130000000000000000","max_change_rate":"0.030000000000000000"},"min_self_delegation":"1","delegator_address":"empower1sy88pdqse7xu5ln5vqumna4qg3ye7f8xvttcd3","validator_address":"empowervaloper1sy88pdqse7xu5ln5vqumna4qg3ye7f8x5s4hry","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"v92TzfiIfsA4925d+o0eUgWobbTfZ3fBtQAJF7r+M5E="},"value":{"denom":"umpwr","amount":"1000000"}}],"memo":"4fd5e497563b2e09cfe6f857fb35bdae76c12582@65.108.206.56:26656","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"Ag88fbz3ngAJ/jVhpqoZUqK8L675thkiYPzMzUEYypNX"},"mode_info":{"single":{"mode":"SIGN_MODE_DIRECT"}},"sequence":"0"}],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":["1cxUS++JlMD+owyBZAU7ee7ICFE7If4kftypTEKGtZ1qMhAJFxC6xsaLDPCygi0TeB81SEyQMouLTL9VyTei8A=="]} 2 | -------------------------------------------------------------------------------- /testnets/altruistic-1/gentx/n0ok[MC].json: -------------------------------------------------------------------------------- 1 | {"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgCreateValidator","description":{"moniker":"n0ok[MC]","identity":"2CCE7DDD3B53F8AB","website":"https://n0ok.net","security_contact":"n0ok0ne.Sergey@gmail.com","details":"Secure and reliable individual PoS/PoW validator. Best uptime and 24/7 support."},"commission":{"rate":"0.050000000000000000","max_rate":"0.200000000000000000","max_change_rate":"0.100000000000000000"},"min_self_delegation":"1","delegator_address":"empower1nzk8plx0q9j2k7nql33fyh38zwl8zeu65qa0rr","validator_address":"empowervaloper1nzk8plx0q9j2k7nql33fyh38zwl8zeu6vmrqdk","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"GdXEt2F2aPdoh8npwVkZwR69XarGWt1pAugT1N4toH4="},"value":{"denom":"umpwr","amount":"1000000"}}],"memo":"d582bcd8a8f0a20c551098571727726bc75bae74@213.239.217.52:26656","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AhEcMaoEQWT5mYcDaMWY+gWKjuQwIsfW+X8AMkvIt3Hp"},"mode_info":{"single":{"mode":"SIGN_MODE_DIRECT"}},"sequence":"0"}],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":["yBzfhct1nuUotdYyH2KyvOunw42Ni1xyrOmQcOeQiFxKAht01aZmBVUHbg6TfZOO4T1668L4fUiUHk1/Ex3Fbg=="]} 2 | -------------------------------------------------------------------------------- /testnets/altruistic-1/gentx/gentx-Stake-Take.json: -------------------------------------------------------------------------------- 1 | {"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgCreateValidator","description":{"moniker":"Stake-Take","identity":"4A1DED53D477793B","website":"https://stake-take.com/","security_contact":"team@stake-take.com","details":" Trustworthy and high performance validators. Stake with us and Take profit 🚀 "},"commission":{"rate":"0.050000000000000000","max_rate":"0.200000000000000000","max_change_rate":"0.050000000000000000"},"min_self_delegation":"1","delegator_address":"empower1vcr92vm2a3dexxl923zvw02k9pxxda6fpgx3nj","validator_address":"empowervaloper1vcr92vm2a3dexxl923zvw02k9pxxda6fenc7a8","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"e7vE34zcj0Xkuk/+H7RfXLKRSh0ahyzZJQ0I90F1B80="},"value":{"denom":"umpwr","amount":"1000000"}}],"memo":"277ff448eec6ec7fa665f68bdb1c9cb1a52ff597@159.69.110.238:26656","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A+DB2aadNLBgG+GIwQf92kD8GCitnbX/TYcZFw4iStPu"},"mode_info":{"single":{"mode":"SIGN_MODE_DIRECT"}},"sequence":"0"}],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":["C9DICO8slK3SNrQ01dqU9s/8RzL7fHFh/QVvH6rd4MYxMAuuhmZIWQGCE6Ef5TQ9IQ+rLDD9//wZHk4HTe79MQ=="]} 2 | -------------------------------------------------------------------------------- /chain/scripts/protocgen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euox pipefail 4 | 5 | # Get protoc executions 6 | go get github.com/regen-network/cosmos-proto/protoc-gen-gocosmos 2>/dev/null 7 | 8 | # Get cosmos sdk from github 9 | go get github.com/cosmos/cosmos-sdk@v0.45.4 2>/dev/null 10 | 11 | # Get the path of the cosmos-sdk repo from go/pkg/mod 12 | cosmos_sdk_dir=$(go list -f '{{ .Dir }}' -m github.com/cosmos/cosmos-sdk) 13 | 14 | proto_dirs=$(find . -path ./third_party -prune -o -name '*.proto' -print0 | xargs -0 -n1 dirname | sort | uniq) 15 | 16 | for dir in $proto_dirs; do 17 | # Generate protobuf bind 18 | # shellcheck disable=SC2046 19 | buf protoc \ 20 | -I "proto" \ 21 | -I "$cosmos_sdk_dir/third_party/proto" \ 22 | -I "$cosmos_sdk_dir/proto" \ 23 | --gocosmos_out=plugins=interfacetype+grpc,\ 24 | Mgoogle/protobuf/any.proto=github.com/cosmos/cosmos-sdk/codec/types:. \ 25 | $(find "${dir}" -name '*.proto') 26 | 27 | # Generate grpc gateway 28 | # shellcheck disable=SC2046 29 | buf protoc \ 30 | -I "proto" \ 31 | -I "$cosmos_sdk_dir/third_party/proto" \ 32 | -I "$cosmos_sdk_dir/proto" \ 33 | --grpc-gateway_out=logtostderr=true,allow_colon_final_segments=true:. \ 34 | $(find "${dir}" -maxdepth 1 -name '*.proto') 35 | done 36 | 37 | cp -r ./github.com/empowerchain/empowerchain/* ./ 38 | rm -rf ./github.com 39 | -------------------------------------------------------------------------------- /testnets/altruistic-1/gentx/polkachu.json: -------------------------------------------------------------------------------- 1 | {"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgCreateValidator","description":{"moniker":"polkachu.com","identity":"0A6AF02D1557E5B4","website":"https://polkachu.com","security_contact":"hello@polkachu.com","details":"Polkachu is the trusted staking service provider for blockchain projects. 100% refund for downtime slash. Contact us at hello@polkachu.com"},"commission":{"rate":"0.050000000000000000","max_rate":"0.100000000000000000","max_change_rate":"0.050000000000000000"},"min_self_delegation":"1","delegator_address":"empower1jt9w26mpxxjsk63mvd4m2ynj0af09cslld6dn0","validator_address":"empowervaloper1jt9w26mpxxjsk63mvd4m2ynj0af09csl8kyza6","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"XchrDqaIzTF4bCJVdMA1Y+W6W5Yj+21CAtMuNpKDPVs="},"value":{"denom":"umpwr","amount":"1000000"}}],"memo":"eb182533a12d75fbae1ec32ef1f8fc6b6dd06601@65.109.28.219:26656","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"As1WcJsvf1NQgRlS8a2PHuueKhHlCYrFe3VooMxQdflR"},"mode_info":{"single":{"mode":"SIGN_MODE_DIRECT"}},"sequence":"0"}],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":["DximpGcHrQC4pwwDsdzb/92JW1rK0nvT6Fvi/SQrOjs2tKXTeuI+9Nj7sS9mBQS6eM/s0FpJ8vczBRIEMLVklw=="]} 2 | -------------------------------------------------------------------------------- /testnets/altruistic-1/gentx/gentx-220fb60b083bc4d443ce2a7a5363f4813dd4aef4.json: -------------------------------------------------------------------------------- 1 | {"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgCreateValidator","description":{"moniker":"STAVR","identity":"F2F91999ECCC092F","website":"https://github.com/obajay","security_contact":"","details":"A team of professional and reliable validators. Safety first.Stake with us and profit with the mark of quality. Monitoring 25\\7"},"commission":{"rate":"0.050000000000000000","max_rate":"0.200000000000000000","max_change_rate":"0.100000000000000000"},"min_self_delegation":"1","delegator_address":"empower1l4xt877lhhhm9573ewpxrcdl9x29n7sc2c4zwm","validator_address":"empowervaloper1l4xt877lhhhm9573ewpxrcdl9x29n7scjrtdqw","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"X1zl0YRzay9UPF3wHifuuuDEOVNI74XDPO2CtDUZZAk="},"value":{"denom":"umpwr","amount":"1000000"}}],"memo":"220fb60b083bc4d443ce2a7a5363f4813dd4aef4@116.202.236.115:26656","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"Av+EQ55NkIqTiVclshzOo5vPitWXu74wY2ZBBDL/W9DF"},"mode_info":{"single":{"mode":"SIGN_MODE_DIRECT"}},"sequence":"0"}],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":["GMzs05n71PMUJquno2BlGKLDOE1WrQoL+szmeW2qLb10bUmKr/94bAm7fmAW+WreM3Tz71/LPQIZIkvtjZgJJQ=="]} 2 | -------------------------------------------------------------------------------- /testnets/altruistic-1/gentx/gentx-Validatorrun.json: -------------------------------------------------------------------------------- 1 | {"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgCreateValidator","description":{"moniker":"Validator.run","identity":"2CC4D67B2136C051","website":"https://www.validator.run","security_contact":"contact@validator.run","details":"Validator.run provides trusted stake service with 100% refund on downtime slashing. Enterprise grade infrastructure. High end security and 24/7 monitoring."},"commission":{"rate":"0.050000000000000000","max_rate":"0.200000000000000000","max_change_rate":"0.100000000000000000"},"min_self_delegation":"1","delegator_address":"empower1jzds0k6d04zu52paldgzlav7dtvd2lflx6rmar","validator_address":"empowervaloper1jzds0k6d04zu52paldgzlav7dtvd2lfl7pa5nk","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"yxhUC+vVANFIRW+wZLxzpRkHACXjJwQaZwhKVQx/ess="},"value":{"denom":"umpwr","amount":"1000000"}}],"memo":"3335c9458105cf65546db0fb51b66f751eeb4906@5.189.129.30:26656","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A6GoMyiuWqy6f+rdMVV+moHkkr4JRBc/8+rP5CUP7Jxb"},"mode_info":{"single":{"mode":"SIGN_MODE_DIRECT"}},"sequence":"0"}],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":["RQAAABpyt0naxiXeh3ZDaYV1eNkBRixgMiB23VGYjcNLy6RvnRUpMxCspZyn3BFOekmyVkYyKw7ozSJM0yCV7A=="]} 2 | -------------------------------------------------------------------------------- /testnets/altruistic-1/gentx/EZStaking.io-gentx.json: -------------------------------------------------------------------------------- 1 | {"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgCreateValidator","description":{"moniker":"EZStaking.io 100% Slash Protected","identity":"1534523421A364DB","website":"https://ezstaking.io","security_contact":"contact@ezstaking.io","details":"100% refund on downtime slashing. Enterprise grade infrastructure. High end security and 24/7 monitoring. https://twitter.com/EZStaking https://t.me/ezstaking"},"commission":{"rate":"0.050000000000000000","max_rate":"0.200000000000000000","max_change_rate":"0.030000000000000000"},"min_self_delegation":"1","delegator_address":"empower1rnmlnlka66h76h50lyes243z388l5vkpf0qvq9","validator_address":"empowervaloper1rnmlnlka66h76h50lyes243z388l5vkp357rws","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"bQGfW5hTlVwRSkAHE1+VQoZSIr5ymP9adtQ6tMNnyiE="},"value":{"denom":"umpwr","amount":"1000000"}}],"memo":"9de92b545638f6baaa7d6d5109a1f7148f093db3@65.108.77.106:26656","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A0zg7uO5SYGBXQW4Yl8u/sf8U/qr3slCZkBGGBgl+oRW"},"mode_info":{"single":{"mode":"SIGN_MODE_DIRECT"}},"sequence":"0"}],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":["Am3nGLoCQZsrFgoUxzZkf2VxBLLbVty7D1XpAPqAZlk8Oq+ACWwoN6/JMFQGJ0p9CKEV/DSYTfA3m2fhLbpqHw=="]} 2 | -------------------------------------------------------------------------------- /testnets/altruistic-1/gentx/gentx-2a2932e780a681ddf980594f7eacf5a33081edaf.json: -------------------------------------------------------------------------------- 1 | {"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgCreateValidator","description":{"moniker":"✅ CryptoCrew Validators #IBCgang","identity":"9AE70F9E3EDA8956","website":"https://ccvalidators.com","security_contact":"support@ccvalidators.com","details":"CryptoCrew validator \u0026 multi-chain IBC-relayer service for EMPOWER CHAIN. Based in Europe. t.me/cryptocrew_validators"},"commission":{"rate":"0.050000000000000000","max_rate":"0.200000000000000000","max_change_rate":"0.010000000000000000"},"min_self_delegation":"1","delegator_address":"empower15x4mp4jfvptlgyzne62v62534x9y8zrpzahgs7","validator_address":"empowervaloper15x4mp4jfvptlgyzne62v62534x9y8zrp6xf87t","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"2lIFDH4ufWG6BO3g2QF6IY1M/VI1RwiFgZuKhFPfFlE="},"value":{"denom":"umpwr","amount":"1000000"}}],"memo":"2a2932e780a681ddf980594f7eacf5a33081edaf@192.168.147.43:26656","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AuSStkrSPRssn05ab/DwlkRcyf8Vt63SaEn+Oun3Qclj"},"mode_info":{"single":{"mode":"SIGN_MODE_DIRECT"}},"sequence":"0"}],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":["XY/WUpoeOcExKY6ONKojlKILJjLsmE1E1oK/L7cNjCw9poLRM1D1yYVzKJpWks6RAPZ1CFXxy46CUfGSEgX+MQ=="]} 2 | -------------------------------------------------------------------------------- /testnets/altruistic-1/gentx-checker.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | class GentxChecker { 4 | constructor(gentx) { 5 | this._validator_data = gentx.body.messages[0]; 6 | } 7 | 8 | isHealthyDelegatorAddress() { 9 | return this._validator_data.delegator_address.startsWith('empower'); 10 | } 11 | 12 | isHealthyValidatorAddress() { 13 | return this._validator_data.validator_address.startsWith('empower'); 14 | } 15 | 16 | isHealthyAmount() { 17 | return parseInt(this._validator_data.value.amount) / 1000000 === 1.0; 18 | } 19 | 20 | isHealthyDenom() { 21 | return this._validator_data.value['denom'] === 'umpwr'; 22 | } 23 | } 24 | 25 | let rawData = fs.readFileSync(process.argv[2]); 26 | let gentx_json = JSON.parse(rawData); 27 | 28 | const gentxChecker = new GentxChecker(gentx_json) 29 | const str_errors = [] 30 | 31 | if (!gentxChecker.isHealthyDelegatorAddress()) 32 | str_errors.push('Incorrect delegator address.'); 33 | if (!gentxChecker.isHealthyValidatorAddress()) 34 | str_errors.push('Incorrect validator address.'); 35 | if (!gentxChecker.isHealthyAmount()) 36 | str_errors.push('Incorrect amount.'); 37 | if (!gentxChecker.isHealthyDenom()) 38 | str_errors.push('Incorrect denom.'); 39 | 40 | console.log(str_errors.length === 0 ? 'No errors found' : str_errors.join('\n')) 41 | process.exit(str_errors.length === 0 ? 0 : 1) 42 | -------------------------------------------------------------------------------- /testnets/altruistic-1/gentx/gentx-4a38efbae54fd1357329bd583186a68ccd6d85f9.json: -------------------------------------------------------------------------------- 1 | {"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgCreateValidator","description":{"moniker":"SteadyCrypto | EMPOWER","identity":"1571B9CF08E4AF4B","website":"https://SteadyCrypto.solutions","security_contact":"security@steadycrypto.solutions","details":"Creators + operators of the @airdrops_one 🐦 account. 🤝 Working hard to make #Cosmos a better, more decentralized ecosystem. ⚛️ Tweets @ SteadyCrypto 👍 "},"commission":{"rate":"0.050000000000000000","max_rate":"0.200000000000000000","max_change_rate":"0.050000000000000000"},"min_self_delegation":"1","delegator_address":"empower1tr55feld2k4g9xmvqw803m4jvgekldc6n9cegv","validator_address":"empowervaloper1tr55feld2k4g9xmvqw803m4jvgekldc6t7xkxe","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"FTeRs4aERFFFpWSXjNyfRx74XxXgaySmlTYbXXFjcac="},"value":{"denom":"umpwr","amount":"1000000"}}],"memo":"4a38efbae54fd1357329bd583186a68ccd6d85f9@94.130.212.252:26656","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AmZ4KzFsxKpYfFy62gXVuqQZk62apdeBrXzplUjuLiII"},"mode_info":{"single":{"mode":"SIGN_MODE_DIRECT"}},"sequence":"0"}],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":["tLaHbTv4cHHrtzYR7x2r2spgZg0Bw91fpBm+v/p3nZxxVyZnZSfmw0kph+vE2AvxBC7cSXVwTaSLQhTK9B0pLQ=="]} 2 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/types/genesis_test.go: -------------------------------------------------------------------------------- 1 | package types_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/empowerchain/empowerchain/x/proofofexistence/types" 7 | "github.com/stretchr/testify/require" 8 | ) 9 | 10 | func TestDefaultGenesisIsCorrect(t *testing.T) { 11 | genesis := types.DefaultGenesis() 12 | require.Equal(t, &types.GenesisState{ 13 | ProofList: []types.Proof{}, 14 | }, genesis) 15 | } 16 | 17 | func TestGenesisState_Validate(t *testing.T) { 18 | for _, tc := range []struct { 19 | desc string 20 | genState *types.GenesisState 21 | valid bool 22 | }{ 23 | { 24 | desc: "default is valid", 25 | genState: types.DefaultGenesis(), 26 | valid: true, 27 | }, 28 | { 29 | desc: "valid genesis state", 30 | genState: &types.GenesisState{ 31 | 32 | ProofList: []types.Proof{ 33 | { 34 | Hash: "0", 35 | }, 36 | { 37 | Hash: "1", 38 | }, 39 | }, 40 | }, 41 | valid: true, 42 | }, 43 | { 44 | desc: "duplicated proof", 45 | genState: &types.GenesisState{ 46 | ProofList: []types.Proof{ 47 | { 48 | Hash: "0", 49 | }, 50 | { 51 | Hash: "0", 52 | }, 53 | }, 54 | }, 55 | valid: false, 56 | }, 57 | } { 58 | t.Run(tc.desc, func(t *testing.T) { 59 | err := tc.genState.Validate() 60 | if tc.valid { 61 | require.NoError(t, err) 62 | } else { 63 | require.Error(t, err) 64 | } 65 | }) 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /testnets/altruistic-1/gentx/gentx-bfb56f4cb8361c49a2ac107251f92c0ea5a1c251.json: -------------------------------------------------------------------------------- 1 | {"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgCreateValidator","description":{"moniker":"ECO Stake 🌱","identity":"5992A6D423A406D6","website":"https://ecostake.com","security_contact":"support@ecostake.com","details":"ECO Stake is a climate positive validator 🌱 Carbon neutral and 10% of commission is donated to climate causes 🌍 Check out REStake.app on our website and let us auto-compound your staking rewards for you 🔄"},"commission":{"rate":"0.050000000000000000","max_rate":"0.100000000000000000","max_change_rate":"0.010000000000000000"},"min_self_delegation":"1","delegator_address":"empower1msjwmclw77h5j0t69n7j2p9ur5ra46uxcx8zgh","validator_address":"empowervaloper1msjwmclw77h5j0t69n7j2p9ur5ra46uxqaedxz","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"7ZJBXwpZZJyzK9I0LcsRU5Danzv9ipYDfKtbOM0Ww1A="},"value":{"denom":"umpwr","amount":"1000000"}}],"memo":"bfb56f4cb8361c49a2ac107251f92c0ea5a1c251@192.168.1.177:26656","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AxHr9Q92maXSKUADK9uXa7f4dyKG2UI+6Xs0oMg2zRmd"},"mode_info":{"single":{"mode":"SIGN_MODE_LEGACY_AMINO_JSON"}},"sequence":"0"}],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":["xsKlZjNbI/ZqabhMw4cXwD+vZQtrFMtZ+wfmrOlLMFodte+A4cwkE15/7lJgTkVApdjr3SsEKKGtwjnNFTmqsw=="]} 2 | -------------------------------------------------------------------------------- /chain/testutil/keeper/proofofexistence.go: -------------------------------------------------------------------------------- 1 | package keeper 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/cosmos/cosmos-sdk/codec" 7 | codectypes "github.com/cosmos/cosmos-sdk/codec/types" 8 | "github.com/cosmos/cosmos-sdk/store" 9 | storetypes "github.com/cosmos/cosmos-sdk/store/types" 10 | sdk "github.com/cosmos/cosmos-sdk/types" 11 | "github.com/empowerchain/empowerchain/x/proofofexistence/keeper" 12 | "github.com/empowerchain/empowerchain/x/proofofexistence/types" 13 | "github.com/stretchr/testify/require" 14 | "github.com/tendermint/tendermint/libs/log" 15 | tmproto "github.com/tendermint/tendermint/proto/tendermint/types" 16 | tmdb "github.com/tendermint/tm-db" 17 | ) 18 | 19 | func ProofofexistenceKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) { 20 | storeKey := sdk.NewKVStoreKey(types.StoreKey) 21 | memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) 22 | 23 | db := tmdb.NewMemDB() 24 | stateStore := store.NewCommitMultiStore(db) 25 | stateStore.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, db) 26 | stateStore.MountStoreWithDB(memStoreKey, storetypes.StoreTypeMemory, nil) 27 | require.NoError(t, stateStore.LoadLatestVersion()) 28 | 29 | registry := codectypes.NewInterfaceRegistry() 30 | cdc := codec.NewProtoCodec(registry) 31 | 32 | k := keeper.NewKeeper( 33 | cdc, 34 | storeKey, 35 | memStoreKey, 36 | ) 37 | 38 | ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, log.NewNopLogger()) 39 | 40 | return k, ctx 41 | } 42 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/genesis_test.go: -------------------------------------------------------------------------------- 1 | package proofofexistence_test 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | 7 | keepertest "github.com/empowerchain/empowerchain/testutil/keeper" 8 | "github.com/empowerchain/empowerchain/testutil/nullify" 9 | "github.com/empowerchain/empowerchain/x/proofofexistence" 10 | "github.com/empowerchain/empowerchain/x/proofofexistence/types" 11 | "github.com/stretchr/testify/require" 12 | ) 13 | 14 | func TestGenesis(t *testing.T) { 15 | genesisState := types.GenesisState{ 16 | ProofList: []types.Proof{ 17 | { 18 | Hash: "0", 19 | Timestamp: time.UnixMilli(42).UTC(), 20 | Reporter: "empower10m8qakrveaxvcr5085c73de30ff5umdem2ua5u", 21 | }, 22 | { 23 | Hash: "1", 24 | Timestamp: time.UnixMilli(123).UTC(), 25 | Reporter: "empower10m8qakrveaxvcr5085c73de30ff5umdem2ua5u", 26 | }, 27 | }, 28 | } 29 | 30 | k, ctx := keepertest.ProofofexistenceKeeper(t) 31 | proofofexistence.InitGenesis(ctx, *k, genesisState) 32 | got := proofofexistence.ExportGenesis(ctx, *k) 33 | require.NotNil(t, got) 34 | 35 | for i, expected := range genesisState.ProofList { 36 | actual := got.ProofList[i] 37 | require.Equal(t, expected.Hash, actual.Hash) 38 | require.Equal(t, expected.Reporter, actual.Reporter) 39 | require.Equal(t, expected.Timestamp, actual.Timestamp) 40 | } 41 | 42 | nullify.Fill(&genesisState) 43 | nullify.Fill(got) 44 | 45 | require.ElementsMatch(t, genesisState.ProofList, got.ProofList) 46 | } 47 | -------------------------------------------------------------------------------- /testnets/altruistic-1/gentx/gentx-56d05d4ae0e1440ad7c68e52cc841c424d59badd.json: -------------------------------------------------------------------------------- 1 | {"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgCreateValidator","description":{"moniker":"Crypto Chemistry","identity":"969E99E6E4DD9BD5","website":"https://cryptochemistry.io/","security_contact":"relyte@protonmail.com","details":"Crypto Chemistry aims to decentralize and provide security \u0026 stability to the DPoS Networks we validate. We are active in the communities we operate in \u0026 participate in governance to ensure proper representation."},"commission":{"rate":"0.050000000000000000","max_rate":"0.200000000000000000","max_change_rate":"0.100000000000000000"},"min_self_delegation":"1","delegator_address":"empower1a84g9rv7z2fx9ls60x2w20anddejg65rczrfz2","validator_address":"empowervaloper1a84g9rv7z2fx9ls60x2w20anddejg65rqeaxvl","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"4gGhDL7WykhZcW+705hEhKk93ZI4C2ri1uWHBQdBia4="},"value":{"denom":"umpwr","amount":"1000000"}}],"memo":"56d05d4ae0e1440ad7c68e52cc841c424d59badd@192.168.1.46:26656","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AjG0FpLi0Fpb7vI82lkM2itlcQRuQRvb5qEPkVR7o5ku"},"mode_info":{"single":{"mode":"SIGN_MODE_DIRECT"}},"sequence":"0"}],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":["d+pWi5/gilf95y+t/kfR1Mbj8sQy/AUvFFMOuudTzvtbQg1rTnA+/8OZtuLFBPmkRqIS6+arEio0VHkiAACHgA=="]} 2 | -------------------------------------------------------------------------------- /testnets/altruistic-1/gentx/gentx-225ad85c594d03942a026b90f4dab43f90230ea0.json: -------------------------------------------------------------------------------- 1 | {"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgCreateValidator","description":{"moniker":" WhisperNode🤐","identity":"9C7571030BEF5157","website":"https://REStake.WhisperNode.com","security_contact":"security@whispernode.com","details":"WhisperNode operates robust, high up-time validators across the Cosmos ecosystem. Auto-compound your rewards with our REStake app. Join our Discord: https://discord.gg/4E5KZsRtjE / tweet @ https://twitter.com/WhisperNode 🐦"},"commission":{"rate":"0.050000000000000000","max_rate":"0.200000000000000000","max_change_rate":"0.050000000000000000"},"min_self_delegation":"1000000","delegator_address":"empower1qjg3cqx8w46drfyj96tsqwksle7cg5yw0sw226","validator_address":"empowervaloper1qjg3cqx8w46drfyj96tsqwksle7cg5ywhts9y0","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"dGFmrf3w0xk0s6oV6/EZT3PxTFx2U+3+0Zu6YKtd5nE="},"value":{"denom":"umpwr","amount":"1000000"}}],"memo":"225ad85c594d03942a026b90f4dab43f90230ea0@88.99.3.158:26656","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AwVIUmMsldM6W5Ol6s14dUOxpDDbmUtyBQR+RKPxicfy"},"mode_info":{"single":{"mode":"SIGN_MODE_DIRECT"}},"sequence":"0"}],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":["ovfilakALLZ1KSnEqQ0CJ7gqkU5x0Huqbd8KJGoCoWZqT3d2j6RsVHhDU/eRvGPvfg6XKlWd3EH4GEqgHcuu/g=="]} 2 | -------------------------------------------------------------------------------- /testnets/altruistic-1/gentx/gentx-6a675d4f66bfe049321c3861bcfd19bd09fefbde.json: -------------------------------------------------------------------------------- 1 | {"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgCreateValidator","description":{"moniker":" carbonZERO????","identity":"9E3466C0CB62F484","website":"https://restake.carbonZERO.zone/chihuahua","security_contact":"security@carbonzero.zone","details":"Eco-friendly Chihuahua staking. Donating 10% of ALL commissions earned = donated to Ecologi.com to plant ???????? \u0026 reduce co2 emissions. Try our REStake bot! Find us on Twitter for more info: https://twitter.com/carbonZEROzone"},"commission":{"rate":"0.050000000000000000","max_rate":"0.200000000000000000","max_change_rate":"0.050000000000000000"},"min_self_delegation":"1000000","delegator_address":"empower1vhyzdf0lv3zul4q2fpwthvfydg34najfpz23qk","validator_address":"empowervaloper1vhyzdf0lv3zul4q2fpwthvfydg34najfee57wr","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"eVA+OikF29E7rTE6jCKbnvraVfABRlEwEqaJ4lEiT2w="},"value":{"denom":"umpwr","amount":"1000000"}}],"memo":"6a675d4f66bfe049321c3861bcfd19bd09fefbde@195.3.223.204:26656","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A7cGQ8YyrzlpflhZbxIrWZ+DRvM/BMCiM49adgxoQ5IM"},"mode_info":{"single":{"mode":"SIGN_MODE_DIRECT"}},"sequence":"0"}],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":["1ra0XnKwTLhDDF/rbI7deVD9chM7KSoq/lNhiySWStcEZWi2uAaD/db0QUHi1Ej3Yu5eKDL8iw80UolF4v2xgA=="]} 2 | -------------------------------------------------------------------------------- /testnets/altruistic-1/gentx/gentx-333de3fc2eba7eead24e0c5f53d665662b2ba001.json: -------------------------------------------------------------------------------- 1 | {"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgCreateValidator","description":{"moniker":"Empower Validator ♻️ | 20% to plastic waste cleanups","identity":"CB7829D9D72A40E4","website":"https://www.empowerchain.io/validator","security_contact":"validator@empowerchain.io","details":"We work to develop best practise governance in the Cosmos ecosystem, with a focus on transparency, decentralisation and sustainability. 20% of fees goes to funding plastic waste cleanups around the globe, fighting for a world without waste."},"commission":{"rate":"0.050000000000000000","max_rate":"0.200000000000000000","max_change_rate":"0.100000000000000000"},"min_self_delegation":"1","delegator_address":"empower1vlan0w7pgm9h8xtfzm80uru497f7mpr8lcngmm","validator_address":"empowervaloper1vlan0w7pgm9h8xtfzm80uru497f7mpr88rd84w","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"xxTdBBjFfEW4XUVeV49KPeqZh2BcOCWd4ZSXxjP9XCU="},"value":{"denom":"umpwr","amount":"1000000"}}],"memo":"333de3fc2eba7eead24e0c5f53d665662b2ba001@10.132.0.11:26656","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A0x/ClNoUoWBtxLOJhcssoRr9VGAXzdLh8lz4Z9pudPb"},"mode_info":{"single":{"mode":"SIGN_MODE_DIRECT"}},"sequence":"0"}],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":["22QE249ylvRL226TgD3m+5q0fKU8Y6WgNWNucEU3d8An5V7wsGGa8NEjdHQFvZy5IVVm7xurx3VQvOeiDANmcA=="]} 2 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/types/message_create_proof.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "encoding/base64" 5 | 6 | sdk "github.com/cosmos/cosmos-sdk/types" 7 | sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" 8 | ) 9 | 10 | const TypeMsgCreateProof = "create_proof" 11 | 12 | var _ sdk.Msg = &MsgCreateProof{} 13 | 14 | func NewMsgCreateProof(reporter string, hash string) *MsgCreateProof { 15 | return &MsgCreateProof{ 16 | Reporter: reporter, 17 | Hash: hash, 18 | } 19 | } 20 | 21 | func (msg *MsgCreateProof) Route() string { 22 | return RouterKey 23 | } 24 | 25 | func (msg *MsgCreateProof) Type() string { 26 | return TypeMsgCreateProof 27 | } 28 | 29 | func (msg *MsgCreateProof) GetSigners() []sdk.AccAddress { 30 | reporter, err := sdk.AccAddressFromBech32(msg.Reporter) 31 | if err != nil { 32 | panic(err) 33 | } 34 | return []sdk.AccAddress{reporter} 35 | } 36 | 37 | func (msg *MsgCreateProof) GetSignBytes() []byte { 38 | bz := ModuleCdc.MustMarshalJSON(msg) 39 | return sdk.MustSortJSON(bz) 40 | } 41 | 42 | func (msg *MsgCreateProof) ValidateBasic() error { 43 | _, err := sdk.AccAddressFromBech32(msg.Reporter) 44 | if err != nil { 45 | return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid reporter address (%s)", err) 46 | } 47 | 48 | hashBytes, err := base64.StdEncoding.DecodeString(msg.Hash) 49 | if err != nil { 50 | return sdkerrors.Wrapf(ErrInvalidHash, "Hash %s is not base64 encoded", msg.Hash) 51 | } 52 | 53 | if len(hashBytes) != 32 { 54 | return sdkerrors.Wrapf(ErrInvalidHash, "Base 64-decoded hash %s is not SHA-256", msg.Hash) 55 | } 56 | 57 | return nil 58 | } 59 | -------------------------------------------------------------------------------- /chain/scripts/generate-docs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eo pipefail 4 | 5 | mkdir -p ./tmp-swagger-gen 6 | 7 | # move the vendor folder to a temp dir so that go list works properly 8 | temp_dir="f29ea6aa861dc4b083e8e48f67cce" 9 | if [ -d vendor ]; then 10 | mv ./vendor ./$temp_dir 11 | fi 12 | 13 | # Get the path of the cosmos-sdk repo from go/pkg/mod 14 | cosmos_sdk_dir=$(go list -f '{{ .Dir }}' -m github.com/cosmos/cosmos-sdk) 15 | 16 | # move the vendor folder back to ./vendor 17 | if [ -d $temp_dir ]; then 18 | mv ./$temp_dir ./vendor 19 | fi 20 | 21 | proto_dirs=$(find ./proto $cosmos_sdk_dir/proto -path -prune -o -name '*.proto' -print0 | xargs -0 -n1 dirname | sort | uniq) 22 | for dir in $proto_dirs; do 23 | # generate swagger files (filter query files) 24 | query_file=$(find "${dir}" -maxdepth 1 \( -name 'query.proto' -o -name 'service.proto' \)) 25 | if [[ ! -z "$query_file" ]]; then 26 | protoc \ 27 | -I "proto" \ 28 | -I "$cosmos_sdk_dir/third_party/proto" \ 29 | -I "$cosmos_sdk_dir/proto" \ 30 | "$query_file" \ 31 | --swagger_out ./tmp-swagger-gen \ 32 | --swagger_opt logtostderr=true \ 33 | --swagger_opt fqn_for_swagger_name=true \ 34 | --swagger_opt simple_operation_ids=true 35 | fi 36 | done 37 | 38 | # combine swagger files 39 | # uses nodejs package `swagger-combine`. 40 | # all the individual swagger files need to be configured in `config.json` for merging 41 | swagger-combine ./docs/config.json -o ./docs/swagger-ui/swagger.yaml -f yaml --continueOnConflictingPaths true --includeDefinitions true 42 | 43 | # clean swagger files 44 | #rm -rf ./tmp-swagger-gen 45 | -------------------------------------------------------------------------------- /chain/testutil/nullify/nullify.go: -------------------------------------------------------------------------------- 1 | // Package nullify provides methods to init nil values structs for test assertion. 2 | package nullify 3 | 4 | import ( 5 | "reflect" 6 | "unsafe" 7 | 8 | sdk "github.com/cosmos/cosmos-sdk/types" 9 | ) 10 | 11 | var ( 12 | coinType = reflect.TypeOf(sdk.Coin{}) 13 | coinsType = reflect.TypeOf(sdk.Coins{}) 14 | ) 15 | 16 | // Fill analyze all struct fields and slices with 17 | // reflection and initialize the nil and empty slices, 18 | // structs, and pointers. 19 | func Fill(x interface{}) interface{} { 20 | v := reflect.Indirect(reflect.ValueOf(x)) 21 | switch v.Kind() { 22 | case reflect.Slice: 23 | for i := 0; i < v.Len(); i++ { 24 | obj := v.Index(i) 25 | objPt := reflect.NewAt(obj.Type(), unsafe.Pointer(obj.UnsafeAddr())).Interface() 26 | objPt = Fill(objPt) 27 | obj.Set(reflect.ValueOf(objPt)) 28 | } 29 | case reflect.Struct: 30 | for i := 0; i < v.NumField(); i++ { 31 | f := reflect.Indirect(v.Field(i)) 32 | if !f.CanSet() { 33 | continue 34 | } 35 | switch f.Kind() { 36 | case reflect.Slice: 37 | f.Set(reflect.MakeSlice(f.Type(), 0, 0)) 38 | case reflect.Struct: 39 | switch f.Type() { 40 | case coinType: 41 | coin := reflect.New(coinType).Interface() 42 | s := reflect.ValueOf(coin).Elem() 43 | f.Set(s) 44 | case coinsType: 45 | coins := reflect.New(coinsType).Interface() 46 | s := reflect.ValueOf(coins).Elem() 47 | f.Set(s) 48 | default: 49 | objPt := reflect.NewAt(f.Type(), unsafe.Pointer(f.UnsafeAddr())).Interface() 50 | s := Fill(objPt) 51 | f.Set(reflect.ValueOf(s)) 52 | } 53 | } 54 | } 55 | } 56 | return reflect.Indirect(v).Interface() 57 | } 58 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/types/message_create_proof_test.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "encoding/base64" 5 | "fmt" 6 | "github.com/tendermint/tendermint/crypto" 7 | "testing" 8 | 9 | sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" 10 | "github.com/empowerchain/empowerchain/testutil/sample" 11 | "github.com/stretchr/testify/require" 12 | ) 13 | 14 | const testData = "This is just some random test data to be hashed. 42." 15 | 16 | func TestMsgCreateProof_ValidateBasic(t *testing.T) { 17 | hash := crypto.Sha256([]byte(testData)) 18 | hashb64 := base64.StdEncoding.EncodeToString(hash) 19 | 20 | tests := []struct { 21 | name string 22 | msg MsgCreateProof 23 | err error 24 | }{ 25 | { 26 | name: "invalid address", 27 | msg: MsgCreateProof{ 28 | Reporter: "invalid_address", 29 | Hash: hashb64, 30 | }, 31 | err: sdkerrors.ErrInvalidAddress, 32 | }, { 33 | name: "valid address and valid hash", 34 | msg: MsgCreateProof{ 35 | Reporter: sample.AccAddress(), 36 | Hash: hashb64, 37 | }, 38 | }, 39 | { 40 | name: "invalid base64", 41 | msg: MsgCreateProof{ 42 | Reporter: sample.AccAddress(), 43 | Hash: "this is not base64!", 44 | }, 45 | err: ErrInvalidHash, 46 | }, 47 | { 48 | name: "invalid hash", 49 | msg: MsgCreateProof{ 50 | Reporter: sample.AccAddress(), 51 | Hash: base64.StdEncoding.EncodeToString([]byte("this is not a hash!")), 52 | }, 53 | err: ErrInvalidHash, 54 | }, 55 | } 56 | for _, tt := range tests { 57 | fmt.Println(tt.name, tt.msg.Hash) 58 | t.Run(tt.name, func(t *testing.T) { 59 | err := tt.msg.ValidateBasic() 60 | if tt.err != nil { 61 | require.ErrorIs(t, err, tt.err) 62 | return 63 | } 64 | require.NoError(t, err) 65 | }) 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /chain/cmd/empowerd/cmd/testnet_test.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/empowerchain/empowerchain/app" 7 | "github.com/empowerchain/empowerchain/app/params" 8 | "testing" 9 | 10 | "github.com/cosmos/cosmos-sdk/client" 11 | "github.com/cosmos/cosmos-sdk/client/flags" 12 | "github.com/cosmos/cosmos-sdk/server" 13 | banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" 14 | genutiltest "github.com/cosmos/cosmos-sdk/x/genutil/client/testutil" 15 | genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" 16 | "github.com/spf13/viper" 17 | "github.com/stretchr/testify/require" 18 | "github.com/tendermint/tendermint/libs/log" 19 | ) 20 | 21 | func Test_TestnetCmd(t *testing.T) { 22 | home := t.TempDir() 23 | encodingConfig := params.MakeEncodingConfig(app.ModuleBasics) 24 | logger := log.NewNopLogger() 25 | cfg, err := genutiltest.CreateDefaultTendermintConfig(home) 26 | require.NoError(t, err) 27 | 28 | err = genutiltest.ExecInitCmd(app.ModuleBasics, home, encodingConfig.Codec) 29 | require.NoError(t, err) 30 | 31 | serverCtx := server.NewContext(viper.New(), cfg, logger) 32 | clientCtx := client.Context{}. 33 | WithCodec(encodingConfig.Codec). 34 | WithHomeDir(home). 35 | WithTxConfig(encodingConfig.TxConfig) 36 | 37 | ctx := context.Background() 38 | ctx = context.WithValue(ctx, server.ServerContextKey, serverCtx) 39 | ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) 40 | cmd := testnetCmd(app.ModuleBasics, banktypes.GenesisBalancesIterator{}) 41 | cmd.SetArgs([]string{fmt.Sprintf("--%s=test", flags.FlagKeyringBackend), fmt.Sprintf("--output-dir=%s", home)}) 42 | err = cmd.ExecuteContext(ctx) 43 | require.NoError(t, err) 44 | 45 | genFile := cfg.GenesisFile() 46 | appState, _, err := genutiltypes.GenesisStateFromGenFile(genFile) 47 | require.NoError(t, err) 48 | 49 | bankGenState := banktypes.GetGenesisStateFromAppState(encodingConfig.Codec, appState) 50 | require.NotEmpty(t, bankGenState.Supply.String()) 51 | } 52 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/keeper/grpc_query_test.go: -------------------------------------------------------------------------------- 1 | package keeper_test 2 | 3 | import ( 4 | "strconv" 5 | "testing" 6 | 7 | sdk "github.com/cosmos/cosmos-sdk/types" 8 | "github.com/stretchr/testify/require" 9 | "google.golang.org/grpc/codes" 10 | "google.golang.org/grpc/status" 11 | 12 | keepertest "github.com/empowerchain/empowerchain/testutil/keeper" 13 | "github.com/empowerchain/empowerchain/testutil/nullify" 14 | "github.com/empowerchain/empowerchain/x/proofofexistence/keeper" 15 | "github.com/empowerchain/empowerchain/x/proofofexistence/types" 16 | ) 17 | 18 | // Prevent strconv unused error 19 | var _ = strconv.IntSize 20 | 21 | func TestProofQuerySingle(t *testing.T) { 22 | k, ctx := keepertest.ProofofexistenceKeeper(t) 23 | q := keeper.Querier{Keeper: *k} 24 | wctx := sdk.WrapSDKContext(ctx) 25 | msgs := createNProof(k, ctx, 2) 26 | for _, tc := range []struct { 27 | desc string 28 | request *types.QueryGetProofRequest 29 | response *types.QueryGetProofResponse 30 | err error 31 | }{ 32 | { 33 | desc: "First", 34 | request: &types.QueryGetProofRequest{ 35 | Hash: msgs[0].Hash, 36 | }, 37 | response: &types.QueryGetProofResponse{Proof: msgs[0]}, 38 | }, 39 | { 40 | desc: "Second", 41 | request: &types.QueryGetProofRequest{ 42 | Hash: msgs[1].Hash, 43 | }, 44 | response: &types.QueryGetProofResponse{Proof: msgs[1]}, 45 | }, 46 | { 47 | desc: "KeyNotFound", 48 | request: &types.QueryGetProofRequest{ 49 | Hash: strconv.Itoa(100000), 50 | }, 51 | err: status.Error(codes.NotFound, "not found"), 52 | }, 53 | { 54 | desc: "InvalidRequest", 55 | err: status.Error(codes.InvalidArgument, "invalid request"), 56 | }, 57 | } { 58 | t.Run(tc.desc, func(t *testing.T) { 59 | response, err := q.Proof(wctx, tc.request) 60 | if tc.err != nil { 61 | require.ErrorIs(t, err, tc.err) 62 | } else { 63 | require.NoError(t, err) 64 | require.Equal(t, 65 | nullify.Fill(tc.response), 66 | nullify.Fill(response), 67 | ) 68 | } 69 | }) 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/keeper/proof.go: -------------------------------------------------------------------------------- 1 | package keeper 2 | 3 | import ( 4 | "github.com/cosmos/cosmos-sdk/store/prefix" 5 | sdk "github.com/cosmos/cosmos-sdk/types" 6 | sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" 7 | "github.com/empowerchain/empowerchain/x/proofofexistence/types" 8 | ) 9 | 10 | // CreateNewProof create a new proof from its hash 11 | func (k Keeper) CreateNewProof(ctx sdk.Context, hash string, reporter string) error { 12 | proof := types.Proof{ 13 | Hash: hash, 14 | Timestamp: ctx.BlockTime(), 15 | Reporter: reporter, 16 | } 17 | 18 | return k.SetProof(ctx, proof) 19 | } 20 | 21 | // SetProof persists a specific proof. Usually, you want to use CreateNewProof 22 | // SetProof is more useful for things like genesis setup 23 | func (k Keeper) SetProof(ctx sdk.Context, proof types.Proof) error { 24 | store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.ProofKeyPrefix)) 25 | key := types.ProofKey( 26 | proof.Hash, 27 | ) 28 | 29 | if store.Has(key) { 30 | return sdkerrors.Wrap(types.ErrHashExists, proof.Hash) 31 | } 32 | 33 | b := k.cdc.MustMarshal(&proof) 34 | store.Set(key, b) 35 | 36 | return nil 37 | } 38 | 39 | // GetProof returns a proof from its 'index' (hash in this case) 40 | func (k Keeper) GetProof( 41 | ctx sdk.Context, 42 | hash string, 43 | 44 | ) (val types.Proof, found bool) { 45 | store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.ProofKeyPrefix)) 46 | 47 | b := store.Get(types.ProofKey( 48 | hash, 49 | )) 50 | if b == nil { 51 | return val, false 52 | } 53 | 54 | k.cdc.MustUnmarshal(b, &val) 55 | return val, true 56 | } 57 | 58 | // GetAllProof returns all proofs 59 | func (k Keeper) GetAllProof(ctx sdk.Context) (list []types.Proof) { 60 | store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.ProofKeyPrefix)) 61 | iterator := sdk.KVStorePrefixIterator(store, []byte{}) 62 | 63 | defer iterator.Close() 64 | 65 | for ; iterator.Valid(); iterator.Next() { 66 | var val types.Proof 67 | k.cdc.MustUnmarshal(iterator.Value(), &val) 68 | list = append(list, val) 69 | } 70 | 71 | return 72 | } 73 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/client/cli/query_stored_proof_test.go: -------------------------------------------------------------------------------- 1 | package cli_test 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | "testing" 7 | 8 | clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" 9 | "github.com/stretchr/testify/require" 10 | tmcli "github.com/tendermint/tendermint/libs/cli" 11 | "google.golang.org/grpc/codes" 12 | "google.golang.org/grpc/status" 13 | 14 | "github.com/empowerchain/empowerchain/testutil/network" 15 | "github.com/empowerchain/empowerchain/testutil/nullify" 16 | "github.com/empowerchain/empowerchain/x/proofofexistence/client/cli" 17 | "github.com/empowerchain/empowerchain/x/proofofexistence/types" 18 | ) 19 | 20 | // Prevent strconv unused error 21 | var _ = strconv.IntSize 22 | 23 | func networkWithProofObjects(t *testing.T, n int) (*network.Network, []types.Proof) { 24 | t.Helper() 25 | cfg := network.DefaultConfig() 26 | state := types.GenesisState{} 27 | require.NoError(t, cfg.Codec.UnmarshalJSON(cfg.GenesisState[types.ModuleName], &state)) 28 | 29 | for i := 0; i < n; i++ { 30 | proof := types.Proof{ 31 | Hash: strconv.Itoa(i), 32 | } 33 | nullify.Fill(&proof) 34 | state.ProofList = append(state.ProofList, proof) 35 | } 36 | buf, err := cfg.Codec.MarshalJSON(&state) 37 | require.NoError(t, err) 38 | cfg.GenesisState[types.ModuleName] = buf 39 | return network.New(t, cfg), state.ProofList 40 | } 41 | 42 | func TestShowProof(t *testing.T) { 43 | net, objs := networkWithProofObjects(t, 2) 44 | 45 | ctx := net.Validators[0].ClientCtx 46 | common := []string{ 47 | fmt.Sprintf("--%s=json", tmcli.OutputFlag), 48 | } 49 | for _, tc := range []struct { 50 | desc string 51 | idHash string 52 | 53 | args []string 54 | err error 55 | obj types.Proof 56 | }{ 57 | { 58 | desc: "found", 59 | idHash: objs[0].Hash, 60 | 61 | args: common, 62 | obj: objs[0], 63 | }, 64 | { 65 | desc: "not found", 66 | idHash: strconv.Itoa(100000), 67 | 68 | args: common, 69 | err: status.Error(codes.NotFound, "not found"), 70 | }, 71 | } { 72 | t.Run(tc.desc, func(t *testing.T) { 73 | args := []string{ 74 | tc.idHash, 75 | } 76 | args = append(args, tc.args...) 77 | out, err := clitestutil.ExecTestCLICmd(ctx, cli.CmdShowProof(), args) 78 | if tc.err != nil { 79 | stat, ok := status.FromError(tc.err) 80 | require.True(t, ok) 81 | require.ErrorIs(t, stat.Err(), tc.err) 82 | } else { 83 | require.NoError(t, err) 84 | var resp types.QueryGetProofResponse 85 | require.NoError(t, net.Config.Codec.UnmarshalJSON(out.Bytes(), &resp)) 86 | require.NotNil(t, resp.Proof) 87 | require.Equal(t, 88 | nullify.Fill(&tc.obj), 89 | nullify.Fill(&resp.Proof), 90 | ) 91 | } 92 | }) 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/module_simulation.go: -------------------------------------------------------------------------------- 1 | package proofofexistence 2 | 3 | import ( 4 | "math/rand" 5 | 6 | "github.com/cosmos/cosmos-sdk/baseapp" 7 | simappparams "github.com/cosmos/cosmos-sdk/simapp/params" 8 | sdk "github.com/cosmos/cosmos-sdk/types" 9 | "github.com/cosmos/cosmos-sdk/types/module" 10 | simtypes "github.com/cosmos/cosmos-sdk/types/simulation" 11 | "github.com/cosmos/cosmos-sdk/x/simulation" 12 | "github.com/empowerchain/empowerchain/testutil/sample" 13 | proofofexistencesimulation "github.com/empowerchain/empowerchain/x/proofofexistence/simulation" 14 | "github.com/empowerchain/empowerchain/x/proofofexistence/types" 15 | ) 16 | 17 | // avoid unused import issue 18 | var ( 19 | _ = sample.AccAddress 20 | _ = proofofexistencesimulation.FindAccount 21 | _ = simappparams.StakePerAccount 22 | _ = simulation.MsgEntryKind 23 | _ = baseapp.Paramspace 24 | ) 25 | 26 | const ( 27 | opWeightMsgCreate = "op_weight_msg_create" 28 | // TODO: Determine the simulation weight value 29 | defaultWeightMsgCreate int = 100 30 | ) 31 | 32 | // GenerateGenesisState creates a randomized GenState of the module 33 | func (AppModule) GenerateGenesisState(simState *module.SimulationState) { 34 | accs := make([]string, len(simState.Accounts)) 35 | for i, acc := range simState.Accounts { 36 | accs[i] = acc.Address.String() 37 | } 38 | proofofexistenceGenesis := types.GenesisState{} 39 | simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(&proofofexistenceGenesis) 40 | } 41 | 42 | // ProposalContents doesn't return any content functions for governance proposals 43 | func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalContent { 44 | return nil 45 | } 46 | 47 | // RandomizedParams creates randomized param changes for the simulator 48 | func (am AppModule) RandomizedParams(_ *rand.Rand) []simtypes.ParamChange { 49 | return []simtypes.ParamChange{} 50 | } 51 | 52 | // RegisterStoreDecoder registers a decoder 53 | func (am AppModule) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) {} 54 | 55 | // WeightedOperations returns the all the gov module operations with their respective weights. 56 | func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation { 57 | operations := make([]simtypes.WeightedOperation, 0) 58 | 59 | var weightMsgCreate int 60 | simState.AppParams.GetOrGenerate(simState.Cdc, opWeightMsgCreate, &weightMsgCreate, nil, 61 | func(_ *rand.Rand) { 62 | weightMsgCreate = defaultWeightMsgCreate 63 | }, 64 | ) 65 | operations = append(operations, simulation.NewWeightedOperation( 66 | weightMsgCreate, 67 | proofofexistencesimulation.SimulateMsgCreate(am.accountKeeper, am.bankKeeper, am.keeper), 68 | )) 69 | 70 | return operations 71 | } 72 | -------------------------------------------------------------------------------- /chain/scripts/serve.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | source scripts/serve_env.sh 5 | 6 | # Stop if it is already running 7 | if pgrep -x "$BINARY" >/dev/null; then 8 | echo "Terminating $BINARY..." 9 | killall $BINARY 10 | fi 11 | 12 | echo "Removing previous data..." 13 | rm -rf $CHAIN_DIR &> /dev/null 14 | 15 | # Add directories for chain(s), exit if an error occurs 16 | if ! mkdir -p $CHAIN_DIR 2>/dev/null; then 17 | echo "Failed to create chain folder. Aborting..." 18 | exit 1 19 | fi 20 | 21 | echo "Initializing $CHAIN_ID..." 22 | $BINARY init test --home $CHAIN_DIR --chain-id=$CHAIN_ID 23 | 24 | echo "Adding genesis accounts..." 25 | echo "$ALICE_MNEMONIC" | $BINARY keys add alice --home $CHAIN_DIR --recover --keyring-backend=test 26 | echo "$BOB_MNEMONIC" | $BINARY keys add bob --home $CHAIN_DIR --recover --keyring-backend=test 27 | echo "$VALIDATOR_MNEMONIC" | $BINARY keys add validator --home $CHAIN_DIR --recover --keyring-backend=test 28 | 29 | $BINARY add-genesis-account $($BINARY --home $CHAIN_DIR keys show alice --keyring-backend test -a) 100000000000stake --home $CHAIN_DIR 30 | $BINARY add-genesis-account $($BINARY --home $CHAIN_DIR keys show bob --keyring-backend test -a) 100000000000stake --home $CHAIN_DIR 31 | $BINARY add-genesis-account $($BINARY --home $CHAIN_DIR keys show validator --keyring-backend test -a) 100000000000stake --home $CHAIN_DIR 32 | 33 | $BINARY gentx validator 7000000000stake --home $CHAIN_DIR --chain-id $CHAIN_ID --keyring-backend test 34 | $BINARY collect-gentxs --home $CHAIN_DIR 35 | 36 | echo "Changing defaults and ports in app.toml and config.toml files..." 37 | sed -i -e 's#"tcp://0.0.0.0:26656"#"tcp://0.0.0.0:'"$P2P_PORT"'"#g' $CHAIN_DIR/config/config.toml 38 | sed -i -e 's#"tcp://127.0.0.1:26657"#"tcp://0.0.0.0:'"$RPC_PORT"'"#g' $CHAIN_DIR/config/config.toml 39 | sed -i -e 's/timeout_commit = "5s"/timeout_commit = "1s"/g' $CHAIN_DIR/config/config.toml 40 | sed -i -e 's/timeout_propose = "3s"/timeout_propose = "1s"/g' $CHAIN_DIR/config/config.toml 41 | sed -i -e 's/index_all_keys = false/index_all_keys = true/g' $CHAIN_DIR/config/config.toml 42 | sed -i -e 's/enable = false/enable = true/g' $CHAIN_DIR/config/app.toml 43 | sed -i -e 's/swagger = false/swagger = true/g' $CHAIN_DIR/config/app.toml 44 | sed -i -e 's#"tcp://0.0.0.0:1317"#"tcp://0.0.0.0:'"$REST_PORT"'"#g' $CHAIN_DIR/config/app.toml 45 | sed -i -e 's#":8080"#":'"$ROSETTA_PORT"'"#g' $CHAIN_DIR/config/app.toml 46 | sed -i -e 's/enable-unsafe-cors = false/enable-unsafe-cors = true/g' $CHAIN_DIR/config/app.toml 47 | sed -i -e 's/enabled-unsafe-cors = false/enable-unsafe-cors = true/g' $CHAIN_DIR/config/app.toml 48 | 49 | echo "Starting $CHAIN_ID in $CHAIN_DIR..." 50 | echo "Creating log file at $LOG_FILE_PATH" 51 | $BINARY start --log_level trace --log_format json --home $CHAIN_DIR --pruning=nothing --rpc.unsafe --grpc.address="0.0.0.0:$GRPC_PORT" --grpc-web.address="0.0.0.0:$GRPC_WEB" > $LOG_FILE_PATH 2>&1 & 52 | 53 | sleep 3 54 | 55 | if ! $BINARY --home $CHAIN_DIR --node tcp://:$RPC_PORT status; then 56 | echo "Chain failed to start" 57 | fi 58 | 59 | echo "Chain started!" 60 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ "main" ] 17 | paths: 18 | - 'chain/**' 19 | pull_request: 20 | # The branches below must be a subset of the branches above 21 | branches: [ "main" ] 22 | paths: 23 | - 'chain/**' 24 | schedule: 25 | - cron: '17 11 * * 2' 26 | 27 | jobs: 28 | analyze: 29 | name: Analyze 30 | runs-on: ubuntu-latest 31 | permissions: 32 | actions: read 33 | contents: read 34 | security-events: write 35 | 36 | strategy: 37 | fail-fast: false 38 | matrix: 39 | language: [ 'go' ] 40 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 41 | # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support 42 | 43 | steps: 44 | - name: Checkout repository 45 | uses: actions/checkout@v3 46 | 47 | # Initializes the CodeQL tools for scanning. 48 | - name: Initialize CodeQL 49 | uses: github/codeql-action/init@v2 50 | with: 51 | languages: ${{ matrix.language }} 52 | # If you wish to specify custom queries, you can do so here or in a config file. solved it smoothly. 53 | # By default, queries listed here will override any specified in a config file. 54 | # Prefix the list here with "+" to use these queries and those in the config file. 55 | 56 | # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs 57 | # queries: security-extended,security-and-quality 58 | 59 | 60 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 61 | # If this step fails, then you should remove it and run the build manually (see below) 62 | - name: Autobuild 63 | uses: github/codeql-action/autobuild@v2 64 | 65 | # ℹ️ Command-line programs to run using the OS shell. 66 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun 67 | 68 | # If the Autobuild fails above, remove it and uncomment the following three lines. 69 | # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. 70 | 71 | # - run: | 72 | # echo "Run, Build Application using script" 73 | # ./location_of_script_within_repo/buildscript.sh 74 | 75 | - name: Perform CodeQL Analysis 76 | uses: github/codeql-action/analyze@v2 77 | -------------------------------------------------------------------------------- /chain/testutil/network/network.go: -------------------------------------------------------------------------------- 1 | package network 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | "time" 7 | 8 | "github.com/cosmos/cosmos-sdk/baseapp" 9 | "github.com/cosmos/cosmos-sdk/crypto/hd" 10 | "github.com/cosmos/cosmos-sdk/crypto/keyring" 11 | pruningtypes "github.com/cosmos/cosmos-sdk/pruning/types" 12 | servertypes "github.com/cosmos/cosmos-sdk/server/types" 13 | "github.com/cosmos/cosmos-sdk/simapp" 14 | "github.com/cosmos/cosmos-sdk/testutil/network" 15 | sdk "github.com/cosmos/cosmos-sdk/types" 16 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" 17 | "github.com/stretchr/testify/require" 18 | tmrand "github.com/tendermint/tendermint/libs/rand" 19 | tmdb "github.com/tendermint/tm-db" 20 | 21 | "github.com/empowerchain/empowerchain/app" 22 | "github.com/empowerchain/empowerchain/app/params" 23 | ) 24 | 25 | type ( 26 | Network = network.Network 27 | Config = network.Config 28 | ) 29 | 30 | // New creates instance with fully configured cosmos network. 31 | // Accepts optional config, that will be used in place of the DefaultConfig() if provided. 32 | func New(t *testing.T, configs ...network.Config) *network.Network { 33 | if len(configs) > 1 { 34 | panic("at most one config should be provided") 35 | } 36 | var cfg network.Config 37 | if len(configs) == 0 { 38 | cfg = DefaultConfig() 39 | } else { 40 | cfg = configs[0] 41 | } 42 | net, err := network.New(t, t.TempDir(), cfg) 43 | require.NoError(t, err) 44 | 45 | t.Cleanup(net.Cleanup) 46 | return net 47 | } 48 | 49 | // DefaultConfig will initialize config for the network with custom application, 50 | // genesis and single validator. All other parameters are inherited from cosmos-sdk/testutil/network.DefaultConfig 51 | func DefaultConfig() network.Config { 52 | encoding := params.MakeEncodingConfig(app.ModuleBasics) 53 | return network.Config{ 54 | Codec: encoding.Codec, 55 | TxConfig: encoding.TxConfig, 56 | LegacyAmino: encoding.Amino, 57 | InterfaceRegistry: encoding.InterfaceRegistry, 58 | AccountRetriever: authtypes.AccountRetriever{}, 59 | AppConstructor: func(val network.Validator) servertypes.Application { 60 | return app.New( 61 | val.Ctx.Logger, tmdb.NewMemDB(), nil, true, map[int64]bool{}, val.Ctx.Config.RootDir, 0, 62 | encoding, 63 | simapp.EmptyAppOptions{}, 64 | baseapp.SetPruning(pruningtypes.NewPruningOptionsFromString(val.AppConfig.Pruning)), 65 | baseapp.SetMinGasPrices(val.AppConfig.MinGasPrices), 66 | ) 67 | }, 68 | GenesisState: app.ModuleBasics.DefaultGenesis(encoding.Codec), 69 | TimeoutCommit: 2 * time.Second, 70 | ChainID: "chain-" + tmrand.NewRand().Str(6), 71 | NumValidators: 1, 72 | BondDenom: sdk.DefaultBondDenom, 73 | MinGasPrices: fmt.Sprintf("0.000006%s", sdk.DefaultBondDenom), 74 | AccountTokens: sdk.TokensFromConsensusPower(1000, sdk.DefaultPowerReduction), 75 | StakingTokens: sdk.TokensFromConsensusPower(500, sdk.DefaultPowerReduction), 76 | BondedTokens: sdk.TokensFromConsensusPower(100, sdk.DefaultPowerReduction), 77 | PruningStrategy: pruningtypes.PruningOptionNothing, 78 | CleanupDir: true, 79 | SigningAlgo: string(hd.Secp256k1Type), 80 | KeyringOptions: []keyring.Option{}, 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/keeper/proof_test.go: -------------------------------------------------------------------------------- 1 | package keeper_test 2 | 3 | import ( 4 | "encoding/base64" 5 | sdk "github.com/cosmos/cosmos-sdk/types" 6 | "github.com/empowerchain/empowerchain/testutil/sample" 7 | "github.com/empowerchain/empowerchain/x/proofofexistence/keeper" 8 | "github.com/empowerchain/empowerchain/x/proofofexistence/types" 9 | "github.com/tendermint/tendermint/crypto" 10 | "strconv" 11 | "testing" 12 | "time" 13 | 14 | keepertest "github.com/empowerchain/empowerchain/testutil/keeper" 15 | "github.com/stretchr/testify/require" 16 | ) 17 | 18 | func createNProof(k *keeper.Keeper, ctx sdk.Context, n int) []types.Proof { 19 | items := make([]types.Proof, n) 20 | for i := range items { 21 | hash, reporter := createTestProofData(strconv.Itoa(i)) 22 | items[i].Hash = hash 23 | items[i].Reporter = reporter 24 | items[i].Timestamp = time.Unix(1657454750+int64(i*25), 0).UTC() 25 | 26 | if err := k.SetProof(ctx, items[i]); err != nil { 27 | panic(err) 28 | } 29 | } 30 | return items 31 | } 32 | 33 | func createTestProofData(data string) (hash string, reporter string) { 34 | hashb := crypto.Sha256([]byte(data)) 35 | hash = base64.StdEncoding.EncodeToString(hashb) 36 | reporter = sample.AccAddress() 37 | 38 | return hash, reporter 39 | } 40 | 41 | func TestCreateNewProof(t *testing.T) { 42 | k, ctx := keepertest.ProofofexistenceKeeper(t) 43 | hash, reporter := createTestProofData("my test data") 44 | 45 | err := k.CreateNewProof(ctx, hash, reporter) 46 | require.NoError(t, err) 47 | 48 | proof, found := k.GetProof(ctx, hash) 49 | require.True(t, found) 50 | require.Equal(t, reporter, proof.Reporter) 51 | require.Equal(t, hash, proof.Hash) 52 | require.Equal(t, ctx.BlockTime(), proof.Timestamp) 53 | } 54 | 55 | func TestCreateNewProofWithExistingHash(t *testing.T) { 56 | k, ctx := keepertest.ProofofexistenceKeeper(t) 57 | hash, reporter := createTestProofData("42") 58 | 59 | err := k.CreateNewProof(ctx, hash, reporter) 60 | require.NoError(t, err) 61 | 62 | err = k.CreateNewProof(ctx, hash, reporter) 63 | require.ErrorIs(t, err, types.ErrHashExists) 64 | } 65 | 66 | func TestGetProof(t *testing.T) { 67 | k, ctx := keepertest.ProofofexistenceKeeper(t) 68 | hash, reporter := createTestProofData("69") 69 | 70 | _, found := k.GetProof(ctx, hash) 71 | require.False(t, found) 72 | 73 | err := k.CreateNewProof(ctx, hash, reporter) 74 | require.NoError(t, err) 75 | 76 | proof, found := k.GetProof(ctx, hash) 77 | require.True(t, found) 78 | require.Equal(t, reporter, proof.Reporter) 79 | require.Equal(t, hash, proof.Hash) 80 | require.Equal(t, ctx.BlockTime(), proof.Timestamp) 81 | } 82 | 83 | func TestGetAllProof(t *testing.T) { 84 | k, ctx := keepertest.ProofofexistenceKeeper(t) 85 | proofs := createNProof(k, ctx, 36) 86 | got := k.GetAllProof(ctx) 87 | 88 | require.Equal(t, len(proofs), len(got)) 89 | 90 | for _, p := range proofs { 91 | found := false 92 | for _, g := range got { 93 | if p.Hash == g.Hash && p.Reporter == g.Reporter && p.Timestamp == g.Timestamp { 94 | found = true 95 | break 96 | } 97 | } 98 | require.Truef(t, found, "Proof %v was not found", p) 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/spec/01_concepts.md: -------------------------------------------------------------------------------- 1 | # Concepts 2 | 3 | ## Proof of Existence 4 | 5 | Sometimes also called "constructive proof" or "existence proof" in mathematics and is a method of proof that 6 | demonstrates the existence of a mathematical object by creating or providing a method for creating the object. 7 | In our case, it is a way for someone to prove that some piece of data (document, text, bytes, etc) 8 | existed at a specific point in time (and has not changed since). 9 | 10 | A proof of existence is a combination of a hash and a timestamp where both are immutable (and everyone trusts 11 | that they are in fact immutable). Given a piece of data that was hashed and that hash was stored on an immutable blockchain, 12 | anyone who has the same data can at any time prove to themselves or other that the data existed at the point the proof was added on-chain. 13 | 14 | An important property of Proof of Existence is also that you don't need to provide the data itself until 15 | a verification of proof is needed. In other words, all that is stored on-chain is the proof, which cannot be used 16 | to re-create the original data. 17 | 18 | The typical examples include: 19 | - Demonstrating data/IP ownership 20 | - Proving data has not changed/been corrupted 21 | - Document integrity 22 | 23 | ## Hashing 24 | 25 | A cryptographic hash is the output of a mathematical hashing function that turns (maps) a variably sized piece of data 26 | into a small, practically unique, fixed size unique string ("the hash"). 27 | Traditionally these hashes are used for security purposes such as avoiding to store passwords in 28 | databases for software services (instead they just store a hash of the password that was provided 29 | when the user registered, and then check the provided password upon login with the stored hash). 30 | 31 | The way hashes are used in Proof of Existence is in combination with the immutability of a Blockchain. 32 | When someone needs to verify some data they can find the hash on the blockchain and compare it to the data they have themselves. 33 | They only need to run the data through the same hashing function and compare their output with the hash stored on the blockchain. 34 | If they are the same, the data has not been altered and existed at the time the transaction was entered into the blockchain. 35 | 36 | ## Hash collision 37 | 38 | Whenever you map something large (or at least larger than the output) into something small there will also be the 39 | theoretical possibility of collisions, where two different datasets yield the same result. 40 | In other words it is theoretically possible to have one hash function as the correct proof for more than one set of data. 41 | To illustrate this we can take as example the widely used SHA-256 hashing algorithm: 42 | It produces a hash made out of 32 bytes (1 byte is 8 bits, so a total of 256 bits) 43 | and each byte can each represent 256 different values. The total number of possible 44 | permutations under SHA-256 then becomes 32^256. That is such an absurdly large number 45 | (it is a number so large that it has 386 digits and is more than 10^56 (or just about 3 septendecillion) 46 | times larger than the number of atoms in the universe) that any practical chances of a collision is just about inconceivable. -------------------------------------------------------------------------------- /chain/cmd/empowerd/cmd/genaccounts_test.go: -------------------------------------------------------------------------------- 1 | package cmd_test 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "testing" 7 | 8 | "github.com/cosmos/cosmos-sdk/crypto/hd" 9 | "github.com/cosmos/cosmos-sdk/crypto/keyring" 10 | sdk "github.com/cosmos/cosmos-sdk/types" 11 | "github.com/empowerchain/empowerchain/app" 12 | "github.com/empowerchain/empowerchain/app/params" 13 | 14 | "github.com/cosmos/cosmos-sdk/client" 15 | "github.com/cosmos/cosmos-sdk/client/flags" 16 | "github.com/cosmos/cosmos-sdk/server" 17 | "github.com/cosmos/cosmos-sdk/testutil/testdata" 18 | "github.com/cosmos/cosmos-sdk/types/module" 19 | "github.com/cosmos/cosmos-sdk/x/genutil" 20 | genutiltest "github.com/cosmos/cosmos-sdk/x/genutil/client/testutil" 21 | empowercmd "github.com/empowerchain/empowerchain/cmd/empowerd/cmd" 22 | "github.com/spf13/viper" 23 | "github.com/stretchr/testify/require" 24 | "github.com/tendermint/tendermint/libs/log" 25 | ) 26 | 27 | var testMbm = module.NewBasicManager(genutil.AppModuleBasic{}) 28 | 29 | func TestAddGenesisAccountCmd(t *testing.T) { 30 | _, _, addr1 := testdata.KeyTestPubAddr() 31 | tests := []struct { 32 | name string 33 | addr string 34 | denom string 35 | withKeyring bool 36 | expectErr bool 37 | }{ 38 | { 39 | name: "invalid address", 40 | addr: "", 41 | denom: "1000atom", 42 | withKeyring: false, 43 | expectErr: true, 44 | }, 45 | { 46 | name: "valid address", 47 | addr: addr1.String(), 48 | denom: "1000atom", 49 | withKeyring: false, 50 | expectErr: false, 51 | }, 52 | { 53 | name: "multiple denoms", 54 | addr: addr1.String(), 55 | denom: "1000atom, 2000stake", 56 | withKeyring: false, 57 | expectErr: false, 58 | }, 59 | { 60 | name: "with keyring", 61 | addr: "ser", 62 | denom: "1000atom", 63 | withKeyring: true, 64 | expectErr: false, 65 | }, 66 | } 67 | 68 | for _, tc := range tests { 69 | tc := tc 70 | t.Run(tc.name, func(t *testing.T) { 71 | home := t.TempDir() 72 | logger := log.NewNopLogger() 73 | cfg, err := genutiltest.CreateDefaultTendermintConfig(home) 74 | require.NoError(t, err) 75 | 76 | appCodec := params.MakeEncodingConfig(app.ModuleBasics).Codec 77 | err = genutiltest.ExecInitCmd(testMbm, home, appCodec) 78 | require.NoError(t, err) 79 | 80 | serverCtx := server.NewContext(viper.New(), cfg, logger) 81 | clientCtx := client.Context{}.WithCodec(appCodec).WithHomeDir(home) 82 | 83 | if tc.withKeyring { 84 | path := hd.CreateHDPath(118, 0, 0).String() 85 | kr, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendMemory, home, nil, appCodec) 86 | require.NoError(t, err) 87 | _, _, err = kr.NewMnemonic(tc.addr, keyring.English, path, keyring.DefaultBIP39Passphrase, hd.Secp256k1) 88 | require.NoError(t, err) 89 | clientCtx = clientCtx.WithKeyring(kr) 90 | } 91 | 92 | ctx := context.Background() 93 | ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) 94 | ctx = context.WithValue(ctx, server.ServerContextKey, serverCtx) 95 | 96 | cmd := empowercmd.AddGenesisAccountCmd(home) 97 | cmd.SetArgs([]string{ 98 | tc.addr, 99 | tc.denom, 100 | fmt.Sprintf("--%s=home", flags.FlagHome)}) 101 | 102 | if tc.expectErr { 103 | require.Error(t, cmd.ExecuteContext(ctx)) 104 | } else { 105 | require.NoError(t, cmd.ExecuteContext(ctx)) 106 | } 107 | }) 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /chain/.golangci.yml: -------------------------------------------------------------------------------- 1 | run: 2 | tests: false 3 | # # timeout for analysis, e.g. 30s, 5m, default is 1m 4 | # timeout: 5m 5 | 6 | linters: 7 | disable-all: true 8 | # Enable specific linter 9 | # https://golangci-lint.run/usage/linters/#enabled-by-default-linters 10 | enable: 11 | - asciicheck 12 | - bidichk 13 | # - bodyclose <- needs go 1.18 support 14 | # - contextcheck <- needs go 1.18 support 15 | # - cyclop 16 | - depguard 17 | # - dogsled <- disabled because we would like to participate in the iditerod 18 | # - dupl <- really just catches cli stub text 19 | - durationcheck 20 | - errcheck 21 | - errname 22 | # - errorlint <- later 23 | # - exhaustive <- too picky 24 | # - exhaustivestruct <- disabled because we don't want to use every element of every struct 25 | - exportloopref 26 | # - forbidigo <- forbids fmt.Print* by default 27 | - forcetypeassert 28 | # - funlen <- some of our functions are longer than this by necessity 29 | # - gci <- questionable utility 30 | # - gochecknoglobals <- disabled because we want some globals 31 | # - gochecknoinits <- disabled because we want to use init() 32 | # - gocognit <- disabled for same reason as gocyclo 33 | - goconst 34 | # - gocritic <- re enable later to catch capitalized local variables 35 | # - gocyclo <- disabled because it won't work with how we cosmos 36 | # - godot 37 | # - godox <- detects TODO/BUG/FIXME and we may wantnthis later but isn't appropriate now 38 | # - goerr113 <- disabled due to lack of comprehension 39 | - gofmt 40 | # - gofumpt <- disabled https://github.com/osmosis-labs/osmosis/issues/1309 41 | - goheader 42 | - goimports 43 | # - gomoddirectives <- disables replaces 44 | - gomodguard 45 | - goprintffuncname 46 | # - gosec <- triggers too much for this round and should be re-enabled later 47 | - gosimple # specializes in simplifying code, subset of staticcheck binary. 48 | - govet 49 | # - ifshort <- questionable value, unclear if globally helping readability. 50 | - importas 51 | - ineffassign 52 | # - ireturn <- disabled because we want to return interfaces 53 | # - lll <- disabled as it is a bit much. Maybe we have a desired limit? 54 | - makezero 55 | - misspell 56 | - nakedret 57 | # - nestif <- ? 58 | # - nilerr <- needs go 1.18 support 59 | - nilnil 60 | # - nlreturn <- disabled as it doesn't auto-fix something simple and doesn't add anything useful 61 | # - noctx <- needs go 1.18 support 62 | # - nolintlint <- disabled because we use nolint in some places 63 | - paralleltest 64 | # - prealloc <- disabled because it makes simple code complicated 65 | # - predeclared <- later 66 | - promlinter 67 | # - revive <- temporarily disabled while jacob figures out how to make poolId not trigger it. 68 | # - rowserrcheck <- needs go 1.18 support 69 | # - sqlclosecheck <- needs go 1.18 support 70 | - staticcheck # set of rules from staticcheck, subset of staticcheck binary. 71 | - stylecheck # replacement of golint, subset of staticcheck binary. 72 | # - tagliatelle <- disabled for defying cosmos idiom 73 | - tenv 74 | - testpackage 75 | # - thelper <- later 76 | # - tparallel <- needs go 1.18 support 77 | - typecheck 78 | - unconvert 79 | # - unparam <- looks for unused parameters (enable later) 80 | - unused # looks for unused variables, subset of staticcheck binary. 81 | # - varnamelen <- disabled because defies idiom 82 | # - wastedassign 83 | - whitespace 84 | # - wrapcheck 85 | # - wsl 86 | 87 | #issues: 88 | # exclude-rules: 89 | # - linters: 90 | # - staticcheck 91 | # text: "SA1024: cutset contains duplicate characters" # proved to not provide much value, only false positives. 92 | # - linters: 93 | # - staticcheck 94 | # text: "SA9004: only the first constant in this group has an explicit type" # explicitly recommended in go syntax 95 | # - linters: 96 | # - stylecheck 97 | # text: "ST1003:" # requires identifiers with "id" to be "ID". 98 | # - linters: 99 | # - stylecheck 100 | # text: "ST1005:" # punctuation in error messages 101 | # max-issues-per-linter: 10000 102 | # max-same-issues: 10000 -------------------------------------------------------------------------------- /testnets/altruistic-1/README.md: -------------------------------------------------------------------------------- 1 | ![empower](https://user-images.githubusercontent.com/104348282/192093493-67779857-653e-4018-8c78-49530690f7a0.png) 2 | 3 | # Prepare testnet altruistic-1 4 | **Update packages and install required packages** 5 | ```bash 6 | sudo apt update && sudo apt upgrade -y && \ 7 | sudo apt install curl tar wget clang pkg-config libssl-dev jq build-essential bsdmainutils git make ncdu gcc git jq chrony liblz4-tool -y 8 | ``` 9 | 10 | **Install Go 1.18.3** 11 | ```bash 12 | cd $HOME && version="1.18.3" && \ 13 | wget "https://golang.org/dl/go$version.linux-amd64.tar.gz" && \ 14 | sudo rm -rf /usr/local/go && \ 15 | sudo tar -C /usr/local -xzf "go$version.linux-amd64.tar.gz" && \ 16 | rm "go$version.linux-amd64.tar.gz" && \ 17 | echo "export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin" >> $HOME/.bash_profile && \ 18 | source $HOME/.bash_profile && \ 19 | go version 20 | ``` 21 | 22 | **Install binary empowerd** 23 | ```bash 24 | cd $HOME && git clone https://github.com/empowerchain/empowerchain && \ 25 | cd empowerchain/chain && \ 26 | make install && \ 27 | empowerd version --long | head 28 | ``` 29 | 30 | **Init moniker and set chain-id** 31 | ```bash 32 | empowerd init --chain-id altruistic-1 && \ 33 | empowerd config chain-id altruistic-1 34 | ``` 35 | 36 | **Create wallet** 37 | ```bash 38 | empowerd keys add 39 | ``` 40 | 🔴 **Save the mnemonic of your wallet!** 41 | 42 | **Add genesis account** 43 | ```bash 44 | empowerd add-genesis-account 1000000umpwr 45 | ``` 46 | 47 | **Create gentx** 48 | ```bash 49 | empowerd gentx 1000000umpwr \ 50 | --chain-id=altruistic-1 \ 51 | --moniker="" \ 52 | --commission-max-change-rate 0.1 \ 53 | --commission-max-rate 0.2 \ 54 | --commission-rate 0.05 \ 55 | --pubkey $(empowerd tendermint show-validator) \ 56 | --website="" \ 57 | --security-contact="" \ 58 | --identity="" \ 59 | --details="" 60 | ``` 61 | 62 | After executing this command, you have a gentx. Submit a pull request (gentx folder) with the given gentx 63 | ```bash 64 | File Genesis transaction written to "/.empowerchain/config/gentx/gentx-xxx.json" 65 | ``` 66 | 🟡 Save **priv_validator_key.json** in **config** folder! 67 | 68 |

Preparing to launch altruistic-1 (for those who are in genesis)

69 | 70 | **Download genesis altruistic-1** 71 | ```bash 72 | rm -rf $HOME/.empowerchain/config/genesis.json && cd $HOME/.empowerchain/config && wget https://raw.githubusercontent.com/empowerchain/empowerchain/main/testnets/altruistic-1/genesis.json 73 | ``` 74 | 75 | **Unnsafe-reset-all** 76 | ```bash 77 | empowerd tendermint unsafe-reset-all --home $HOME/.empowerchain 78 | ``` 79 | 80 | **Check genesis** 81 | ```bash 82 | sha256sum $HOME/.empowerchain/config/genesis.json 83 | ``` 84 | Result: fcae4a283488be14181fdc55f46705d9e11a32f8e3e8e25da5374914915d5ca8 85 | 86 | **Create a service file** 87 | ```bash 88 | sudo tee /etc/systemd/system/empowerd.service > /dev/null < NUL) 21 | ifeq ($(GCCEXE),) 22 | $(error gcc.exe not installed for ledger support, please install or set LEDGER_ENABLED=false) 23 | else 24 | build_tags += ledger 25 | endif 26 | else 27 | UNAME_S = $(shell uname -s) 28 | ifeq ($(UNAME_S),OpenBSD) 29 | $(warning OpenBSD detected, disabling ledger support (https://github.com/cosmos/cosmos-sdk/issues/1988)) 30 | else 31 | GCC = $(shell command -v gcc 2> /dev/null) 32 | ifeq ($(GCC),) 33 | $(error gcc not installed for ledger support, please install or set LEDGER_ENABLED=false) 34 | else 35 | build_tags += ledger 36 | endif 37 | endif 38 | endif 39 | endif 40 | 41 | ifeq (cleveldb,$(findstring cleveldb,$(EMPOWER_BUILD_OPTIONS))) 42 | build_tags += gcc 43 | else ifeq (rocksdb,$(findstring rocksdb,$(EMPOWER_BUILD_OPTIONS))) 44 | build_tags += gcc 45 | endif 46 | build_tags += $(BUILD_TAGS) 47 | build_tags := $(strip $(build_tags)) 48 | 49 | whitespace := 50 | whitespace += $(whitespace) 51 | comma := , 52 | build_tags_comma_sep := $(subst $(whitespace),$(comma),$(build_tags)) 53 | 54 | # process linker flags 55 | 56 | ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=$(CHAIN_NAME) \ 57 | -X github.com/cosmos/cosmos-sdk/version.AppName=$(BINARY_NAME) \ 58 | -X github.com/cosmos/cosmos-sdk/version.Version=$(VERSION) \ 59 | -X github.com/cosmos/cosmos-sdk/version.Commit=$(COMMIT) \ 60 | -X "github.com/cosmos/cosmos-sdk/version.BuildTags=$(build_tags_comma_sep)" 61 | 62 | ifeq (cleveldb,$(findstring cleveldb,$(EMPOWER_BUILD_OPTIONS))) 63 | ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=cleveldb 64 | else ifeq (rocksdb,$(findstring rocksdb,$(EMPOWER_BUILD_OPTIONS))) 65 | ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=rocksdb 66 | endif 67 | ifeq (,$(findstring nostrip,$(EMPOWER_BUILD_OPTIONS))) 68 | ldflags += -w -s 69 | endif 70 | ifeq ($(LINK_STATICALLY),true) 71 | ldflags += -linkmode=external -extldflags "-Wl,-z,muldefs -static" 72 | endif 73 | ldflags += $(LDFLAGS) 74 | ldflags := $(strip $(ldflags)) 75 | 76 | BUILD_FLAGS := -tags "$(build_tags)" -ldflags '$(ldflags)' 77 | # check for nostrip option 78 | ifeq (,$(findstring nostrip,$(EMPOWER_BUILD_OPTIONS))) 79 | BUILD_FLAGS += -trimpath 80 | endif 81 | 82 | ############################################################################### 83 | ### Build ### 84 | ############################################################################### 85 | 86 | ver: 87 | @echo $(VERSION) 88 | 89 | all: install lint test 90 | 91 | BUILD_TARGETS := build install 92 | 93 | build: BUILD_ARGS=-o $(BUILD_DIR)/ 94 | 95 | $(BUILD_TARGETS): go.sum $(BUILD_DIR)/ 96 | go $@ -mod=readonly $(BUILD_FLAGS) $(BUILD_ARGS) ./... 97 | 98 | $(BUILD_DIR)/: 99 | mkdir -p $(BUILD_DIR)/ 100 | 101 | build-linux: go.sum 102 | LEDGER_ENABLED=false GOOS=linux GOARCH=amd64 $(MAKE) build 103 | 104 | go-mod-cache: go.sum 105 | @echo "--> Download go modules to local cache" 106 | @go mod download 107 | 108 | go.sum: go.mod 109 | @echo "--> Ensure dependencies have not been modified" 110 | @go mod verify 111 | 112 | clean: 113 | rm -rf $(BUILD_DIR) 114 | rm -f $(shell which $(BINARY_NAME)) 115 | 116 | ############################################################################### 117 | ### Test ### 118 | ############################################################################### 119 | 120 | test: 121 | @go test -v ./x/... 122 | 123 | smoketest: install 124 | ./scripts/test/smoke.sh 125 | 126 | ############################################################################### 127 | ### Proto ### 128 | ############################################################################### 129 | 130 | proto: 131 | @echo 132 | @echo "=========== Generate Message ============" 133 | @echo 134 | ./scripts/protocgen.sh 135 | @echo 136 | @echo "=========== Generate Complete ============" 137 | @echo 138 | 139 | ############################################################################### 140 | ### Serve ### 141 | ############################################################################### 142 | 143 | serve: 144 | @echo 145 | @echo "=========== Serve ============" 146 | @echo 147 | ./scripts/serve.sh 148 | @echo 149 | @echo "=========== Serving now ============" 150 | @echo 151 | 152 | kill: 153 | @echo "Killing empowerd and removing previous data" 154 | -@rm -rf ./tmp/empowerchain-local-1 155 | -@killall empowerd 2>/dev/null 156 | 157 | 158 | ############################################################################### 159 | ### Linting ### 160 | ############################################################################### 161 | 162 | lint: 163 | @echo "--> Running linter" 164 | @go run github.com/golangci/golangci-lint/cmd/golangci-lint run --timeout=10m 165 | 166 | format: 167 | @go run github.com/golangci/golangci-lint/cmd/golangci-lint run ./... --fix 168 | @go run mvdan.cc/gofumpt -l -w x/ app/ ante/ tests/ -------------------------------------------------------------------------------- /chain/x/proofofexistence/module.go: -------------------------------------------------------------------------------- 1 | package proofofexistence 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "fmt" 7 | 8 | "github.com/gorilla/mux" 9 | "github.com/grpc-ecosystem/grpc-gateway/runtime" 10 | "github.com/spf13/cobra" 11 | 12 | abci "github.com/tendermint/tendermint/abci/types" 13 | 14 | "github.com/cosmos/cosmos-sdk/client" 15 | "github.com/cosmos/cosmos-sdk/codec" 16 | cdctypes "github.com/cosmos/cosmos-sdk/codec/types" 17 | sdk "github.com/cosmos/cosmos-sdk/types" 18 | "github.com/cosmos/cosmos-sdk/types/module" 19 | "github.com/empowerchain/empowerchain/x/proofofexistence/client/cli" 20 | "github.com/empowerchain/empowerchain/x/proofofexistence/keeper" 21 | "github.com/empowerchain/empowerchain/x/proofofexistence/types" 22 | ) 23 | 24 | var ( 25 | _ module.AppModule = AppModule{} 26 | _ module.AppModuleBasic = AppModuleBasic{} 27 | ) 28 | 29 | // ---------------------------------------------------------------------------- 30 | // AppModuleBasic 31 | // ---------------------------------------------------------------------------- 32 | 33 | // AppModuleBasic implements the AppModuleBasic interface for the capability module. 34 | type AppModuleBasic struct { 35 | cdc codec.BinaryCodec 36 | } 37 | 38 | func NewAppModuleBasic(cdc codec.BinaryCodec) AppModuleBasic { 39 | return AppModuleBasic{cdc: cdc} 40 | } 41 | 42 | // Name returns the capability module's name. 43 | func (AppModuleBasic) Name() string { 44 | return types.ModuleName 45 | } 46 | 47 | func (AppModuleBasic) RegisterCodec(cdc *codec.LegacyAmino) { 48 | types.RegisterCodec(cdc) 49 | } 50 | 51 | func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { 52 | types.RegisterCodec(cdc) 53 | } 54 | 55 | // RegisterInterfaces registers the module's interface types 56 | func (a AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry) { 57 | types.RegisterInterfaces(reg) 58 | } 59 | 60 | // DefaultGenesis returns the capability module's default genesis state. 61 | func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { 62 | return cdc.MustMarshalJSON(types.DefaultGenesis()) 63 | } 64 | 65 | // ValidateGenesis performs genesis state validation for the capability module. 66 | func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { 67 | var genState types.GenesisState 68 | if err := cdc.UnmarshalJSON(bz, &genState); err != nil { 69 | return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) 70 | } 71 | return genState.Validate() 72 | } 73 | 74 | // RegisterRESTRoutes registers the capability module's REST service handlers. 75 | func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) { 76 | } 77 | 78 | // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module. 79 | func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { 80 | if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil { 81 | return 82 | } 83 | } 84 | 85 | // GetTxCmd returns the capability module's root tx command. 86 | func (a AppModuleBasic) GetTxCmd() *cobra.Command { 87 | return cli.GetTxCmd() 88 | } 89 | 90 | // GetQueryCmd returns the capability module's root query command. 91 | func (AppModuleBasic) GetQueryCmd() *cobra.Command { 92 | return cli.GetQueryCmd(types.StoreKey) 93 | } 94 | 95 | // ---------------------------------------------------------------------------- 96 | // AppModule 97 | // ---------------------------------------------------------------------------- 98 | 99 | // AppModule implements the AppModule interface for the capability module. 100 | type AppModule struct { 101 | AppModuleBasic 102 | 103 | keeper keeper.Keeper 104 | accountKeeper types.AccountKeeper 105 | bankKeeper types.BankKeeper 106 | } 107 | 108 | func NewAppModule( 109 | cdc codec.Codec, 110 | keeper keeper.Keeper, 111 | accountKeeper types.AccountKeeper, 112 | bankKeeper types.BankKeeper, 113 | ) AppModule { 114 | return AppModule{ 115 | AppModuleBasic: NewAppModuleBasic(cdc), 116 | keeper: keeper, 117 | accountKeeper: accountKeeper, 118 | bankKeeper: bankKeeper, 119 | } 120 | } 121 | 122 | // Name returns the capability module's name. 123 | func (am AppModule) Name() string { 124 | return am.AppModuleBasic.Name() 125 | } 126 | 127 | // Deprecated: Route returns the capability module's message routing key. 128 | func (am AppModule) Route() sdk.Route { 129 | return sdk.Route{} 130 | } 131 | 132 | // QuerierRoute returns the capability module's query routing key. 133 | func (AppModule) QuerierRoute() string { return types.QuerierRoute } 134 | 135 | // LegacyQuerierHandler returns the capability module's Querier. 136 | func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { 137 | return nil 138 | } 139 | 140 | // RegisterServices registers a GRPC query service to respond to the 141 | // module-specific GRPC queries. 142 | func (am AppModule) RegisterServices(cfg module.Configurator) { 143 | querier := keeper.Querier{Keeper: am.keeper} 144 | types.RegisterQueryServer(cfg.QueryServer(), querier) 145 | msgServer := keeper.NewMsgServerImpl(am.keeper) 146 | types.RegisterMsgServer(cfg.MsgServer(), msgServer) 147 | } 148 | 149 | // RegisterInvariants registers the capability module's invariants. 150 | func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} 151 | 152 | // InitGenesis performs the capability module's genesis initialization It returns 153 | // no validator updates. 154 | func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate { 155 | var genState types.GenesisState 156 | // Initialize global index to index in genesis state 157 | cdc.MustUnmarshalJSON(gs, &genState) 158 | 159 | InitGenesis(ctx, am.keeper, genState) 160 | 161 | return []abci.ValidatorUpdate{} 162 | } 163 | 164 | // ExportGenesis returns the capability module's exported genesis state as raw JSON bytes. 165 | func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { 166 | genState := ExportGenesis(ctx, am.keeper) 167 | return cdc.MustMarshalJSON(genState) 168 | } 169 | 170 | // ConsensusVersion implements ConsensusVersion. 171 | func (AppModule) ConsensusVersion() uint64 { return 2 } 172 | 173 | // BeginBlock executes all ABCI BeginBlock logic respective to the capability module. 174 | func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {} 175 | 176 | // EndBlock executes all ABCI EndBlock logic respective to the capability module. It 177 | // returns no validator updates. 178 | func (am AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { 179 | return []abci.ValidatorUpdate{} 180 | } 181 | -------------------------------------------------------------------------------- /chain/app/export.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "log" 7 | 8 | tmproto "github.com/tendermint/tendermint/proto/tendermint/types" 9 | 10 | servertypes "github.com/cosmos/cosmos-sdk/server/types" 11 | sdk "github.com/cosmos/cosmos-sdk/types" 12 | slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" 13 | "github.com/cosmos/cosmos-sdk/x/staking" 14 | stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" 15 | ) 16 | 17 | // ExportAppStateAndValidators exports the state of the application for a genesis 18 | // file. 19 | func (app *App) ExportAppStateAndValidators(forZeroHeight bool, jailAllowedAddrs []string) (servertypes.ExportedApp, error) { 20 | // as if they could withdraw from the start of the next block 21 | ctx := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}) 22 | 23 | // We export at last height + 1, because that's the height at which 24 | // Tendermint will start InitChain. 25 | height := app.LastBlockHeight() + 1 26 | if forZeroHeight { 27 | height = 0 28 | app.prepForZeroHeightGenesis(ctx, jailAllowedAddrs) 29 | } 30 | 31 | genState := app.mm.ExportGenesis(ctx, app.appCodec) 32 | appState, err := json.MarshalIndent(genState, "", " ") 33 | if err != nil { 34 | return servertypes.ExportedApp{}, err 35 | } 36 | 37 | validators, err := staking.WriteValidators(ctx, app.StakingKeeper) 38 | if err != nil { 39 | return servertypes.ExportedApp{}, err 40 | } 41 | return servertypes.ExportedApp{ 42 | AppState: appState, 43 | Validators: validators, 44 | Height: height, 45 | ConsensusParams: app.BaseApp.GetConsensusParams(ctx), 46 | }, nil 47 | } 48 | 49 | // prepare for fresh start at zero height 50 | // NOTE zero height genesis is a temporary feature which will be deprecated 51 | // in favour of export at a block height 52 | func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []string) { 53 | applyAllowedAddrs := false 54 | 55 | // check if there is a allowed address list 56 | if len(jailAllowedAddrs) > 0 { 57 | applyAllowedAddrs = true 58 | } 59 | 60 | allowedAddrsMap := make(map[string]bool) 61 | 62 | for _, addr := range jailAllowedAddrs { 63 | _, err := sdk.ValAddressFromBech32(addr) 64 | if err != nil { 65 | log.Fatal(err) 66 | } 67 | allowedAddrsMap[addr] = true 68 | } 69 | 70 | /* Just to be safe, assert the invariants on current state. */ 71 | app.CrisisKeeper.AssertInvariants(ctx) 72 | 73 | /* Handle fee distribution state. */ 74 | 75 | // withdraw all validator commission 76 | app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) { 77 | _, err := app.DistrKeeper.WithdrawValidatorCommission(ctx, val.GetOperator()) 78 | if err != nil { 79 | panic(err) 80 | } 81 | return false 82 | }) 83 | 84 | // withdraw all delegator rewards 85 | dels := app.StakingKeeper.GetAllDelegations(ctx) 86 | for _, delegation := range dels { 87 | _, err := app.DistrKeeper.WithdrawDelegationRewards(ctx, delegation.GetDelegatorAddr(), delegation.GetValidatorAddr()) 88 | if err != nil { 89 | panic(err) 90 | } 91 | } 92 | 93 | // clear validator slash events 94 | app.DistrKeeper.DeleteAllValidatorSlashEvents(ctx) 95 | 96 | // clear validator historical rewards 97 | app.DistrKeeper.DeleteAllValidatorHistoricalRewards(ctx) 98 | 99 | // set context height to zero 100 | height := ctx.BlockHeight() 101 | ctx = ctx.WithBlockHeight(0) 102 | 103 | // reinitialize all validators 104 | app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) { 105 | // donate any unwithdrawn outstanding reward fraction tokens to the community pool 106 | scraps := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, val.GetOperator()) 107 | feePool := app.DistrKeeper.GetFeePool(ctx) 108 | feePool.CommunityPool = feePool.CommunityPool.Add(scraps...) 109 | app.DistrKeeper.SetFeePool(ctx, feePool) 110 | 111 | if err := app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, val.GetOperator()); err != nil { 112 | panic(err) 113 | } 114 | return false 115 | }) 116 | 117 | // reinitialize all delegations 118 | for _, del := range dels { 119 | valAddr, err := sdk.ValAddressFromBech32(del.ValidatorAddress) 120 | if err != nil { 121 | panic(err) 122 | } 123 | delAddr := sdk.MustAccAddressFromBech32(del.DelegatorAddress) 124 | 125 | if err := app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, delAddr, valAddr); err != nil { 126 | // never called as BeforeDelegationCreated always returns nil 127 | panic(fmt.Errorf("error while incrementing period: %w", err)) 128 | } 129 | 130 | if err := app.DistrKeeper.Hooks().AfterDelegationModified(ctx, delAddr, valAddr); err != nil { 131 | // never called as AfterDelegationModified always returns nil 132 | panic(fmt.Errorf("error while creating a new delegation period record: %w", err)) 133 | } 134 | } 135 | 136 | // reset context height 137 | ctx = ctx.WithBlockHeight(height) 138 | 139 | /* Handle staking state. */ 140 | 141 | // iterate through redelegations, reset creation height 142 | app.StakingKeeper.IterateRedelegations(ctx, func(_ int64, red stakingtypes.Redelegation) (stop bool) { 143 | for i := range red.Entries { 144 | red.Entries[i].CreationHeight = 0 145 | } 146 | app.StakingKeeper.SetRedelegation(ctx, red) 147 | return false 148 | }) 149 | 150 | // iterate through unbonding delegations, reset creation height 151 | app.StakingKeeper.IterateUnbondingDelegations(ctx, func(_ int64, ubd stakingtypes.UnbondingDelegation) (stop bool) { 152 | for i := range ubd.Entries { 153 | ubd.Entries[i].CreationHeight = 0 154 | } 155 | app.StakingKeeper.SetUnbondingDelegation(ctx, ubd) 156 | return false 157 | }) 158 | 159 | // Iterate through validators by power descending, reset bond heights, and 160 | // update bond intra-tx counters. 161 | store := ctx.KVStore(app.keys[stakingtypes.StoreKey]) 162 | iter := sdk.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey) 163 | counter := int16(0) 164 | 165 | for ; iter.Valid(); iter.Next() { 166 | addr := sdk.ValAddress(iter.Key()[1:]) 167 | validator, found := app.StakingKeeper.GetValidator(ctx, addr) 168 | if !found { 169 | panic("expected validator, not found") 170 | } 171 | 172 | validator.UnbondingHeight = 0 173 | if applyAllowedAddrs && !allowedAddrsMap[addr.String()] { 174 | validator.Jailed = true 175 | } 176 | 177 | app.StakingKeeper.SetValidator(ctx, validator) 178 | counter++ 179 | } 180 | 181 | iter.Close() 182 | 183 | if _, err := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx); err != nil { 184 | panic(err) 185 | } 186 | 187 | /* Handle slashing state. */ 188 | 189 | // reset start height on signing infos 190 | app.SlashingKeeper.IterateValidatorSigningInfos( 191 | ctx, 192 | func(addr sdk.ConsAddress, info slashingtypes.ValidatorSigningInfo) (stop bool) { 193 | info.StartHeight = 0 194 | app.SlashingKeeper.SetValidatorSigningInfo(ctx, addr, info) 195 | return false 196 | }, 197 | ) 198 | } 199 | -------------------------------------------------------------------------------- /chain/cmd/empowerd/cmd/genaccounts.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "bufio" 5 | "encoding/json" 6 | "errors" 7 | "fmt" 8 | 9 | "github.com/spf13/cobra" 10 | 11 | "github.com/cosmos/cosmos-sdk/client" 12 | "github.com/cosmos/cosmos-sdk/client/flags" 13 | "github.com/cosmos/cosmos-sdk/crypto/keyring" 14 | "github.com/cosmos/cosmos-sdk/server" 15 | sdk "github.com/cosmos/cosmos-sdk/types" 16 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" 17 | authvesting "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" 18 | banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" 19 | "github.com/cosmos/cosmos-sdk/x/genutil" 20 | genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" 21 | ) 22 | 23 | const ( 24 | flagVestingStart = "vesting-start-time" 25 | flagVestingEnd = "vesting-end-time" 26 | flagVestingAmt = "vesting-amount" 27 | ) 28 | 29 | // AddGenesisAccountCmd returns add-genesis-account cobra Command. 30 | func AddGenesisAccountCmd(defaultNodeHome string) *cobra.Command { 31 | cmd := &cobra.Command{ 32 | Use: "add-genesis-account [address_or_key_name] [coin][,[coin]]", 33 | Short: "Add a genesis account to genesis.json", 34 | Long: `Add a genesis account to genesis.json. The provided account must specify 35 | the account address or key name and a list of initial coins. If a key name is given, 36 | the address will be looked up in the local Keybase. The list of initial tokens must 37 | contain valid denominations. Accounts may optionally be supplied with vesting parameters. 38 | `, 39 | Args: cobra.ExactArgs(2), 40 | RunE: func(cmd *cobra.Command, args []string) error { 41 | clientCtx := client.GetClientContextFromCmd(cmd) 42 | serverCtx := server.GetServerContextFromCmd(cmd) 43 | config := serverCtx.Config 44 | 45 | config.SetRoot(clientCtx.HomeDir) 46 | 47 | var kr keyring.Keyring 48 | addr, err := sdk.AccAddressFromBech32(args[0]) 49 | if err != nil { 50 | inBuf := bufio.NewReader(cmd.InOrStdin()) 51 | keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend) 52 | if keyringBackend != "" && clientCtx.Keyring == nil { 53 | var err error 54 | kr, err = keyring.New(sdk.KeyringServiceName(), keyringBackend, clientCtx.HomeDir, inBuf, clientCtx.Codec) 55 | if err != nil { 56 | return err 57 | } 58 | } else { 59 | kr = clientCtx.Keyring 60 | } 61 | 62 | k, err := kr.Key(args[0]) 63 | if err != nil { 64 | return fmt.Errorf("failed to get address from Keyring: %w", err) 65 | } 66 | addr, err = k.GetAddress() 67 | if err != nil { 68 | return err 69 | } 70 | } 71 | 72 | coins, err := sdk.ParseCoinsNormalized(args[1]) 73 | if err != nil { 74 | return fmt.Errorf("failed to parse coins: %w", err) 75 | } 76 | 77 | vestingStart, _ := cmd.Flags().GetInt64(flagVestingStart) 78 | vestingEnd, _ := cmd.Flags().GetInt64(flagVestingEnd) 79 | vestingAmtStr, _ := cmd.Flags().GetString(flagVestingAmt) 80 | 81 | vestingAmt, err := sdk.ParseCoinsNormalized(vestingAmtStr) 82 | if err != nil { 83 | return fmt.Errorf("failed to parse vesting amount: %w", err) 84 | } 85 | 86 | // create concrete account type based on input parameters 87 | var genAccount authtypes.GenesisAccount 88 | 89 | balances := banktypes.Balance{Address: addr.String(), Coins: coins.Sort()} 90 | baseAccount := authtypes.NewBaseAccount(addr, nil, 0, 0) 91 | 92 | if !vestingAmt.IsZero() { 93 | baseVestingAccount := authvesting.NewBaseVestingAccount(baseAccount, vestingAmt.Sort(), vestingEnd) 94 | 95 | if (balances.Coins.IsZero() && !baseVestingAccount.OriginalVesting.IsZero()) || 96 | baseVestingAccount.OriginalVesting.IsAnyGT(balances.Coins) { 97 | return errors.New("vesting amount cannot be greater than total amount") 98 | } 99 | 100 | switch { 101 | case vestingStart != 0 && vestingEnd != 0: 102 | genAccount = authvesting.NewContinuousVestingAccountRaw(baseVestingAccount, vestingStart) 103 | 104 | case vestingEnd != 0: 105 | genAccount = authvesting.NewDelayedVestingAccountRaw(baseVestingAccount) 106 | 107 | default: 108 | return errors.New("invalid vesting parameters; must supply start and end time or end time") 109 | } 110 | } else { 111 | genAccount = baseAccount 112 | } 113 | 114 | if err := genAccount.Validate(); err != nil { 115 | return fmt.Errorf("failed to validate new genesis account: %w", err) 116 | } 117 | 118 | genFile := config.GenesisFile() 119 | appState, genDoc, err := genutiltypes.GenesisStateFromGenFile(genFile) 120 | if err != nil { 121 | return fmt.Errorf("failed to unmarshal genesis state: %w", err) 122 | } 123 | 124 | authGenState := authtypes.GetGenesisStateFromAppState(clientCtx.Codec, appState) 125 | 126 | accs, err := authtypes.UnpackAccounts(authGenState.Accounts) 127 | if err != nil { 128 | return fmt.Errorf("failed to get accounts from any: %w", err) 129 | } 130 | 131 | if accs.Contains(addr) { 132 | return fmt.Errorf("cannot add account at existing address %s", addr) 133 | } 134 | 135 | // Add the new account to the set of genesis accounts and sanitize the 136 | // accounts afterwards. 137 | accs = append(accs, genAccount) 138 | accs = authtypes.SanitizeGenesisAccounts(accs) 139 | 140 | genAccs, err := authtypes.PackAccounts(accs) 141 | if err != nil { 142 | return fmt.Errorf("failed to convert accounts into any's: %w", err) 143 | } 144 | authGenState.Accounts = genAccs 145 | 146 | authGenStateBz, err := clientCtx.Codec.MarshalJSON(&authGenState) 147 | if err != nil { 148 | return fmt.Errorf("failed to marshal auth genesis state: %w", err) 149 | } 150 | 151 | appState[authtypes.ModuleName] = authGenStateBz 152 | 153 | bankGenState := banktypes.GetGenesisStateFromAppState(clientCtx.Codec, appState) 154 | bankGenState.Balances = append(bankGenState.Balances, balances) 155 | bankGenState.Balances = banktypes.SanitizeGenesisBalances(bankGenState.Balances) 156 | bankGenState.Supply = bankGenState.Supply.Add(balances.Coins...) 157 | 158 | bankGenStateBz, err := clientCtx.Codec.MarshalJSON(bankGenState) 159 | if err != nil { 160 | return fmt.Errorf("failed to marshal bank genesis state: %w", err) 161 | } 162 | 163 | appState[banktypes.ModuleName] = bankGenStateBz 164 | 165 | appStateJSON, err := json.Marshal(appState) 166 | if err != nil { 167 | return fmt.Errorf("failed to marshal application genesis state: %w", err) 168 | } 169 | 170 | genDoc.AppState = appStateJSON 171 | return genutil.ExportGenesisFile(genDoc, genFile) 172 | }, 173 | } 174 | 175 | cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory") 176 | cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test)") 177 | cmd.Flags().String(flagVestingAmt, "", "amount of coins for vesting accounts") 178 | cmd.Flags().Int64(flagVestingStart, 0, "schedule start time (unix epoch) for vesting accounts") 179 | cmd.Flags().Int64(flagVestingEnd, 0, "schedule end time (unix epoch) for vesting accounts") 180 | flags.AddQueryFlagsToCmd(cmd) 181 | 182 | return cmd 183 | } 184 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/types/query.pb.gw.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. 2 | // source: empowerchain/proofofexistence/query.proto 3 | 4 | /* 5 | Package types is a reverse proxy. 6 | 7 | It translates gRPC into RESTful JSON APIs. 8 | */ 9 | package types 10 | 11 | import ( 12 | "context" 13 | "io" 14 | "net/http" 15 | 16 | "github.com/golang/protobuf/descriptor" 17 | "github.com/golang/protobuf/proto" 18 | "github.com/grpc-ecosystem/grpc-gateway/runtime" 19 | "github.com/grpc-ecosystem/grpc-gateway/utilities" 20 | "google.golang.org/grpc" 21 | "google.golang.org/grpc/codes" 22 | "google.golang.org/grpc/grpclog" 23 | "google.golang.org/grpc/metadata" 24 | "google.golang.org/grpc/status" 25 | ) 26 | 27 | // Suppress "imported and not used" errors 28 | var _ codes.Code 29 | var _ io.Reader 30 | var _ status.Status 31 | var _ = runtime.String 32 | var _ = utilities.NewDoubleArray 33 | var _ = descriptor.ForMessage 34 | var _ = metadata.Join 35 | 36 | func request_Query_Proof_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { 37 | var protoReq QueryGetProofRequest 38 | var metadata runtime.ServerMetadata 39 | 40 | var ( 41 | val string 42 | ok bool 43 | err error 44 | _ = err 45 | ) 46 | 47 | val, ok = pathParams["hash"] 48 | if !ok { 49 | return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "hash") 50 | } 51 | 52 | protoReq.Hash, err = runtime.String(val) 53 | 54 | if err != nil { 55 | return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "hash", err) 56 | } 57 | 58 | msg, err := client.Proof(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) 59 | return msg, metadata, err 60 | 61 | } 62 | 63 | func local_request_Query_Proof_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { 64 | var protoReq QueryGetProofRequest 65 | var metadata runtime.ServerMetadata 66 | 67 | var ( 68 | val string 69 | ok bool 70 | err error 71 | _ = err 72 | ) 73 | 74 | val, ok = pathParams["hash"] 75 | if !ok { 76 | return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "hash") 77 | } 78 | 79 | protoReq.Hash, err = runtime.String(val) 80 | 81 | if err != nil { 82 | return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "hash", err) 83 | } 84 | 85 | msg, err := server.Proof(ctx, &protoReq) 86 | return msg, metadata, err 87 | 88 | } 89 | 90 | // RegisterQueryHandlerServer registers the http handlers for service Query to "mux". 91 | // UnaryRPC :call QueryServer directly. 92 | // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. 93 | // Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. 94 | func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { 95 | 96 | mux.Handle("GET", pattern_Query_Proof_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { 97 | ctx, cancel := context.WithCancel(req.Context()) 98 | defer cancel() 99 | var stream runtime.ServerTransportStream 100 | ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) 101 | inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) 102 | rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) 103 | if err != nil { 104 | runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) 105 | return 106 | } 107 | resp, md, err := local_request_Query_Proof_0(rctx, inboundMarshaler, server, req, pathParams) 108 | md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) 109 | ctx = runtime.NewServerMetadataContext(ctx, md) 110 | if err != nil { 111 | runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) 112 | return 113 | } 114 | 115 | forward_Query_Proof_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) 116 | 117 | }) 118 | 119 | return nil 120 | } 121 | 122 | // RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but 123 | // automatically dials to "endpoint" and closes the connection when "ctx" gets done. 124 | func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { 125 | conn, err := grpc.Dial(endpoint, opts...) 126 | if err != nil { 127 | return err 128 | } 129 | defer func() { 130 | if err != nil { 131 | if cerr := conn.Close(); cerr != nil { 132 | grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) 133 | } 134 | return 135 | } 136 | go func() { 137 | <-ctx.Done() 138 | if cerr := conn.Close(); cerr != nil { 139 | grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) 140 | } 141 | }() 142 | }() 143 | 144 | return RegisterQueryHandler(ctx, mux, conn) 145 | } 146 | 147 | // RegisterQueryHandler registers the http handlers for service Query to "mux". 148 | // The handlers forward requests to the grpc endpoint over "conn". 149 | func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { 150 | return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn)) 151 | } 152 | 153 | // RegisterQueryHandlerClient registers the http handlers for service Query 154 | // to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient". 155 | // Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient" 156 | // doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in 157 | // "QueryClient" to call the correct interceptors. 158 | func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { 159 | 160 | mux.Handle("GET", pattern_Query_Proof_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { 161 | ctx, cancel := context.WithCancel(req.Context()) 162 | defer cancel() 163 | inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) 164 | rctx, err := runtime.AnnotateContext(ctx, mux, req) 165 | if err != nil { 166 | runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) 167 | return 168 | } 169 | resp, md, err := request_Query_Proof_0(rctx, inboundMarshaler, client, req, pathParams) 170 | ctx = runtime.NewServerMetadataContext(ctx, md) 171 | if err != nil { 172 | runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) 173 | return 174 | } 175 | 176 | forward_Query_Proof_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) 177 | 178 | }) 179 | 180 | return nil 181 | } 182 | 183 | var ( 184 | pattern_Query_Proof_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"empowerchain", "proofofexistence", "proof", "hash"}, "", runtime.AssumeColonVerbOpt(false))) 185 | ) 186 | 187 | var ( 188 | forward_Query_Proof_0 = runtime.ForwardResponseMessage 189 | ) 190 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/types/params.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-gogo. DO NOT EDIT. 2 | // source: empowerchain/proofofexistence/params.proto 3 | 4 | package types 5 | 6 | import ( 7 | fmt "fmt" 8 | _ "github.com/gogo/protobuf/gogoproto" 9 | proto "github.com/gogo/protobuf/proto" 10 | io "io" 11 | math "math" 12 | math_bits "math/bits" 13 | ) 14 | 15 | // Reference imports to suppress errors if they are not otherwise used. 16 | var _ = proto.Marshal 17 | var _ = fmt.Errorf 18 | var _ = math.Inf 19 | 20 | // This is a compile-time assertion to ensure that this generated file 21 | // is compatible with the proto package it is being compiled against. 22 | // A compilation error at this line likely means your copy of the 23 | // proto package needs to be updated. 24 | const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package 25 | 26 | // Params defines the parameters for the module. 27 | type Params struct { 28 | } 29 | 30 | func (m *Params) Reset() { *m = Params{} } 31 | func (*Params) ProtoMessage() {} 32 | func (*Params) Descriptor() ([]byte, []int) { 33 | return fileDescriptor_02a10c91c2407116, []int{0} 34 | } 35 | func (m *Params) XXX_Unmarshal(b []byte) error { 36 | return m.Unmarshal(b) 37 | } 38 | func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { 39 | if deterministic { 40 | return xxx_messageInfo_Params.Marshal(b, m, deterministic) 41 | } else { 42 | b = b[:cap(b)] 43 | n, err := m.MarshalToSizedBuffer(b) 44 | if err != nil { 45 | return nil, err 46 | } 47 | return b[:n], nil 48 | } 49 | } 50 | func (m *Params) XXX_Merge(src proto.Message) { 51 | xxx_messageInfo_Params.Merge(m, src) 52 | } 53 | func (m *Params) XXX_Size() int { 54 | return m.Size() 55 | } 56 | func (m *Params) XXX_DiscardUnknown() { 57 | xxx_messageInfo_Params.DiscardUnknown(m) 58 | } 59 | 60 | var xxx_messageInfo_Params proto.InternalMessageInfo 61 | 62 | func init() { 63 | proto.RegisterType((*Params)(nil), "empowerchain.empowerchain.proofofexistence.Params") 64 | } 65 | 66 | func init() { 67 | proto.RegisterFile("empowerchain/proofofexistence/params.proto", fileDescriptor_02a10c91c2407116) 68 | } 69 | 70 | var fileDescriptor_02a10c91c2407116 = []byte{ 71 | // 161 bytes of a gzipped FileDescriptorProto 72 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x4a, 0xcd, 0x2d, 0xc8, 73 | 0x2f, 0x4f, 0x2d, 0x4a, 0xce, 0x48, 0xcc, 0xcc, 0xd3, 0x2f, 0x28, 0xca, 0xcf, 0x4f, 0xcb, 0x4f, 74 | 0x4b, 0xad, 0xc8, 0x2c, 0x2e, 0x49, 0xcd, 0x4b, 0x4e, 0xd5, 0x2f, 0x48, 0x2c, 0x4a, 0xcc, 0x2d, 75 | 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x42, 0x51, 0xab, 0x87, 0xc2, 0x41, 0xd7, 0x28, 0x25, 76 | 0x92, 0x9e, 0x9f, 0x9e, 0x0f, 0xd6, 0xa6, 0x0f, 0x62, 0x41, 0x4c, 0x50, 0xe2, 0xe3, 0x62, 0x0b, 77 | 0x00, 0x9b, 0x68, 0xc5, 0x32, 0x63, 0x81, 0x3c, 0x83, 0x53, 0xf8, 0x89, 0x47, 0x72, 0x8c, 0x17, 78 | 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe1, 0xb1, 0x1c, 0xc3, 0x85, 0xc7, 0x72, 0x0c, 79 | 0x37, 0x1e, 0xcb, 0x31, 0x44, 0xd9, 0xa6, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 80 | 0xea, 0xa3, 0x38, 0x11, 0x85, 0x53, 0x81, 0xe9, 0xe2, 0x92, 0xca, 0x82, 0xd4, 0xe2, 0x24, 0x36, 81 | 0xb0, 0x7d, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x63, 0x71, 0xfd, 0x71, 0xdf, 0x00, 0x00, 82 | 0x00, 83 | } 84 | 85 | func (m *Params) Marshal() (dAtA []byte, err error) { 86 | size := m.Size() 87 | dAtA = make([]byte, size) 88 | n, err := m.MarshalToSizedBuffer(dAtA[:size]) 89 | if err != nil { 90 | return nil, err 91 | } 92 | return dAtA[:n], nil 93 | } 94 | 95 | func (m *Params) MarshalTo(dAtA []byte) (int, error) { 96 | size := m.Size() 97 | return m.MarshalToSizedBuffer(dAtA[:size]) 98 | } 99 | 100 | func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { 101 | i := len(dAtA) 102 | _ = i 103 | var l int 104 | _ = l 105 | return len(dAtA) - i, nil 106 | } 107 | 108 | func encodeVarintParams(dAtA []byte, offset int, v uint64) int { 109 | offset -= sovParams(v) 110 | base := offset 111 | for v >= 1<<7 { 112 | dAtA[offset] = uint8(v&0x7f | 0x80) 113 | v >>= 7 114 | offset++ 115 | } 116 | dAtA[offset] = uint8(v) 117 | return base 118 | } 119 | func (m *Params) Size() (n int) { 120 | if m == nil { 121 | return 0 122 | } 123 | var l int 124 | _ = l 125 | return n 126 | } 127 | 128 | func sovParams(x uint64) (n int) { 129 | return (math_bits.Len64(x|1) + 6) / 7 130 | } 131 | func sozParams(x uint64) (n int) { 132 | return sovParams(uint64((x << 1) ^ uint64((int64(x) >> 63)))) 133 | } 134 | func (m *Params) Unmarshal(dAtA []byte) error { 135 | l := len(dAtA) 136 | iNdEx := 0 137 | for iNdEx < l { 138 | preIndex := iNdEx 139 | var wire uint64 140 | for shift := uint(0); ; shift += 7 { 141 | if shift >= 64 { 142 | return ErrIntOverflowParams 143 | } 144 | if iNdEx >= l { 145 | return io.ErrUnexpectedEOF 146 | } 147 | b := dAtA[iNdEx] 148 | iNdEx++ 149 | wire |= uint64(b&0x7F) << shift 150 | if b < 0x80 { 151 | break 152 | } 153 | } 154 | fieldNum := int32(wire >> 3) 155 | wireType := int(wire & 0x7) 156 | if wireType == 4 { 157 | return fmt.Errorf("proto: Params: wiretype end group for non-group") 158 | } 159 | if fieldNum <= 0 { 160 | return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) 161 | } 162 | switch fieldNum { 163 | default: 164 | iNdEx = preIndex 165 | skippy, err := skipParams(dAtA[iNdEx:]) 166 | if err != nil { 167 | return err 168 | } 169 | if (skippy < 0) || (iNdEx+skippy) < 0 { 170 | return ErrInvalidLengthParams 171 | } 172 | if (iNdEx + skippy) > l { 173 | return io.ErrUnexpectedEOF 174 | } 175 | iNdEx += skippy 176 | } 177 | } 178 | 179 | if iNdEx > l { 180 | return io.ErrUnexpectedEOF 181 | } 182 | return nil 183 | } 184 | func skipParams(dAtA []byte) (n int, err error) { 185 | l := len(dAtA) 186 | iNdEx := 0 187 | depth := 0 188 | for iNdEx < l { 189 | var wire uint64 190 | for shift := uint(0); ; shift += 7 { 191 | if shift >= 64 { 192 | return 0, ErrIntOverflowParams 193 | } 194 | if iNdEx >= l { 195 | return 0, io.ErrUnexpectedEOF 196 | } 197 | b := dAtA[iNdEx] 198 | iNdEx++ 199 | wire |= (uint64(b) & 0x7F) << shift 200 | if b < 0x80 { 201 | break 202 | } 203 | } 204 | wireType := int(wire & 0x7) 205 | switch wireType { 206 | case 0: 207 | for shift := uint(0); ; shift += 7 { 208 | if shift >= 64 { 209 | return 0, ErrIntOverflowParams 210 | } 211 | if iNdEx >= l { 212 | return 0, io.ErrUnexpectedEOF 213 | } 214 | iNdEx++ 215 | if dAtA[iNdEx-1] < 0x80 { 216 | break 217 | } 218 | } 219 | case 1: 220 | iNdEx += 8 221 | case 2: 222 | var length int 223 | for shift := uint(0); ; shift += 7 { 224 | if shift >= 64 { 225 | return 0, ErrIntOverflowParams 226 | } 227 | if iNdEx >= l { 228 | return 0, io.ErrUnexpectedEOF 229 | } 230 | b := dAtA[iNdEx] 231 | iNdEx++ 232 | length |= (int(b) & 0x7F) << shift 233 | if b < 0x80 { 234 | break 235 | } 236 | } 237 | if length < 0 { 238 | return 0, ErrInvalidLengthParams 239 | } 240 | iNdEx += length 241 | case 3: 242 | depth++ 243 | case 4: 244 | if depth == 0 { 245 | return 0, ErrUnexpectedEndOfGroupParams 246 | } 247 | depth-- 248 | case 5: 249 | iNdEx += 4 250 | default: 251 | return 0, fmt.Errorf("proto: illegal wireType %d", wireType) 252 | } 253 | if iNdEx < 0 { 254 | return 0, ErrInvalidLengthParams 255 | } 256 | if depth == 0 { 257 | return iNdEx, nil 258 | } 259 | } 260 | return 0, io.ErrUnexpectedEOF 261 | } 262 | 263 | var ( 264 | ErrInvalidLengthParams = fmt.Errorf("proto: negative length found during unmarshaling") 265 | ErrIntOverflowParams = fmt.Errorf("proto: integer overflow") 266 | ErrUnexpectedEndOfGroupParams = fmt.Errorf("proto: unexpected end of group") 267 | ) 268 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/types/genesis.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-gogo. DO NOT EDIT. 2 | // source: empowerchain/proofofexistence/genesis.proto 3 | 4 | package types 5 | 6 | import ( 7 | fmt "fmt" 8 | _ "github.com/gogo/protobuf/gogoproto" 9 | proto "github.com/gogo/protobuf/proto" 10 | io "io" 11 | math "math" 12 | math_bits "math/bits" 13 | ) 14 | 15 | // Reference imports to suppress errors if they are not otherwise used. 16 | var _ = proto.Marshal 17 | var _ = fmt.Errorf 18 | var _ = math.Inf 19 | 20 | // This is a compile-time assertion to ensure that this generated file 21 | // is compatible with the proto package it is being compiled against. 22 | // A compilation error at this line likely means your copy of the 23 | // proto package needs to be updated. 24 | const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package 25 | 26 | // GenesisState defines the proofofexistence module's genesis state. 27 | type GenesisState struct { 28 | ProofList []Proof `protobuf:"bytes,1,rep,name=proofList,proto3" json:"proofList"` 29 | } 30 | 31 | func (m *GenesisState) Reset() { *m = GenesisState{} } 32 | func (m *GenesisState) String() string { return proto.CompactTextString(m) } 33 | func (*GenesisState) ProtoMessage() {} 34 | func (*GenesisState) Descriptor() ([]byte, []int) { 35 | return fileDescriptor_4d5747d6c1bccdf7, []int{0} 36 | } 37 | func (m *GenesisState) XXX_Unmarshal(b []byte) error { 38 | return m.Unmarshal(b) 39 | } 40 | func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { 41 | if deterministic { 42 | return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic) 43 | } else { 44 | b = b[:cap(b)] 45 | n, err := m.MarshalToSizedBuffer(b) 46 | if err != nil { 47 | return nil, err 48 | } 49 | return b[:n], nil 50 | } 51 | } 52 | func (m *GenesisState) XXX_Merge(src proto.Message) { 53 | xxx_messageInfo_GenesisState.Merge(m, src) 54 | } 55 | func (m *GenesisState) XXX_Size() int { 56 | return m.Size() 57 | } 58 | func (m *GenesisState) XXX_DiscardUnknown() { 59 | xxx_messageInfo_GenesisState.DiscardUnknown(m) 60 | } 61 | 62 | var xxx_messageInfo_GenesisState proto.InternalMessageInfo 63 | 64 | func (m *GenesisState) GetProofList() []Proof { 65 | if m != nil { 66 | return m.ProofList 67 | } 68 | return nil 69 | } 70 | 71 | func init() { 72 | proto.RegisterType((*GenesisState)(nil), "empowerchain.empowerchain.proofofexistence.GenesisState") 73 | } 74 | 75 | func init() { 76 | proto.RegisterFile("empowerchain/proofofexistence/genesis.proto", fileDescriptor_4d5747d6c1bccdf7) 77 | } 78 | 79 | var fileDescriptor_4d5747d6c1bccdf7 = []byte{ 80 | // 205 bytes of a gzipped FileDescriptorProto 81 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x4e, 0xcd, 0x2d, 0xc8, 82 | 0x2f, 0x4f, 0x2d, 0x4a, 0xce, 0x48, 0xcc, 0xcc, 0xd3, 0x2f, 0x28, 0xca, 0xcf, 0x4f, 0xcb, 0x4f, 83 | 0x4b, 0xad, 0xc8, 0x2c, 0x2e, 0x49, 0xcd, 0x4b, 0x4e, 0xd5, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 84 | 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xd2, 0x42, 0x56, 0xac, 0x87, 0xc2, 0x41, 0xd7, 85 | 0x29, 0x25, 0x92, 0x9e, 0x9f, 0x9e, 0x0f, 0xd6, 0xa6, 0x0f, 0x62, 0x41, 0x4c, 0x90, 0xd2, 0xc4, 86 | 0x6f, 0x1d, 0x58, 0x00, 0xa2, 0x54, 0x29, 0x95, 0x8b, 0xc7, 0x1d, 0x62, 0x7b, 0x70, 0x49, 0x62, 87 | 0x49, 0xaa, 0x50, 0x28, 0x17, 0x27, 0x58, 0xda, 0x27, 0xb3, 0xb8, 0x44, 0x82, 0x51, 0x81, 0x59, 88 | 0x83, 0xdb, 0xc8, 0x50, 0x8f, 0x78, 0x07, 0xe9, 0x05, 0x80, 0x04, 0x9c, 0x58, 0x4e, 0xdc, 0x93, 89 | 0x67, 0x08, 0x42, 0x98, 0xe4, 0x14, 0x7e, 0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 90 | 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, 0xc7, 0x70, 0xe1, 0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, 91 | 0x51, 0xb6, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0x28, 0xce, 0x46, 92 | 0xe1, 0x54, 0x60, 0xfa, 0xa2, 0xa4, 0xb2, 0x20, 0xb5, 0x38, 0x89, 0x0d, 0xec, 0x0d, 0x63, 0x40, 93 | 0x00, 0x00, 0x00, 0xff, 0xff, 0xbf, 0xa7, 0x7b, 0xd9, 0x62, 0x01, 0x00, 0x00, 94 | } 95 | 96 | func (m *GenesisState) Marshal() (dAtA []byte, err error) { 97 | size := m.Size() 98 | dAtA = make([]byte, size) 99 | n, err := m.MarshalToSizedBuffer(dAtA[:size]) 100 | if err != nil { 101 | return nil, err 102 | } 103 | return dAtA[:n], nil 104 | } 105 | 106 | func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) { 107 | size := m.Size() 108 | return m.MarshalToSizedBuffer(dAtA[:size]) 109 | } 110 | 111 | func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { 112 | i := len(dAtA) 113 | _ = i 114 | var l int 115 | _ = l 116 | if len(m.ProofList) > 0 { 117 | for iNdEx := len(m.ProofList) - 1; iNdEx >= 0; iNdEx-- { 118 | { 119 | size, err := m.ProofList[iNdEx].MarshalToSizedBuffer(dAtA[:i]) 120 | if err != nil { 121 | return 0, err 122 | } 123 | i -= size 124 | i = encodeVarintGenesis(dAtA, i, uint64(size)) 125 | } 126 | i-- 127 | dAtA[i] = 0xa 128 | } 129 | } 130 | return len(dAtA) - i, nil 131 | } 132 | 133 | func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { 134 | offset -= sovGenesis(v) 135 | base := offset 136 | for v >= 1<<7 { 137 | dAtA[offset] = uint8(v&0x7f | 0x80) 138 | v >>= 7 139 | offset++ 140 | } 141 | dAtA[offset] = uint8(v) 142 | return base 143 | } 144 | func (m *GenesisState) Size() (n int) { 145 | if m == nil { 146 | return 0 147 | } 148 | var l int 149 | _ = l 150 | if len(m.ProofList) > 0 { 151 | for _, e := range m.ProofList { 152 | l = e.Size() 153 | n += 1 + l + sovGenesis(uint64(l)) 154 | } 155 | } 156 | return n 157 | } 158 | 159 | func sovGenesis(x uint64) (n int) { 160 | return (math_bits.Len64(x|1) + 6) / 7 161 | } 162 | func sozGenesis(x uint64) (n int) { 163 | return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) 164 | } 165 | func (m *GenesisState) Unmarshal(dAtA []byte) error { 166 | l := len(dAtA) 167 | iNdEx := 0 168 | for iNdEx < l { 169 | preIndex := iNdEx 170 | var wire uint64 171 | for shift := uint(0); ; shift += 7 { 172 | if shift >= 64 { 173 | return ErrIntOverflowGenesis 174 | } 175 | if iNdEx >= l { 176 | return io.ErrUnexpectedEOF 177 | } 178 | b := dAtA[iNdEx] 179 | iNdEx++ 180 | wire |= uint64(b&0x7F) << shift 181 | if b < 0x80 { 182 | break 183 | } 184 | } 185 | fieldNum := int32(wire >> 3) 186 | wireType := int(wire & 0x7) 187 | if wireType == 4 { 188 | return fmt.Errorf("proto: GenesisState: wiretype end group for non-group") 189 | } 190 | if fieldNum <= 0 { 191 | return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) 192 | } 193 | switch fieldNum { 194 | case 1: 195 | if wireType != 2 { 196 | return fmt.Errorf("proto: wrong wireType = %d for field ProofList", wireType) 197 | } 198 | var msglen int 199 | for shift := uint(0); ; shift += 7 { 200 | if shift >= 64 { 201 | return ErrIntOverflowGenesis 202 | } 203 | if iNdEx >= l { 204 | return io.ErrUnexpectedEOF 205 | } 206 | b := dAtA[iNdEx] 207 | iNdEx++ 208 | msglen |= int(b&0x7F) << shift 209 | if b < 0x80 { 210 | break 211 | } 212 | } 213 | if msglen < 0 { 214 | return ErrInvalidLengthGenesis 215 | } 216 | postIndex := iNdEx + msglen 217 | if postIndex < 0 { 218 | return ErrInvalidLengthGenesis 219 | } 220 | if postIndex > l { 221 | return io.ErrUnexpectedEOF 222 | } 223 | m.ProofList = append(m.ProofList, Proof{}) 224 | if err := m.ProofList[len(m.ProofList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { 225 | return err 226 | } 227 | iNdEx = postIndex 228 | default: 229 | iNdEx = preIndex 230 | skippy, err := skipGenesis(dAtA[iNdEx:]) 231 | if err != nil { 232 | return err 233 | } 234 | if (skippy < 0) || (iNdEx+skippy) < 0 { 235 | return ErrInvalidLengthGenesis 236 | } 237 | if (iNdEx + skippy) > l { 238 | return io.ErrUnexpectedEOF 239 | } 240 | iNdEx += skippy 241 | } 242 | } 243 | 244 | if iNdEx > l { 245 | return io.ErrUnexpectedEOF 246 | } 247 | return nil 248 | } 249 | func skipGenesis(dAtA []byte) (n int, err error) { 250 | l := len(dAtA) 251 | iNdEx := 0 252 | depth := 0 253 | for iNdEx < l { 254 | var wire uint64 255 | for shift := uint(0); ; shift += 7 { 256 | if shift >= 64 { 257 | return 0, ErrIntOverflowGenesis 258 | } 259 | if iNdEx >= l { 260 | return 0, io.ErrUnexpectedEOF 261 | } 262 | b := dAtA[iNdEx] 263 | iNdEx++ 264 | wire |= (uint64(b) & 0x7F) << shift 265 | if b < 0x80 { 266 | break 267 | } 268 | } 269 | wireType := int(wire & 0x7) 270 | switch wireType { 271 | case 0: 272 | for shift := uint(0); ; shift += 7 { 273 | if shift >= 64 { 274 | return 0, ErrIntOverflowGenesis 275 | } 276 | if iNdEx >= l { 277 | return 0, io.ErrUnexpectedEOF 278 | } 279 | iNdEx++ 280 | if dAtA[iNdEx-1] < 0x80 { 281 | break 282 | } 283 | } 284 | case 1: 285 | iNdEx += 8 286 | case 2: 287 | var length int 288 | for shift := uint(0); ; shift += 7 { 289 | if shift >= 64 { 290 | return 0, ErrIntOverflowGenesis 291 | } 292 | if iNdEx >= l { 293 | return 0, io.ErrUnexpectedEOF 294 | } 295 | b := dAtA[iNdEx] 296 | iNdEx++ 297 | length |= (int(b) & 0x7F) << shift 298 | if b < 0x80 { 299 | break 300 | } 301 | } 302 | if length < 0 { 303 | return 0, ErrInvalidLengthGenesis 304 | } 305 | iNdEx += length 306 | case 3: 307 | depth++ 308 | case 4: 309 | if depth == 0 { 310 | return 0, ErrUnexpectedEndOfGroupGenesis 311 | } 312 | depth-- 313 | case 5: 314 | iNdEx += 4 315 | default: 316 | return 0, fmt.Errorf("proto: illegal wireType %d", wireType) 317 | } 318 | if iNdEx < 0 { 319 | return 0, ErrInvalidLengthGenesis 320 | } 321 | if depth == 0 { 322 | return iNdEx, nil 323 | } 324 | } 325 | return 0, io.ErrUnexpectedEOF 326 | } 327 | 328 | var ( 329 | ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") 330 | ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") 331 | ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") 332 | ) 333 | -------------------------------------------------------------------------------- /chain/cmd/empowerd/cmd/root.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "errors" 5 | "io" 6 | "os" 7 | "path/filepath" 8 | 9 | "github.com/empowerchain/empowerchain/app" 10 | "github.com/empowerchain/empowerchain/app/params" 11 | 12 | serverconfig "github.com/cosmos/cosmos-sdk/server/config" 13 | "github.com/spf13/cast" 14 | "github.com/spf13/cobra" 15 | tmcfg "github.com/tendermint/tendermint/config" 16 | tmcli "github.com/tendermint/tendermint/libs/cli" 17 | "github.com/tendermint/tendermint/libs/log" 18 | dbm "github.com/tendermint/tm-db" 19 | 20 | "github.com/cosmos/cosmos-sdk/baseapp" 21 | "github.com/cosmos/cosmos-sdk/client" 22 | "github.com/cosmos/cosmos-sdk/client/config" 23 | "github.com/cosmos/cosmos-sdk/client/debug" 24 | "github.com/cosmos/cosmos-sdk/client/flags" 25 | "github.com/cosmos/cosmos-sdk/client/keys" 26 | "github.com/cosmos/cosmos-sdk/client/rpc" 27 | "github.com/cosmos/cosmos-sdk/server" 28 | servertypes "github.com/cosmos/cosmos-sdk/server/types" 29 | "github.com/cosmos/cosmos-sdk/snapshots" 30 | snapshottypes "github.com/cosmos/cosmos-sdk/snapshots/types" 31 | "github.com/cosmos/cosmos-sdk/store" 32 | sdk "github.com/cosmos/cosmos-sdk/types" 33 | authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" 34 | "github.com/cosmos/cosmos-sdk/x/auth/types" 35 | banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" 36 | "github.com/cosmos/cosmos-sdk/x/crisis" 37 | genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" 38 | ) 39 | 40 | // NewRootCmd creates a new root command for empowerd. It is called once in the main function. 41 | func NewRootCmd() (*cobra.Command, params.EncodingConfig) { 42 | encodingConfig := params.MakeEncodingConfig(app.ModuleBasics) 43 | initClientCtx := client.Context{}. 44 | WithCodec(encodingConfig.Codec). 45 | WithInterfaceRegistry(encodingConfig.InterfaceRegistry). 46 | WithTxConfig(encodingConfig.TxConfig). 47 | WithLegacyAmino(encodingConfig.Amino). 48 | WithInput(os.Stdin). 49 | WithAccountRetriever(types.AccountRetriever{}). 50 | WithHomeDir(app.DefaultNodeHome). 51 | WithViper("") // In app, we don't use any prefix for env variables. 52 | 53 | rootCmd := &cobra.Command{ 54 | Use: "empowerd", 55 | Short: "EmpowerChain CLI", 56 | PersistentPreRunE: func(cmd *cobra.Command, _ []string) error { 57 | // set the default command outputs 58 | cmd.SetOut(cmd.OutOrStdout()) 59 | cmd.SetErr(cmd.ErrOrStderr()) 60 | 61 | initClientCtx, err := client.ReadPersistentCommandFlags(initClientCtx, cmd.Flags()) 62 | if err != nil { 63 | return err 64 | } 65 | 66 | initClientCtx, err = config.ReadFromClientConfig(initClientCtx) 67 | if err != nil { 68 | return err 69 | } 70 | 71 | if err := client.SetCmdClientContextHandler(initClientCtx, cmd); err != nil { 72 | return err 73 | } 74 | 75 | customAppTemplate, customAppConfig := initAppConfig() 76 | 77 | customTMConfig := initTendermintConfig() 78 | 79 | return server.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig, customTMConfig) 80 | }, 81 | } 82 | 83 | initRootCmd(rootCmd, encodingConfig) 84 | 85 | return rootCmd, encodingConfig 86 | } 87 | 88 | // initAppConfig helps to override default appConfig template and configs. 89 | // return "", nil if no custom configuration is required for the application. 90 | func initAppConfig() (string, interface{}) { 91 | // The following code snippet is just for reference. 92 | 93 | // WASMConfig defines configuration for the wasm module. 94 | type WASMConfig struct { 95 | // This is the maximum sdk gas (wasm and storage) that we allow for any x/wasm "smart" queries 96 | QueryGasLimit uint64 `mapstructure:"query_gas_limit"` 97 | 98 | // Address defines the gRPC-web server to listen on 99 | LruSize uint64 `mapstructure:"lru_size"` 100 | } 101 | 102 | type CustomAppConfig struct { 103 | serverconfig.Config 104 | 105 | WASM WASMConfig `mapstructure:"wasm"` 106 | } 107 | 108 | // Optionally allow the chain developer to overwrite the SDK's default 109 | // server config. 110 | srvCfg := serverconfig.DefaultConfig() 111 | // The SDK's default minimum gas price is set to "" (empty value) inside 112 | // app.toml. If left empty by validators, the node will halt on startup. 113 | // However, the chain developer can set a default app.toml value for their 114 | // validators here. 115 | // 116 | // In summary: 117 | // - if you leave srvCfg.MinGasPrices = "", all validators MUST tweak their 118 | // own app.toml config, 119 | // - if you set srvCfg.MinGasPrices non-empty, validators CAN tweak their 120 | // own app.toml to override, or use this default value. 121 | // 122 | // In app, we set the min gas prices to 0. 123 | srvCfg.MinGasPrices = "0stake" 124 | 125 | customAppConfig := CustomAppConfig{ 126 | Config: *srvCfg, 127 | WASM: WASMConfig{ 128 | LruSize: 1, 129 | QueryGasLimit: 300000, 130 | }, 131 | } 132 | 133 | customAppTemplate := serverconfig.DefaultConfigTemplate + ` 134 | [wasm] 135 | # This is the maximum sdk gas (wasm and storage) that we allow for any x/wasm "smart" queries 136 | query_gas_limit = 300000 137 | # This is the number of wasm vm instances we keep cached in memory for speed-up 138 | # Warning: this is currently unstable and may lead to crashes, best to keep for 0 unless testing locally 139 | lru_size = 0` 140 | 141 | return customAppTemplate, customAppConfig 142 | } 143 | 144 | // initTendermintConfig helps to override default Tendermint Config values. 145 | // return tmcfg.DefaultConfig if no custom configuration is required for the application. 146 | func initTendermintConfig() *tmcfg.Config { 147 | cfg := tmcfg.DefaultConfig() 148 | 149 | // these values put a higher strain on node memory 150 | // cfg.P2P.MaxNumInboundPeers = 100 151 | // cfg.P2P.MaxNumOutboundPeers = 40 152 | 153 | return cfg 154 | } 155 | 156 | func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { 157 | cfg := sdk.GetConfig() 158 | cfg.Seal() 159 | 160 | rootCmd.AddCommand( 161 | genutilcli.InitCmd(app.ModuleBasics, app.DefaultNodeHome), 162 | genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome), 163 | genutilcli.MigrateGenesisCmd(), 164 | genutilcli.GenTxCmd(app.ModuleBasics, encodingConfig.TxConfig, banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome), 165 | genutilcli.ValidateGenesisCmd(app.ModuleBasics), 166 | AddGenesisAccountCmd(app.DefaultNodeHome), 167 | tmcli.NewCompletionCmd(rootCmd, true), 168 | testnetCmd(app.ModuleBasics, banktypes.GenesisBalancesIterator{}), 169 | debug.Cmd(), 170 | config.Cmd(), 171 | ) 172 | 173 | a := appCreator{encodingConfig} 174 | server.AddCommands(rootCmd, app.DefaultNodeHome, a.newApp, a.appExport, addModuleInitFlags) 175 | 176 | // add keybase, auxiliary RPC, query, and tx child commands 177 | rootCmd.AddCommand( 178 | rpc.StatusCommand(), 179 | queryCommand(), 180 | txCommand(), 181 | keys.Commands(app.DefaultNodeHome), 182 | ) 183 | 184 | // add rosetta 185 | rootCmd.AddCommand(server.RosettaCommand(encodingConfig.InterfaceRegistry, encodingConfig.Codec)) 186 | } 187 | 188 | func addModuleInitFlags(startCmd *cobra.Command) { 189 | crisis.AddModuleInitFlags(startCmd) 190 | } 191 | 192 | func queryCommand() *cobra.Command { 193 | cmd := &cobra.Command{ 194 | Use: "query", 195 | Aliases: []string{"q"}, 196 | Short: "Querying subcommands", 197 | DisableFlagParsing: true, 198 | SuggestionsMinimumDistance: 2, 199 | RunE: client.ValidateCmd, 200 | } 201 | 202 | cmd.AddCommand( 203 | authcmd.GetAccountCmd(), 204 | rpc.ValidatorCommand(), 205 | rpc.BlockCommand(), 206 | authcmd.QueryTxsByEventsCmd(), 207 | authcmd.QueryTxCmd(), 208 | ) 209 | 210 | app.ModuleBasics.AddQueryCommands(cmd) 211 | cmd.PersistentFlags().String(flags.FlagChainID, "", "The network chain ID") 212 | 213 | return cmd 214 | } 215 | 216 | func txCommand() *cobra.Command { 217 | cmd := &cobra.Command{ 218 | Use: "tx", 219 | Short: "Transactions subcommands", 220 | DisableFlagParsing: true, 221 | SuggestionsMinimumDistance: 2, 222 | RunE: client.ValidateCmd, 223 | } 224 | 225 | cmd.AddCommand( 226 | authcmd.GetSignCommand(), 227 | authcmd.GetSignBatchCommand(), 228 | authcmd.GetMultiSignCommand(), 229 | authcmd.GetMultiSignBatchCmd(), 230 | authcmd.GetValidateSignaturesCommand(), 231 | authcmd.GetBroadcastCommand(), 232 | authcmd.GetEncodeCommand(), 233 | authcmd.GetDecodeCommand(), 234 | ) 235 | 236 | app.ModuleBasics.AddTxCommands(cmd) 237 | cmd.PersistentFlags().String(flags.FlagChainID, "", "The network chain ID") 238 | 239 | return cmd 240 | } 241 | 242 | type appCreator struct { 243 | encCfg params.EncodingConfig 244 | } 245 | 246 | // newApp is an appCreator 247 | func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, appOpts servertypes.AppOptions) servertypes.Application { 248 | var cache sdk.MultiStorePersistentCache 249 | 250 | if cast.ToBool(appOpts.Get(server.FlagInterBlockCache)) { 251 | cache = store.NewCommitKVStoreCacheManager() 252 | } 253 | 254 | skipUpgradeHeights := make(map[int64]bool) 255 | for _, h := range cast.ToIntSlice(appOpts.Get(server.FlagUnsafeSkipUpgrades)) { 256 | skipUpgradeHeights[int64(h)] = true 257 | } 258 | 259 | pruningOpts, err := server.GetPruningOptionsFromFlags(appOpts) 260 | if err != nil { 261 | panic(err) 262 | } 263 | 264 | snapshotDir := filepath.Join(cast.ToString(appOpts.Get(flags.FlagHome)), "data", "snapshots") 265 | snapshotDB, err := dbm.NewDB("metadata", server.GetAppDBBackend(appOpts), snapshotDir) 266 | if err != nil { 267 | panic(err) 268 | } 269 | snapshotStore, err := snapshots.NewStore(snapshotDB, snapshotDir) 270 | if err != nil { 271 | panic(err) 272 | } 273 | 274 | snapshotOptions := snapshottypes.NewSnapshotOptions( 275 | cast.ToUint64(appOpts.Get(server.FlagStateSyncSnapshotInterval)), 276 | cast.ToUint32(appOpts.Get(server.FlagStateSyncSnapshotKeepRecent)), 277 | ) 278 | 279 | return app.New( 280 | logger, db, traceStore, true, skipUpgradeHeights, 281 | cast.ToString(appOpts.Get(flags.FlagHome)), 282 | cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)), 283 | a.encCfg, 284 | appOpts, 285 | baseapp.SetPruning(pruningOpts), 286 | baseapp.SetMinGasPrices(cast.ToString(appOpts.Get(server.FlagMinGasPrices))), 287 | baseapp.SetHaltHeight(cast.ToUint64(appOpts.Get(server.FlagHaltHeight))), 288 | baseapp.SetHaltTime(cast.ToUint64(appOpts.Get(server.FlagHaltTime))), 289 | baseapp.SetMinRetainBlocks(cast.ToUint64(appOpts.Get(server.FlagMinRetainBlocks))), 290 | baseapp.SetInterBlockCache(cache), 291 | baseapp.SetTrace(cast.ToBool(appOpts.Get(server.FlagTrace))), 292 | baseapp.SetIndexEvents(cast.ToStringSlice(appOpts.Get(server.FlagIndexEvents))), 293 | baseapp.SetSnapshot(snapshotStore, snapshotOptions), 294 | ) 295 | } 296 | 297 | // appExport creates a new app (optionally at a given height) 298 | // and exports state. 299 | func (a appCreator) appExport(logger log.Logger, db dbm.DB, traceStore io.Writer, height int64, forZeroHeight bool, jailAllowedAddrs []string, appOpts servertypes.AppOptions) (servertypes.ExportedApp, error) { 300 | var empowerApp *app.App 301 | homePath, ok := appOpts.Get(flags.FlagHome).(string) 302 | if !ok || homePath == "" { 303 | return servertypes.ExportedApp{}, errors.New("application home not set") 304 | } 305 | 306 | if height != -1 { 307 | empowerApp = app.New(logger, db, traceStore, false, map[int64]bool{}, homePath, uint(1), a.encCfg, appOpts) 308 | 309 | if err := empowerApp.LoadHeight(height); err != nil { 310 | return servertypes.ExportedApp{}, err 311 | } 312 | } else { 313 | empowerApp = app.New(logger, db, traceStore, true, map[int64]bool{}, homePath, uint(1), a.encCfg, appOpts) 314 | } 315 | 316 | return empowerApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs) 317 | } 318 | -------------------------------------------------------------------------------- /chain/x/proofofexistence/types/proof.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-gogo. DO NOT EDIT. 2 | // source: empowerchain/proofofexistence/proof.proto 3 | 4 | package types 5 | 6 | import ( 7 | fmt "fmt" 8 | _ "github.com/gogo/protobuf/gogoproto" 9 | proto "github.com/gogo/protobuf/proto" 10 | github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" 11 | _ "github.com/golang/protobuf/ptypes/timestamp" 12 | io "io" 13 | math "math" 14 | math_bits "math/bits" 15 | time "time" 16 | ) 17 | 18 | // Reference imports to suppress errors if they are not otherwise used. 19 | var _ = proto.Marshal 20 | var _ = fmt.Errorf 21 | var _ = math.Inf 22 | var _ = time.Kitchen 23 | 24 | // This is a compile-time assertion to ensure that this generated file 25 | // is compatible with the proto package it is being compiled against. 26 | // A compilation error at this line likely means your copy of the 27 | // proto package needs to be updated. 28 | const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package 29 | 30 | type Proof struct { 31 | // Hash is the SHA-256 hash of the data of which is being made a proof for. 32 | // The hash needs to be sent as a Base64 encoded string. 33 | Hash string `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` 34 | // Timestamp is the time the proof was added on-chain (block time) 35 | Timestamp time.Time `protobuf:"bytes,2,opt,name=timestamp,proto3,stdtime" json:"timestamp" yaml:"timestamp"` 36 | // Reporter is the account address that created the proof 37 | Reporter string `protobuf:"bytes,3,opt,name=reporter,proto3" json:"reporter,omitempty"` 38 | } 39 | 40 | func (m *Proof) Reset() { *m = Proof{} } 41 | func (m *Proof) String() string { return proto.CompactTextString(m) } 42 | func (*Proof) ProtoMessage() {} 43 | func (*Proof) Descriptor() ([]byte, []int) { 44 | return fileDescriptor_df2ebf73a2cd905c, []int{0} 45 | } 46 | func (m *Proof) XXX_Unmarshal(b []byte) error { 47 | return m.Unmarshal(b) 48 | } 49 | func (m *Proof) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { 50 | if deterministic { 51 | return xxx_messageInfo_Proof.Marshal(b, m, deterministic) 52 | } else { 53 | b = b[:cap(b)] 54 | n, err := m.MarshalToSizedBuffer(b) 55 | if err != nil { 56 | return nil, err 57 | } 58 | return b[:n], nil 59 | } 60 | } 61 | func (m *Proof) XXX_Merge(src proto.Message) { 62 | xxx_messageInfo_Proof.Merge(m, src) 63 | } 64 | func (m *Proof) XXX_Size() int { 65 | return m.Size() 66 | } 67 | func (m *Proof) XXX_DiscardUnknown() { 68 | xxx_messageInfo_Proof.DiscardUnknown(m) 69 | } 70 | 71 | var xxx_messageInfo_Proof proto.InternalMessageInfo 72 | 73 | func (m *Proof) GetHash() string { 74 | if m != nil { 75 | return m.Hash 76 | } 77 | return "" 78 | } 79 | 80 | func (m *Proof) GetTimestamp() time.Time { 81 | if m != nil { 82 | return m.Timestamp 83 | } 84 | return time.Time{} 85 | } 86 | 87 | func (m *Proof) GetReporter() string { 88 | if m != nil { 89 | return m.Reporter 90 | } 91 | return "" 92 | } 93 | 94 | func init() { 95 | proto.RegisterType((*Proof)(nil), "empowerchain.empowerchain.proofofexistence.Proof") 96 | } 97 | 98 | func init() { 99 | proto.RegisterFile("empowerchain/proofofexistence/proof.proto", fileDescriptor_df2ebf73a2cd905c) 100 | } 101 | 102 | var fileDescriptor_df2ebf73a2cd905c = []byte{ 103 | // 263 bytes of a gzipped FileDescriptorProto 104 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x4c, 0xcd, 0x2d, 0xc8, 105 | 0x2f, 0x4f, 0x2d, 0x4a, 0xce, 0x48, 0xcc, 0xcc, 0xd3, 0x2f, 0x28, 0xca, 0xcf, 0x4f, 0xcb, 0x4f, 106 | 0x4b, 0xad, 0xc8, 0x2c, 0x2e, 0x49, 0xcd, 0x4b, 0x4e, 0x85, 0x08, 0xe8, 0x15, 0x14, 0xe5, 0x97, 107 | 0xe4, 0x0b, 0x69, 0x21, 0x2b, 0xd5, 0x43, 0xe1, 0xa0, 0xeb, 0x93, 0x92, 0x4f, 0xcf, 0xcf, 0x4f, 108 | 0xcf, 0x01, 0xeb, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0xc9, 0xcc, 0x4d, 0x2d, 0x2e, 0x49, 109 | 0xcc, 0x2d, 0x80, 0x18, 0x26, 0x25, 0x92, 0x9e, 0x9f, 0x9e, 0x0f, 0x66, 0xea, 0x83, 0x58, 0x10, 110 | 0x51, 0xa5, 0x7e, 0x46, 0x2e, 0xd6, 0x00, 0x90, 0x59, 0x42, 0x42, 0x5c, 0x2c, 0x19, 0x89, 0xc5, 111 | 0x19, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x60, 0xb6, 0x50, 0x18, 0x17, 0x27, 0xdc, 0x18, 112 | 0x09, 0x26, 0x05, 0x46, 0x0d, 0x6e, 0x23, 0x29, 0x3d, 0x88, 0x45, 0x7a, 0x30, 0x8b, 0xf4, 0x42, 113 | 0x60, 0x2a, 0x9c, 0x64, 0x4e, 0xdc, 0x93, 0x67, 0xf8, 0x74, 0x4f, 0x5e, 0xa0, 0x32, 0x31, 0x37, 114 | 0xc7, 0x4a, 0x09, 0xae, 0x55, 0x69, 0xc2, 0x7d, 0x79, 0xc6, 0x20, 0x84, 0x51, 0x42, 0x52, 0x5c, 115 | 0x1c, 0x45, 0xa9, 0x05, 0xf9, 0x45, 0x25, 0xa9, 0x45, 0x12, 0xcc, 0x60, 0xfb, 0xe0, 0x7c, 0xa7, 116 | 0xf0, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 117 | 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0xb2, 0x4d, 0xcf, 0x2c, 0xc9, 118 | 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x47, 0x09, 0x44, 0x14, 0x4e, 0x05, 0x66, 0x98, 0x96, 119 | 0x54, 0x16, 0xa4, 0x16, 0x27, 0xb1, 0x81, 0x5d, 0x6c, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x80, 120 | 0x9f, 0x55, 0x9b, 0x81, 0x01, 0x00, 0x00, 121 | } 122 | 123 | func (m *Proof) Marshal() (dAtA []byte, err error) { 124 | size := m.Size() 125 | dAtA = make([]byte, size) 126 | n, err := m.MarshalToSizedBuffer(dAtA[:size]) 127 | if err != nil { 128 | return nil, err 129 | } 130 | return dAtA[:n], nil 131 | } 132 | 133 | func (m *Proof) MarshalTo(dAtA []byte) (int, error) { 134 | size := m.Size() 135 | return m.MarshalToSizedBuffer(dAtA[:size]) 136 | } 137 | 138 | func (m *Proof) MarshalToSizedBuffer(dAtA []byte) (int, error) { 139 | i := len(dAtA) 140 | _ = i 141 | var l int 142 | _ = l 143 | if len(m.Reporter) > 0 { 144 | i -= len(m.Reporter) 145 | copy(dAtA[i:], m.Reporter) 146 | i = encodeVarintProof(dAtA, i, uint64(len(m.Reporter))) 147 | i-- 148 | dAtA[i] = 0x1a 149 | } 150 | n1, err1 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) 151 | if err1 != nil { 152 | return 0, err1 153 | } 154 | i -= n1 155 | i = encodeVarintProof(dAtA, i, uint64(n1)) 156 | i-- 157 | dAtA[i] = 0x12 158 | if len(m.Hash) > 0 { 159 | i -= len(m.Hash) 160 | copy(dAtA[i:], m.Hash) 161 | i = encodeVarintProof(dAtA, i, uint64(len(m.Hash))) 162 | i-- 163 | dAtA[i] = 0xa 164 | } 165 | return len(dAtA) - i, nil 166 | } 167 | 168 | func encodeVarintProof(dAtA []byte, offset int, v uint64) int { 169 | offset -= sovProof(v) 170 | base := offset 171 | for v >= 1<<7 { 172 | dAtA[offset] = uint8(v&0x7f | 0x80) 173 | v >>= 7 174 | offset++ 175 | } 176 | dAtA[offset] = uint8(v) 177 | return base 178 | } 179 | func (m *Proof) Size() (n int) { 180 | if m == nil { 181 | return 0 182 | } 183 | var l int 184 | _ = l 185 | l = len(m.Hash) 186 | if l > 0 { 187 | n += 1 + l + sovProof(uint64(l)) 188 | } 189 | l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp) 190 | n += 1 + l + sovProof(uint64(l)) 191 | l = len(m.Reporter) 192 | if l > 0 { 193 | n += 1 + l + sovProof(uint64(l)) 194 | } 195 | return n 196 | } 197 | 198 | func sovProof(x uint64) (n int) { 199 | return (math_bits.Len64(x|1) + 6) / 7 200 | } 201 | func sozProof(x uint64) (n int) { 202 | return sovProof(uint64((x << 1) ^ uint64((int64(x) >> 63)))) 203 | } 204 | func (m *Proof) Unmarshal(dAtA []byte) error { 205 | l := len(dAtA) 206 | iNdEx := 0 207 | for iNdEx < l { 208 | preIndex := iNdEx 209 | var wire uint64 210 | for shift := uint(0); ; shift += 7 { 211 | if shift >= 64 { 212 | return ErrIntOverflowProof 213 | } 214 | if iNdEx >= l { 215 | return io.ErrUnexpectedEOF 216 | } 217 | b := dAtA[iNdEx] 218 | iNdEx++ 219 | wire |= uint64(b&0x7F) << shift 220 | if b < 0x80 { 221 | break 222 | } 223 | } 224 | fieldNum := int32(wire >> 3) 225 | wireType := int(wire & 0x7) 226 | if wireType == 4 { 227 | return fmt.Errorf("proto: Proof: wiretype end group for non-group") 228 | } 229 | if fieldNum <= 0 { 230 | return fmt.Errorf("proto: Proof: illegal tag %d (wire type %d)", fieldNum, wire) 231 | } 232 | switch fieldNum { 233 | case 1: 234 | if wireType != 2 { 235 | return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) 236 | } 237 | var stringLen uint64 238 | for shift := uint(0); ; shift += 7 { 239 | if shift >= 64 { 240 | return ErrIntOverflowProof 241 | } 242 | if iNdEx >= l { 243 | return io.ErrUnexpectedEOF 244 | } 245 | b := dAtA[iNdEx] 246 | iNdEx++ 247 | stringLen |= uint64(b&0x7F) << shift 248 | if b < 0x80 { 249 | break 250 | } 251 | } 252 | intStringLen := int(stringLen) 253 | if intStringLen < 0 { 254 | return ErrInvalidLengthProof 255 | } 256 | postIndex := iNdEx + intStringLen 257 | if postIndex < 0 { 258 | return ErrInvalidLengthProof 259 | } 260 | if postIndex > l { 261 | return io.ErrUnexpectedEOF 262 | } 263 | m.Hash = string(dAtA[iNdEx:postIndex]) 264 | iNdEx = postIndex 265 | case 2: 266 | if wireType != 2 { 267 | return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) 268 | } 269 | var msglen int 270 | for shift := uint(0); ; shift += 7 { 271 | if shift >= 64 { 272 | return ErrIntOverflowProof 273 | } 274 | if iNdEx >= l { 275 | return io.ErrUnexpectedEOF 276 | } 277 | b := dAtA[iNdEx] 278 | iNdEx++ 279 | msglen |= int(b&0x7F) << shift 280 | if b < 0x80 { 281 | break 282 | } 283 | } 284 | if msglen < 0 { 285 | return ErrInvalidLengthProof 286 | } 287 | postIndex := iNdEx + msglen 288 | if postIndex < 0 { 289 | return ErrInvalidLengthProof 290 | } 291 | if postIndex > l { 292 | return io.ErrUnexpectedEOF 293 | } 294 | if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Timestamp, dAtA[iNdEx:postIndex]); err != nil { 295 | return err 296 | } 297 | iNdEx = postIndex 298 | case 3: 299 | if wireType != 2 { 300 | return fmt.Errorf("proto: wrong wireType = %d for field Reporter", wireType) 301 | } 302 | var stringLen uint64 303 | for shift := uint(0); ; shift += 7 { 304 | if shift >= 64 { 305 | return ErrIntOverflowProof 306 | } 307 | if iNdEx >= l { 308 | return io.ErrUnexpectedEOF 309 | } 310 | b := dAtA[iNdEx] 311 | iNdEx++ 312 | stringLen |= uint64(b&0x7F) << shift 313 | if b < 0x80 { 314 | break 315 | } 316 | } 317 | intStringLen := int(stringLen) 318 | if intStringLen < 0 { 319 | return ErrInvalidLengthProof 320 | } 321 | postIndex := iNdEx + intStringLen 322 | if postIndex < 0 { 323 | return ErrInvalidLengthProof 324 | } 325 | if postIndex > l { 326 | return io.ErrUnexpectedEOF 327 | } 328 | m.Reporter = string(dAtA[iNdEx:postIndex]) 329 | iNdEx = postIndex 330 | default: 331 | iNdEx = preIndex 332 | skippy, err := skipProof(dAtA[iNdEx:]) 333 | if err != nil { 334 | return err 335 | } 336 | if (skippy < 0) || (iNdEx+skippy) < 0 { 337 | return ErrInvalidLengthProof 338 | } 339 | if (iNdEx + skippy) > l { 340 | return io.ErrUnexpectedEOF 341 | } 342 | iNdEx += skippy 343 | } 344 | } 345 | 346 | if iNdEx > l { 347 | return io.ErrUnexpectedEOF 348 | } 349 | return nil 350 | } 351 | func skipProof(dAtA []byte) (n int, err error) { 352 | l := len(dAtA) 353 | iNdEx := 0 354 | depth := 0 355 | for iNdEx < l { 356 | var wire uint64 357 | for shift := uint(0); ; shift += 7 { 358 | if shift >= 64 { 359 | return 0, ErrIntOverflowProof 360 | } 361 | if iNdEx >= l { 362 | return 0, io.ErrUnexpectedEOF 363 | } 364 | b := dAtA[iNdEx] 365 | iNdEx++ 366 | wire |= (uint64(b) & 0x7F) << shift 367 | if b < 0x80 { 368 | break 369 | } 370 | } 371 | wireType := int(wire & 0x7) 372 | switch wireType { 373 | case 0: 374 | for shift := uint(0); ; shift += 7 { 375 | if shift >= 64 { 376 | return 0, ErrIntOverflowProof 377 | } 378 | if iNdEx >= l { 379 | return 0, io.ErrUnexpectedEOF 380 | } 381 | iNdEx++ 382 | if dAtA[iNdEx-1] < 0x80 { 383 | break 384 | } 385 | } 386 | case 1: 387 | iNdEx += 8 388 | case 2: 389 | var length int 390 | for shift := uint(0); ; shift += 7 { 391 | if shift >= 64 { 392 | return 0, ErrIntOverflowProof 393 | } 394 | if iNdEx >= l { 395 | return 0, io.ErrUnexpectedEOF 396 | } 397 | b := dAtA[iNdEx] 398 | iNdEx++ 399 | length |= (int(b) & 0x7F) << shift 400 | if b < 0x80 { 401 | break 402 | } 403 | } 404 | if length < 0 { 405 | return 0, ErrInvalidLengthProof 406 | } 407 | iNdEx += length 408 | case 3: 409 | depth++ 410 | case 4: 411 | if depth == 0 { 412 | return 0, ErrUnexpectedEndOfGroupProof 413 | } 414 | depth-- 415 | case 5: 416 | iNdEx += 4 417 | default: 418 | return 0, fmt.Errorf("proto: illegal wireType %d", wireType) 419 | } 420 | if iNdEx < 0 { 421 | return 0, ErrInvalidLengthProof 422 | } 423 | if depth == 0 { 424 | return iNdEx, nil 425 | } 426 | } 427 | return 0, io.ErrUnexpectedEOF 428 | } 429 | 430 | var ( 431 | ErrInvalidLengthProof = fmt.Errorf("proto: negative length found during unmarshaling") 432 | ErrIntOverflowProof = fmt.Errorf("proto: integer overflow") 433 | ErrUnexpectedEndOfGroupProof = fmt.Errorf("proto: unexpected end of group") 434 | ) 435 | -------------------------------------------------------------------------------- /chain/cmd/empowerd/cmd/testnet.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | // DONTCOVER 4 | 5 | import ( 6 | "bufio" 7 | "encoding/json" 8 | "fmt" 9 | "net" 10 | "os" 11 | "path/filepath" 12 | 13 | "github.com/spf13/cobra" 14 | tmconfig "github.com/tendermint/tendermint/config" 15 | tmos "github.com/tendermint/tendermint/libs/os" 16 | tmrand "github.com/tendermint/tendermint/libs/rand" 17 | "github.com/tendermint/tendermint/types" 18 | tmtime "github.com/tendermint/tendermint/types/time" 19 | 20 | "github.com/cosmos/cosmos-sdk/client" 21 | "github.com/cosmos/cosmos-sdk/client/flags" 22 | "github.com/cosmos/cosmos-sdk/client/tx" 23 | "github.com/cosmos/cosmos-sdk/crypto/hd" 24 | "github.com/cosmos/cosmos-sdk/crypto/keyring" 25 | cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" 26 | "github.com/cosmos/cosmos-sdk/server" 27 | srvconfig "github.com/cosmos/cosmos-sdk/server/config" 28 | "github.com/cosmos/cosmos-sdk/testutil" 29 | sdk "github.com/cosmos/cosmos-sdk/types" 30 | "github.com/cosmos/cosmos-sdk/types/module" 31 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" 32 | banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" 33 | "github.com/cosmos/cosmos-sdk/x/genutil" 34 | genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" 35 | stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" 36 | ) 37 | 38 | var ( 39 | flagNodeDirPrefix = "node-dir-prefix" 40 | flagNumValidators = "v" 41 | flagOutputDir = "output-dir" 42 | flagNodeDaemonHome = "node-daemon-home" 43 | flagStartingIPAddress = "starting-ip-address" 44 | ) 45 | 46 | // get cmd to initialize all files for tendermint testnet and application 47 | func testnetCmd(mbm module.BasicManager, genBalIterator banktypes.GenesisBalancesIterator) *cobra.Command { 48 | cmd := &cobra.Command{ 49 | Use: "testnet", 50 | Short: "Initialize files for a EmpowerChain testnet", 51 | Long: `testnet will create "v" number of directories and populate each with 52 | necessary files (private validator, genesis, config, etc.). 53 | 54 | Note, strict routability for addresses is turned off in the config file. 55 | 56 | Example: 57 | simd testnet --v 4 --output-dir ./output --starting-ip-address 192.168.10.2 58 | `, 59 | RunE: func(cmd *cobra.Command, _ []string) error { 60 | clientCtx, err := client.GetClientQueryContext(cmd) 61 | if err != nil { 62 | return err 63 | } 64 | 65 | serverCtx := server.GetServerContextFromCmd(cmd) 66 | config := serverCtx.Config 67 | 68 | outputDir, _ := cmd.Flags().GetString(flagOutputDir) 69 | keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend) 70 | chainID, _ := cmd.Flags().GetString(flags.FlagChainID) 71 | minGasPrices, _ := cmd.Flags().GetString(server.FlagMinGasPrices) 72 | nodeDirPrefix, _ := cmd.Flags().GetString(flagNodeDirPrefix) 73 | nodeDaemonHome, _ := cmd.Flags().GetString(flagNodeDaemonHome) 74 | startingIPAddress, _ := cmd.Flags().GetString(flagStartingIPAddress) 75 | numValidators, _ := cmd.Flags().GetInt(flagNumValidators) 76 | algo, _ := cmd.Flags().GetString(flags.FlagKeyAlgorithm) 77 | 78 | return InitTestnet( 79 | clientCtx, cmd, config, mbm, genBalIterator, outputDir, chainID, minGasPrices, 80 | nodeDirPrefix, nodeDaemonHome, startingIPAddress, keyringBackend, algo, numValidators, 81 | ) 82 | }, 83 | } 84 | 85 | cmd.Flags().Int(flagNumValidators, 4, "Number of validators to initialize the testnet with") 86 | cmd.Flags().StringP(flagOutputDir, "o", "./mytestnet", "Directory to store initialization data for the testnet") 87 | cmd.Flags().String(flagNodeDirPrefix, "node", "Prefix the directory name for each node with (node results in node0, node1, ...)") 88 | cmd.Flags().String(flagNodeDaemonHome, "empowerd", "Home directory of the node's daemon configuration") 89 | cmd.Flags().String(flagStartingIPAddress, "192.168.0.1", "Starting IP address (192.168.0.1 results in persistent peers list ID0@192.168.0.1:46656, ID1@192.168.0.2:46656, ...)") 90 | cmd.Flags().String(flags.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created") 91 | cmd.Flags().String(server.FlagMinGasPrices, fmt.Sprintf("0.000006%s", sdk.DefaultBondDenom), "Minimum gas prices to accept for transactions; All fees in a tx must meet this minimum (e.g. 0.01photino,0.001stake)") 92 | cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)") 93 | cmd.Flags().String(flags.FlagKeyAlgorithm, string(hd.Secp256k1Type), "Key signing algorithm to generate keys for") 94 | 95 | return cmd 96 | } 97 | 98 | const nodeDirPerm = 0755 99 | 100 | // Initialize the testnet 101 | func InitTestnet( 102 | clientCtx client.Context, 103 | cmd *cobra.Command, 104 | nodeConfig *tmconfig.Config, 105 | mbm module.BasicManager, 106 | genBalIterator banktypes.GenesisBalancesIterator, 107 | outputDir, 108 | chainID, 109 | minGasPrices, 110 | nodeDirPrefix, 111 | nodeDaemonHome, 112 | startingIPAddress, 113 | keyringBackend, 114 | algoStr string, 115 | numValidators int, 116 | ) error { 117 | if chainID == "" { 118 | chainID = "chain-" + tmrand.NewRand().Str(6) 119 | } 120 | 121 | nodeIDs := make([]string, numValidators) 122 | valPubKeys := make([]cryptotypes.PubKey, numValidators) 123 | 124 | empowerChainConfig := srvconfig.DefaultConfig() 125 | empowerChainConfig.MinGasPrices = minGasPrices 126 | empowerChainConfig.API.Enable = true 127 | empowerChainConfig.Telemetry.Enabled = true 128 | empowerChainConfig.Telemetry.PrometheusRetentionTime = 60 129 | empowerChainConfig.Telemetry.EnableHostnameLabel = false 130 | empowerChainConfig.Telemetry.GlobalLabels = [][]string{{"chain_id", chainID}} 131 | 132 | var ( 133 | genAccounts []authtypes.GenesisAccount 134 | genBalances []banktypes.Balance 135 | genFiles []string 136 | ) 137 | 138 | inBuf := bufio.NewReader(cmd.InOrStdin()) 139 | // generate private keys, node IDs, and initial transactions 140 | for i := 0; i < numValidators; i++ { 141 | nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i) 142 | nodeDir := filepath.Join(outputDir, nodeDirName, nodeDaemonHome) 143 | gentxsDir := filepath.Join(outputDir, "gentxs") 144 | 145 | nodeConfig.SetRoot(nodeDir) 146 | nodeConfig.RPC.ListenAddress = "tcp://0.0.0.0:26657" 147 | 148 | if err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm); err != nil { 149 | _ = os.RemoveAll(outputDir) 150 | return err 151 | } 152 | 153 | nodeConfig.Moniker = nodeDirName 154 | 155 | ip, err := getIP(i, startingIPAddress) 156 | if err != nil { 157 | _ = os.RemoveAll(outputDir) 158 | return err 159 | } 160 | 161 | nodeIDs[i], valPubKeys[i], err = genutil.InitializeNodeValidatorFiles(nodeConfig) 162 | if err != nil { 163 | _ = os.RemoveAll(outputDir) 164 | return err 165 | } 166 | 167 | memo := fmt.Sprintf("%s@%s:26656", nodeIDs[i], ip) 168 | genFiles = append(genFiles, nodeConfig.GenesisFile()) 169 | 170 | kb, err := keyring.New(sdk.KeyringServiceName(), keyringBackend, nodeDir, inBuf, clientCtx.Codec) 171 | if err != nil { 172 | return err 173 | } 174 | 175 | keyringAlgos, _ := kb.SupportedAlgorithms() 176 | algo, err := keyring.NewSigningAlgoFromString(algoStr, keyringAlgos) 177 | if err != nil { 178 | return err 179 | } 180 | 181 | addr, secret, err := testutil.GenerateSaveCoinKey(kb, nodeDirName, "", true, algo) 182 | if err != nil { 183 | _ = os.RemoveAll(outputDir) 184 | return err 185 | } 186 | 187 | info := map[string]string{"secret": secret} 188 | 189 | cliPrint, err := json.Marshal(info) 190 | if err != nil { 191 | return err 192 | } 193 | 194 | // save private key seed words 195 | if err := writeFile(fmt.Sprintf("%v.json", "key_seed"), nodeDir, cliPrint); err != nil { 196 | return err 197 | } 198 | 199 | accTokens := sdk.TokensFromConsensusPower(1000, sdk.DefaultPowerReduction) 200 | accStakingTokens := sdk.TokensFromConsensusPower(500, sdk.DefaultPowerReduction) 201 | coins := sdk.Coins{ 202 | sdk.NewCoin("testtoken", accTokens), 203 | sdk.NewCoin(sdk.DefaultBondDenom, accStakingTokens), 204 | } 205 | 206 | genBalances = append(genBalances, banktypes.Balance{Address: addr.String(), Coins: coins.Sort()}) 207 | genAccounts = append(genAccounts, authtypes.NewBaseAccount(addr, nil, 0, 0)) 208 | 209 | valTokens := sdk.TokensFromConsensusPower(100, sdk.DefaultPowerReduction) 210 | createValMsg, err := stakingtypes.NewMsgCreateValidator( 211 | sdk.ValAddress(addr), 212 | valPubKeys[i], 213 | sdk.NewCoin(sdk.DefaultBondDenom, valTokens), 214 | stakingtypes.NewDescription(nodeDirName, "", "", "", ""), 215 | stakingtypes.NewCommissionRates(sdk.OneDec(), sdk.OneDec(), sdk.OneDec()), 216 | sdk.OneInt(), 217 | ) 218 | if err != nil { 219 | return err 220 | } 221 | 222 | txBuilder := clientCtx.TxConfig.NewTxBuilder() 223 | if err := txBuilder.SetMsgs(createValMsg); err != nil { 224 | return err 225 | } 226 | 227 | txBuilder.SetMemo(memo) 228 | 229 | txFactory := tx.Factory{} 230 | txFactory = txFactory. 231 | WithChainID(chainID). 232 | WithMemo(memo). 233 | WithKeybase(kb). 234 | WithTxConfig(clientCtx.TxConfig) 235 | 236 | if err := tx.Sign(txFactory, nodeDirName, txBuilder, true); err != nil { 237 | return err 238 | } 239 | 240 | txBz, err := clientCtx.TxConfig.TxJSONEncoder()(txBuilder.GetTx()) 241 | if err != nil { 242 | return err 243 | } 244 | 245 | if err := writeFile(fmt.Sprintf("%v.json", nodeDirName), gentxsDir, txBz); err != nil { 246 | return err 247 | } 248 | 249 | srvconfig.WriteConfigFile(filepath.Join(nodeDir, "config/app.toml"), empowerChainConfig) 250 | } 251 | 252 | if err := initGenFiles(clientCtx, mbm, chainID, genAccounts, genBalances, genFiles, numValidators); err != nil { 253 | return err 254 | } 255 | 256 | err := collectGenFiles( 257 | clientCtx, nodeConfig, chainID, nodeIDs, valPubKeys, numValidators, 258 | outputDir, nodeDirPrefix, nodeDaemonHome, genBalIterator, 259 | ) 260 | if err != nil { 261 | return err 262 | } 263 | 264 | cmd.PrintErrf("Successfully initialized %d node directories\n", numValidators) 265 | return nil 266 | } 267 | 268 | func initGenFiles( 269 | clientCtx client.Context, mbm module.BasicManager, chainID string, 270 | genAccounts []authtypes.GenesisAccount, genBalances []banktypes.Balance, 271 | genFiles []string, numValidators int, 272 | ) error { 273 | appGenState := mbm.DefaultGenesis(clientCtx.Codec) 274 | 275 | // set the accounts in the genesis state 276 | var authGenState authtypes.GenesisState 277 | clientCtx.Codec.MustUnmarshalJSON(appGenState[authtypes.ModuleName], &authGenState) 278 | 279 | accounts, err := authtypes.PackAccounts(genAccounts) 280 | if err != nil { 281 | return err 282 | } 283 | 284 | authGenState.Accounts = accounts 285 | appGenState[authtypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&authGenState) 286 | 287 | // set the balances in the genesis state 288 | var bankGenState banktypes.GenesisState 289 | clientCtx.Codec.MustUnmarshalJSON(appGenState[banktypes.ModuleName], &bankGenState) 290 | 291 | bankGenState.Balances = banktypes.SanitizeGenesisBalances(genBalances) 292 | for _, bal := range bankGenState.Balances { 293 | bankGenState.Supply = bankGenState.Supply.Add(bal.Coins...) 294 | } 295 | appGenState[banktypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&bankGenState) 296 | 297 | appGenStateJSON, err := json.MarshalIndent(appGenState, "", " ") 298 | if err != nil { 299 | return err 300 | } 301 | 302 | genDoc := types.GenesisDoc{ 303 | ChainID: chainID, 304 | AppState: appGenStateJSON, 305 | Validators: nil, 306 | } 307 | 308 | // generate empty genesis files for each validator and save 309 | for i := 0; i < numValidators; i++ { 310 | if err := genDoc.SaveAs(genFiles[i]); err != nil { 311 | return err 312 | } 313 | } 314 | return nil 315 | } 316 | 317 | func collectGenFiles( 318 | clientCtx client.Context, nodeConfig *tmconfig.Config, chainID string, 319 | nodeIDs []string, valPubKeys []cryptotypes.PubKey, numValidators int, 320 | outputDir, nodeDirPrefix, nodeDaemonHome string, genBalIterator banktypes.GenesisBalancesIterator, 321 | ) error { 322 | var appState json.RawMessage 323 | genTime := tmtime.Now() 324 | 325 | for i := 0; i < numValidators; i++ { 326 | nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i) 327 | nodeDir := filepath.Join(outputDir, nodeDirName, nodeDaemonHome) 328 | gentxsDir := filepath.Join(outputDir, "gentxs") 329 | nodeConfig.Moniker = nodeDirName 330 | 331 | nodeConfig.SetRoot(nodeDir) 332 | 333 | nodeID, valPubKey := nodeIDs[i], valPubKeys[i] 334 | initCfg := genutiltypes.NewInitConfig(chainID, gentxsDir, nodeID, valPubKey) 335 | 336 | genDoc, err := types.GenesisDocFromFile(nodeConfig.GenesisFile()) 337 | if err != nil { 338 | return err 339 | } 340 | 341 | nodeAppState, err := genutil.GenAppStateFromConfig(clientCtx.Codec, clientCtx.TxConfig, nodeConfig, initCfg, *genDoc, genBalIterator) 342 | if err != nil { 343 | return err 344 | } 345 | 346 | if appState == nil { 347 | // set the canonical application state (they should not differ) 348 | appState = nodeAppState 349 | } 350 | 351 | genFile := nodeConfig.GenesisFile() 352 | 353 | // overwrite each validator's genesis file to have a canonical genesis time 354 | if err := genutil.ExportGenesisFileWithTime(genFile, chainID, nil, appState, genTime); err != nil { 355 | return err 356 | } 357 | } 358 | 359 | return nil 360 | } 361 | 362 | func getIP(i int, startingIPAddr string) (ip string, err error) { 363 | if len(startingIPAddr) == 0 { 364 | ip, err = server.ExternalIP() 365 | if err != nil { 366 | return "", err 367 | } 368 | return ip, nil 369 | } 370 | return calculateIP(startingIPAddr, i) 371 | } 372 | 373 | func calculateIP(ip string, i int) (string, error) { 374 | ipv4 := net.ParseIP(ip).To4() 375 | if ipv4 == nil { 376 | return "", fmt.Errorf("%v: non ipv4 address", ip) 377 | } 378 | 379 | for j := 0; j < i; j++ { 380 | ipv4[3]++ 381 | } 382 | 383 | return ipv4.String(), nil 384 | } 385 | 386 | func writeFile(name string, dir string, contents []byte) error { 387 | writePath := filepath.Join(dir) 388 | file := filepath.Join(writePath, name) 389 | 390 | err := tmos.EnsureDir(writePath, 0755) 391 | if err != nil { 392 | return err 393 | } 394 | 395 | err = tmos.WriteFile(file, contents, 0644) 396 | if err != nil { 397 | return err 398 | } 399 | 400 | return nil 401 | } 402 | --------------------------------------------------------------------------------