Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions contract/.env.example

This file was deleted.

3 changes: 3 additions & 0 deletions contract/.envrc.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export SHINE_BOT_CONTRACT=shine
export SHINE_BOT_WALLET_HOST=localhost
export SHINE_BOT_WALLET_PORT=6666
13 changes: 9 additions & 4 deletions contract/.gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
*.wast
CMakeCache.txt
cmake_install.cmake
compile_commands.json
eosc-vault.json
Makefile
.envrc

/.env

.idea
build*/
CMakeFiles/
.vscode/
24 changes: 24 additions & 0 deletions contract/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
cmake_minimum_required(VERSION 3.5)
project(shine VERSION 1.0.0)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(EOSIO_WASMSDK_DEPENDENCY "1.1")

if(EOSIO_WASMSDK_ROOT STREQUAL "" OR NOT EOSIO_WASMSDK_ROOT)
set(EOSIO_WASMSDK_ROOT "/usr/local/eosio.wasmsdk")
endif()

list(APPEND CMAKE_MODULE_PATH ${EOSIO_WASMSDK_ROOT}/lib/cmake)

include(EosioWasmToolchain)

configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/shine.abi" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY)

add_executable(shine.wasm ${CMAKE_CURRENT_SOURCE_DIR}/src/shine.cpp)
target_include_directories(shine.wasm
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include)

set_target_properties(shine.wasm
PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
26 changes: 0 additions & 26 deletions contract/Makefile

This file was deleted.

151 changes: 75 additions & 76 deletions contract/README.md
Original file line number Diff line number Diff line change
@@ -1,109 +1,108 @@
## EOS Shine SmartContract
## EOS Shine Smart Contract

This document describes various aspects of the EOS Shine SmartContract
This document describes various aspects of the EOS Shine smart contract
implementation ranging from architecture, building, troubleshooting, etc.

Moreover, this document also contains various information about EOS
SmartContract in general, mainly aimed at the developer audience.

### Architecture & Features

The Shine contract goal is to enable the implementation of a recognition
system based on praise and votes. Person (i.e. account) broadcast a praise
to all other members. Each member (i.e. account) can then vote for this
particular praise.

TBC
smart contract in general, mainly aimed at the developer audience.

#### Actions

* `praise` (`addpraise`) - Create a praise in the blockchain.
* `vote` (`addvote`) - Vote for a given praise in the blockchain.
* `rewards` (`calcrewards`) - Update the rewards table in the blockchain.
* `post` - Create a post in the blockchain.
* `vote` - Vote for a given praise in the blockchain.
* `reset` - Reset all collected stats to initial state.

### Development

#### Prerequisites
#### Compilation

For development, ideally you would have a testnet running on your machine
executing the EOS blockchain by configuring a local environment. Follow the instructions at https://github.com/EOSIO/eos/wiki/Local-Environment and when you have a `nodeos`
running with a producer emitting blocks, come back here.
##### Docker

There is a `shine_bot.rb` script that enables to interact with the contract
in a more rapid way. For this you will need Ruby 2.4+ installed along with the
following dependency installed globally:
The easiest way to compile is by using EOS Canada `gcr.io/eoscanada-public/eosio-wasmsdk`
Docker image.

While at the root of this project:

```
gem install 'tty-prompt'
cd contract
docker run --rm -it -v `pwd`:/shine -w /shine gcr.io/eoscanada-public/eosio-wasmsdk:v1.1.1 bash build.sh
```

Note that this is not needed if you don't plan on using the

#### Preparation
You will find the compiled `shine.abi` and `shine.wasm` in the `build` directory.

Let's prepare for the development of EOS Shine SmartContract. We will
need an account on a running blockchain. It's quite possible to run
you own test blockchain on your machine for development purposes.
##### Locally

Let's create the account by creating two EOS key sets (first one for owner
permission second one for active permission). Note the private keys outputted
somewhere as we will need them in later section:
Ensure that you have `https://github.com/EOSIO/eosio.wasmsdk` compiled locally.

**Note** You will need to have `eosios@active` private key imported into a
wallet for the account creation to work. Import it using `cleos wallet import <private_key>`.
While at the root of this project:

```
# Owner
cleos create key
Private key: 5H123
Public key: EOSXYZ

# Active
cleos create key
Private key: 5B456
Public key: EOSABC

cleos create account eosio shine EOSXYZ EOSABC
./build.sh
```

Once the account is created, let's import the owner and active private keys
into the default wallet (you are free to use another wallet also):
You will find the compiled `shine.abi` and `shine.wasm` in the `build` directory.

#### Installation

**Note** Ensures that the wallet is unlocked prior doing this operation. You
can unlock it by using `cleos wallet unlock` and entering the wallet password
that was outputted at wallet creation time.
While at the root of this project:

```
# Of course, change 5H123 and 5B456 by real owner & active private keys respectively
cleos wallet import 5H123
cleos wallet import 5B456
cd contract
cleos set contract shine build build/shine.wasm build/shine.abi
```

We are then good to go. Note that if the blockchain node is stopped,
wallet will need to be unlocked again prior doing any operations
in the upcoming sections.

#### Building & Testing
#### Testing

Building the SmartContract ABI and code to WAST is performed through
the `eosiocpp` command line utility. Navigate to the root folder
of this project and then issue:

```
eosiocpp -o shine.wast shine.cpp
```
First, install [eos-bios](https://github.com/eoscanada/eos-bios) then follow
the [local-development-environment](https://github.com/eoscanada/eos-bios#local-development-environment)
instructions to start a local `nodeos` for development.

Once the WAST has been generated correctly, next step is to set the contract
on the account `shine` that was created in the preparation step:
Ensure that your `boot_sequence.yaml` contains the following content: (the content must comes
before the `Replacing eosio account from eosio.bios contract to eosio.system` block):

```
cleos set contract shine `pwd`
- op: system.newaccount
label: Create account eosioforum
data:
creator: eosio
new_account: shine
pubkey: EOS5MHPYyhjBjnQZejzZHqHewPWhGTfQWSVTWYEhDmJu4SXkzgweP

- op: system.newaccount
label: Create user account for shine
data:
creator: eosio
new_account: matt
pubkey: EOS5MHPYyhjBjnQZejzZHqHewPWhGTfQWSVTWYEhDmJu4SXkzgweP

- op: system.newaccount
label: Create user account for shine
data:
creator: eosio
new_account: eve
pubkey: EOS5MHPYyhjBjnQZejzZHqHewPWhGTfQWSVTWYEhDmJu4SXkzgweP

- op: system.newaccount
label: Create user account for shine
data:
creator: eosio
new_account: evan
pubkey: EOS5MHPYyhjBjnQZejzZHqHewPWhGTfQWSVTWYEhDmJu4SXkzgweP

- op: system.newaccount
label: Create user account for shine
data:
creator: eosio
new_account: mike
pubkey: EOS5MHPYyhjBjnQZejzZHqHewPWhGTfQWSVTWYEhDmJu4SXkzgweP
```

##### Testing
Import the following private key in your wallet: `5JpjqdhVCQTegTjrLtCSXHce7c9M8w7EXYZS7xC13jVFF4Phcrx`
(this is the private key for the public one `EOS5MHPYyhjBjnQZejzZHqHewPWhGTfQWSVTWYEhDmJu4SXkzgweP`, of
course, you can use your own pair if you change the public key part in the boot sequence).

To make it easier to develop, the `shine_bot.rb` is a small command line
utility to interact more easily with the SmartContract.
utility to interact more easily with the smart contract.

First, it's possible to run all command in a quick way by passing the flag
`-q` to the CLI tool. This will not ask for question for which a default value
Expand Down Expand Up @@ -133,20 +132,20 @@ the `member_id` being pass to the contract.

Possible usage:

* `./shine_bot.rb --praise` - Perform a praise (author, praisee, memo)
* `./shine_bot.rb --post` - Perform a post (from, to, memo)
* `./shine_bot.rb --vote` - Perform a vote (praise_id, voter)
* `./shine_bot.rb --rewards` - Compute the rewards (pot)
* `./shine_bot.rb --scenario` - Perform a scenario adding 6 praises and 10 votes.
* `./shine_bot.rb --reset` - Reset the all state to initial values
* `./shine_bot.rb --scenario` - Perform a scenario adding 6 posts and 10 votes.

By using the scenario, you will automatically add a bunch of praises and
votes so it's easier to test your SmartContract code and changes afterward.
votes so it's easier to test your smart contract code and changes afterward.

### EOS SmartContract
### EOS smart contract

#### References

This section aims at providing links to documentation related to some concept
of building SmartContract for the EOS blockchain.
of building smart contract for the EOS blockchain.

* `eosio::multi_index`

Expand Down
3 changes: 3 additions & 0 deletions contract/shine.abi → contract/abi/shine.abi
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{
"types": [{
"new_type_name": "account_name",
"type": "name"
},{
"new_type_name": "post_id",
"type": "uint64"
}],
Expand Down
19 changes: 0 additions & 19 deletions contract/asset.hpp

This file was deleted.

16 changes: 16 additions & 0 deletions contract/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env bash

GREEN='\033[0;33m'
RED='\033[0;31m'
NC='\033[0m'

printf "${GREEN}=========== Building shine ===========${NC}\n\n"

BUILD_SUFFIX=${1}
CORES=`getconf _NPROCESSORS_ONLN`

mkdir -p build${BUILD_SUFFIX}
pushd build${BUILD_SUFFIX} &> /dev/null
cmake ../
make -j${CORES}
popd &> /dev/null
18 changes: 18 additions & 0 deletions contract/include/asset.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#pragma once

#include <cmath>

#include <eosiolib/asset.hpp>
#include <eosiolib/eosio.hpp>

namespace eoscanada {

static const eosio::symbol_type EOS_SYMBOL = S(4, EOS);

inline static eosio::asset double_to_asset(double amount, eosio::symbol_type symbol) {
return eosio::asset((uint64_t)(pow(10, symbol.precision()) * amount), symbol);
}

inline static double asset_to_double(const eosio::asset& asset) { return asset.amount / pow(10, asset.symbol.precision()); }

} // namespace eoscanada
2 changes: 1 addition & 1 deletion contract/shine.hpp → contract/include/shine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include "table.hpp"

// Configurable values
#define REWARD_post_count_WEIGHT 0.07
#define REWARD_POST_COUNT_WEIGHT 0.07
#define REWARD_VOTE_RECEIVED_WEIGHT 0.9
#define REWARD_VOTE_GIVEN_WEIGHT 0.03

Expand Down
File renamed without changes.
Binary file removed contract/shine.wasm
Binary file not shown.
5 changes: 4 additions & 1 deletion contract/shine_bot.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
require 'open3'
require 'tty-prompt'

DEBUG = ENV['DEBUG'] || false
EOS_NAME_REGEX = /^[\.1-5a-z]{1,12}[\.a-p]?$/

def main(arguments)
Expand All @@ -20,7 +21,7 @@ def main(arguments)
end

def ask_contract(prompt)
default = ENV['CONTRACT_ACCOUNT']
default = ENV['SHINE_BOT_CONTRACT']
return default if default

prompt.ask('Contract:') do |question|
Expand Down Expand Up @@ -197,6 +198,8 @@ def execute_cleos(arguments)
options << '--wallet-port' << wallet_port if wallet_port
options << '--wallet-host' << wallet_host if wallet_host

puts 'cleos', *options, *arguments if DEBUG

stdout, stderr, status = Open3.capture3('cleos', *options, *arguments)
unless status.success?
puts stderr
Expand Down
6 changes: 3 additions & 3 deletions contract/shine.cpp → contract/src/shine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,9 @@ void shine::distribute_rewards(const asset& pot, distribution_stat& distribution
auto post_count_weight = post_vote_received / (double)distribution.vote_explicit;
auto vote_given_weight = vote_given_weighted / distribution.vote_given_weighted_total;

auto vote_received_amount = double_to_asset(vote_received_weight * pot_amount * REWARD_VOTE_RECEIVED_WEIGHT);
auto post_count_amount = double_to_asset(post_count_weight * pot_amount * REWARD_post_count_WEIGHT);
auto vote_given_amount = double_to_asset(vote_given_weight * pot_amount * REWARD_VOTE_GIVEN_WEIGHT);
auto vote_received_amount = double_to_asset(vote_received_weight * pot_amount * REWARD_VOTE_RECEIVED_WEIGHT, EOS_SYMBOL);
auto post_count_amount = double_to_asset(post_count_weight * pot_amount * REWARD_POST_COUNT_WEIGHT, EOS_SYMBOL);
auto vote_given_amount = double_to_asset(vote_given_weight * pot_amount * REWARD_VOTE_GIVEN_WEIGHT, EOS_SYMBOL);
auto amount_total = vote_received_amount + post_count_amount + vote_given_amount;

balance -= amount_total;
Expand Down